Skip to content

fix: unbreak raisely start and raisely create for CLI logins - #83

Merged
xolott-ark merged 5 commits into
masterfrom
jose/sir-1934-cli-start-crashes-create-404s-and-page-json-edits-never
Aug 10, 2026
Merged

fix: unbreak raisely start and raisely create for CLI logins#83
xolott-ark merged 5 commits into
masterfrom
jose/sir-1934-cli-start-crashes-create-404s-and-page-json-edits-never

Conversation

@xolott-ark

@xolott-ark xolott-ark commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Fixes SIR-1934.

Summary

Three commands were broken for anyone who authenticated with raisely login. Two root causes, both confirmed with runtime instrumentation against the live API rather than by reading code.

CLI tokens have no user record. They are OAuth app authorizations, so /users/me resolves me to the authorization uuid and returns 404. /authenticate also returns identity flat at the top level, with its data key holding authorization metadata (type, scopes, appUuid, authorizationUuid) rather than an organisation record. Three call sites assumed otherwise:

  • informLocalDev read authData.data.organisation.private and threw a TypeError, crashing raisely start before the local server came up. It now reads organisationUuid from .raisely.json (falling back to /authenticate) and fetches the org record separately. No OAuth app scope grants reading an organisation, so that request 403s for every CLI login and only succeeds for admin tokens via RAISELY_TOKEN; since the localDevelopment flag is advisory, it fails open rather than blocking the command.
  • createComponent called /users/me for the organisation uuid and 404'd before creating anything. It now resolves the uuid the same way, and throws an actionable message naming raisely logout / login / init when neither source has it.
  • checkCorrectOrganisation called /users/${authData.userUuid}/move, which became /users/null/move. It now explains that the session identifies no user and points at the admin instead.

raisely start watched only stylesheets. handleCampaignChange returned early unless the changed path was <campaign>/stylesheets/..., so saving a page JSON was dropped with no upload and no message; the preview looked broken with nothing to explain why. Page JSON now routes through uploadPage, reusing the same guards as deploy: skip invalid JSON, skip pages with no uuid, and skip pages whose campaignUuid is not configured, reporting each on the spinner.

Test plan

  • 103 tests pass across 12 files, including new suites for helpers, components, and auth, plus added start cases for the page upload path
  • raisely start reaches a running local server instead of crashing
  • raisely create debug-test-component creates the component and syncs both files down; verified the record and the generated .js / .json on disk
  • Reviewer: confirm the fail-open behaviour on the organisation 403 is acceptable, since the localDevelopment warning is now skipped for standard CLI logins

Notes

Targets develop, matching the convention for feature work here. Verifying create left a debug-test-component record in the Raisely org used for testing; the CLI has no delete command, so it needs removing through the admin panel.


Note

Medium Risk
Touches authentication, org switching, and live upload paths used during local dev; behavior changes are intentional but could affect edge cases around org mismatch and advisory local-dev warnings.

Overview
Fixes CLI login breakage by treating /authenticate identity as top-level fields (not data), and by stopping reliance on /users/me for app-token sessions.

raisely start no longer crashes in informLocalDev when org details aren’t on the auth payload; it loads organisationUuid from config or auth and optionally fetches /organisations/:uuid (403 on CLI tokens is ignored so start isn’t blocked). Org mismatch handling in auth now refuses /users/undefined/move when there’s no userUuid, and exits on failed moves instead of continuing.

createComponent resolves organisationUuid from .raisely.json or /authenticate, with a clear recovery message when resolution fails.

Watch mode uploads campaign page JSON changes via uploadPage, with the same skip rules as deploy (valid JSON, uuid, configured campaign).

Adds a GitHub Actions test workflow (Node 18/20/22) and Vitest coverage for auth, components, helpers, and start page uploads.

Reviewed by Cursor Bugbot for commit 98408b4. Bugbot is set up for automated code reviews on this repo. Configure here.

CLI tokens are OAuth app authorizations with no linked user, and
/authenticate returns identity flat at the top level with no organisation
record, so start crashed in informLocalDev and create 404d on /users/me.

Read the organisation from .raisely.json (falling back to /authenticate),
fetch the org record separately for the localDevelopment flag and fail
open on the expected 403, and skip the organisation switch when the
session identifies no user instead of calling /users/null/move.
handleCampaignChange only handled files under <campaign>/stylesheets, so
saving a page JSON was dropped with no upload and no message, leaving the
preview unchanged after a refresh with nothing to explain why.

Route <campaign>/pages/*.json through uploadPage, reusing the deploy
guards: skip files that are invalid JSON, have no uuid, or belong to a
campaign that is not configured, reporting each on the spinner.
@xolott-ark
xolott-ark requested a review from KeinerM August 7, 2026 20:12

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: high.

Risk Assessment (Framework v2.0)

Framework (v2.0)

Dimension Tier Score Rationale
Security 1 Low No findings
Sensitive domains 1 High Modifies CLI auth/session identity handling: /authenticate shape, org-switch via /users/.../move, and organisation private-flag fetch used by start/create
Data integrity 1 Low No database/query/scoping changes
Deployment 1 Low None
Scope 2 Medium ~140 LOC of mutative changes across 4 existing source files; tests mostly additive
Architecture 2 Low Changes stay within the CLI package boundaries
Feature flags 2 Low Developer CLI tooling; feature flag not required
Dependencies 2 Low No changes

Mitigating Factors

  • New Vitest coverage for auth, components, helpers, and start page-upload path
  • Page upload reuses existing deploy guards (uuid/campaign checks)

Findings

# Finding Status Resolution
1 When org-switch is confirmed but userUuid is missing, checkCorrectOrganisation returns and getToken still returns the token, so the CLI can continue against the wrong organisation after a failed switch Open --
2 auth.test.js case titled for undefined userUuid still supplies userUuid: 'user-1', so the CLI-login no-user guard is not actually asserted Open --

Outstanding findings: 2
Overall risk: HIGH
Decision: ESCALATE
Rationale: Tier 1 Sensitive domains is High because the PR changes authentication/session identity resolution and organisation-switch behavior for CLI OAuth logins; escalate for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Nemo - Pull Request Router and Approver

Comment thread src/actions/auth.js Outdated
Comment thread tests/auth.test.js
@xolott-ark
xolott-ark changed the base branch from develop to master August 7, 2026 21:05
The no-user branch logged and returned, so getToken carried on and the
command ran against the organisation the user had just asked to leave.
For deploy that means writing to the wrong organisation.

Both failure branches now exit(-1) like the permission check above them,
so neither continues and neither leaks a bare stack trace.

The test named for an undefined user uuid was still passing
userUuid: 'user-1', duplicating the case above it and never reaching the
early return. It now omits userUuid, and a new case covers the move
request failing. Both fail without the change above.
Runs pnpm test on Node 18, 20, and 22, covering the >=18 floor declared
in engines, plus pushes to master and develop so merge results are
checked too. Installs with --frozen-lockfile so a stale lockfile fails
the run instead of resolving something different from local.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9b4ec03. Configure here.

Comment thread .github/workflows/test.yml
checkout, setup-node, and action-setup all ran on node 20, which runners
deprecated in September 2025 and now force onto node 24, warning on every
job.

The explicit `cache: pnpm` input still works: setup-node v6 narrowed only
the automatic packageManager-based caching to npm, which this workflow
does not rely on.
@xolott-ark
xolott-ark merged commit deae770 into master Aug 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants