Skip to content

feat(website): route auth through Mystira Identity - #42

Merged
JustAGhosT merged 1 commit into
masterfrom
feat/codeflow-identity-login
Jul 24, 2026
Merged

feat(website): route auth through Mystira Identity#42
JustAGhosT merged 1 commit into
masterfrom
feat/codeflow-identity-login

Conversation

@JustAGhosT

@JustAGhosT JustAGhosT commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add static login, signup, and auth callback routes for Mystira Identity
  • implement browser-side authorization-code + PKCE for the Codeflow website public client
  • route alpha CTAs and header auth links through the new Identity-backed routes

Validation

  • pnpm --dir C:\tmp\codeflow-identity-login\website build

Note: Next build exits 0 and exports the static routes. It still reports the existing ESLint config warning: cannot find package @eslint/eslintrc from website/eslint.config.mjs.

Summary by CodeRabbit

  • New Features
    • Added dedicated Sign in and Sign up pages with Mystira Identity authentication.
    • Added secure authentication flow handling, including success, error, and callback states.
    • Added navigation links for Sign in and Sign up.
    • Added clear loading and error feedback while authentication starts.
  • Updates
    • Updated homepage calls to action to direct visitors to the new authentication pages.
    • Added post-authentication options to continue to CodeFlow or return home.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40c384cf97

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<div className="flex flex-col items-center justify-center gap-4 sm:flex-row">
{state === "success" ? (
<Link
href="/integration"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Forward successful sign-ins to the app

For the alpha CTAs now routed through /login, a successful callback only stores the token response in this site's sessionStorage and then sends the user to /integration, which is the documentation flow rather than the deployed app; a repo-wide search shows CODEFLOW_SESSION_KEY is only used in auth/oidc.ts, and sessionStorage will not carry over to https://app.codeflow.io. As a result, users who click “Try Alpha Preview” can complete Identity login but the actual CodeFlow app never receives that authenticated state. Redirect to the app with a real handoff, or make the app origin own the callback/session.

Useful? React with 👍 / 👎.

Comment thread website/app/auth/oidc.ts Outdated
authorizeUrl.searchParams.set("client_id", CODEFLOW_WEBSITE_CLIENT_ID);
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
authorizeUrl.searchParams.set("response_type", "code");
authorizeUrl.searchParams.set("scope", "openid profile email offline_access");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid requesting refresh tokens from the browser

When Mystira Identity grants offline_access, this browser-only flow stores the entire token response, including any refresh_token, in sessionStorage even though the site never uses it. In deployments where the identity client is allowed to issue refresh tokens, that creates an unnecessary long-lived credential exposure for any client-side script/XSS on the marketing site; remove offline_access unless there is a protected backend/BFF or refresh-token rotation flow that actually consumes it.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@JustAGhosT, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 530f4c07-ba23-43ef-9d41-f7a9cedc5e16

📥 Commits

Reviewing files that changed from the base of the PR and between 40c384c and 1f2141d.

📒 Files selected for processing (8)
  • website/app/auth/AuthCallback.tsx
  • website/app/auth/AuthStart.tsx
  • website/app/auth/callback/page.tsx
  • website/app/auth/oidc.ts
  • website/app/components/Header.tsx
  • website/app/login/page.tsx
  • website/app/page.tsx
  • website/app/signup/page.tsx
📝 Walkthrough

Walkthrough

Adds Mystira Identity OIDC authentication with PKCE, new login/signup pages, callback handling, token persistence, and internal navigation from homepage CTAs and the site header.

Changes

OIDC authentication

Layer / File(s) Summary
OIDC flow and token exchange
website/app/auth/oidc.ts
Defines OIDC contracts and configuration, generates PKCE authorization requests, validates callback state, exchanges authorization codes for tokens, and persists session data.
Authentication entry and callback pages
website/app/auth/AuthStart.tsx, website/app/auth/AuthCallback.tsx, website/app/auth/callback/page.tsx
Adds login/signup initiation UI, callback status handling, success/error messages, and the styled callback page layout.
Site authentication navigation
website/app/components/Header.tsx, website/app/login/page.tsx, website/app/signup/page.tsx, website/app/page.tsx
Adds login and signup navigation, new authentication pages, and internal homepage routes for authentication CTAs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Visitor
  participant AuthStart
  participant MystiraIdentity
  participant AuthCallback
  participant SessionStorage
  Visitor->>AuthStart: Click sign in or sign up
  AuthStart->>SessionStorage: Store state, nonce, and PKCE verifier
  AuthStart->>MystiraIdentity: Redirect to authorization endpoint
  MystiraIdentity-->>AuthCallback: Return authorization code and state
  AuthCallback->>SessionStorage: Load stored request
  AuthCallback->>MystiraIdentity: Exchange code at token endpoint
  MystiraIdentity-->>AuthCallback: Return token response
  AuthCallback->>SessionStorage: Store token response
  AuthCallback-->>Visitor: Show success or error state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: routing website authentication through Mystira Identity.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/codeflow-identity-login

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/app/auth/AuthCallback.tsx`:
- Around line 13-44: Update the AuthCallback useEffect to use a useRef guard
that returns when the effect has already started, and mark it before invoking
completeMystiraIdentityFlow. Keep the existing callback validation, exchange,
state updates, and cleanup behavior unchanged so React Strict Mode replay cannot
start a second sign-in attempt.

In `@website/app/auth/oidc.ts`:
- Line 76: Update the OIDC authorization flow around authorizeUrl and
CODEFLOW_SESSION_KEY so refresh tokens are not requested or stored in
browser-readable sessionStorage: remove offline_access from the requested scope
for this browser-only client, unless the flow is migrated to a BFF using
HttpOnly session cookies.
- Around line 116-119: Update completeMystiraIdentityFlow() to validate
tokenResponse.id_token before persisting CODEFLOW_SESSION_KEY. Verify the ID
token signature, issuer, audience, expiry, and generated nonce, and only then
write the session and remove CODEFLOW_AUTH_STATE_KEY; reject invalid tokens
without persisting the session.
- Around line 61-82: Update the authorization URL construction around the
`intent` and `authorizeUrl` symbols so the `prompt` parameter uses the
provider’s registration value (`create`) when `intent` is signup, while
retaining `login` for normal authentication. Keep the persisted
`StoredAuthRequest` behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d49cebd8-0452-46e3-b4a0-2797c2210b76

📥 Commits

Reviewing files that changed from the base of the PR and between bbbd398 and 40c384c.

📒 Files selected for processing (8)
  • website/app/auth/AuthCallback.tsx
  • website/app/auth/AuthStart.tsx
  • website/app/auth/callback/page.tsx
  • website/app/auth/oidc.ts
  • website/app/components/Header.tsx
  • website/app/login/page.tsx
  • website/app/page.tsx
  • website/app/signup/page.tsx

Comment thread website/app/auth/AuthCallback.tsx
Comment thread website/app/auth/oidc.ts
Comment on lines +61 to +82
const storedRequest: StoredAuthRequest = {
intent,
state,
nonce,
codeVerifier,
redirectUri,
createdAt: Date.now(),
};

sessionStorage.setItem(CODEFLOW_AUTH_STATE_KEY, JSON.stringify(storedRequest));

const authorizeUrl = new URL("/connect/authorize", MYSTIRA_IDENTITY_BASE_URL);
authorizeUrl.searchParams.set("client_id", CODEFLOW_WEBSITE_CLIENT_ID);
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
authorizeUrl.searchParams.set("response_type", "code");
authorizeUrl.searchParams.set("scope", "openid profile email offline_access");
authorizeUrl.searchParams.set("code_challenge", codeChallenge);
authorizeUrl.searchParams.set("code_challenge_method", "S256");
authorizeUrl.searchParams.set("state", state);
authorizeUrl.searchParams.set("nonce", nonce);
authorizeUrl.searchParams.set("prompt", "login");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

What authorization-request parameter does Mystira Identity require to open account registration or a signup screen for an OpenID Connect public client?

💡 Result:

To open the account registration or signup screen within an OpenID Connect authorization request, Mystira Identity—like other standards-compliant OpenID Connect providers—uses the prompt parameter with the value create [1][2]. Specifically, the "Initiating User Registration via OpenID Connect 1.0" specification defines the prompt=create parameter [1]. When a client includes prompt=create in its authorization request, it instructs the OpenID Provider to present the user with an account creation interface rather than the standard login flow [1][2]. After the registration process is completed by the user, the identity provider redirects them back to the client application to finish the authentication flow [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
fd -a 'oidc\.ts$' . | sed 's#^\./##'

echo "== inspect target =="
sed -n '1,130p' website/app/auth/oidc.ts

echo "== references to signup/auth flow =="
rg -n "intent|signup|/signup|CREATE|create|prompt|StoredAuthRequest|CODEFLOW_AUTH_STATE_KEY" website/app website || true

Repository: phoenixvc/codeflow-engine

Length of output: 17580


🌐 Web query:

Mystira Identity prompt=create OpenID Connect user registration

💡 Result:

Mystira is an early-childhood developmental observation platform founded in 2025 that utilizes interactive storytelling to assess children [1][2]. Technical documentation and source code references indicate that Mystira operates as an OpenID Connect (OIDC) identity provider, allowing third-party applications to integrate authentication via standard OIDC flows [3][4][5]. For developers implementing user registration or authentication using Mystira as an IdP, the following technical requirements and practices are observed in existing implementations: 1. Authentication Integration: Applications typically integrate Mystira using frameworks like Auth.js v5 [3][5]. The authentication flow replaces legacy credential-based systems (such as bcrypt/JWT) with OIDC-based login, redirecting users to the Mystira platform to complete authentication [3][5]. 2. Account Linking and Security: In internal implementations, account linking is handled by matching the user's email address [4]. To prevent security vulnerabilities such as account takeover or privilege escalation, systems are required to validate the email_verified claim (accepting either boolean true or the string "true") before linking the OIDC identity to a local user account [4]. 3. Future Roadmap: Developers are encouraged to migrate from email-based matching to matching on the immutable sub (subject) claim to improve security and robustness [4]. Because Mystira functions as an OIDC provider, user registration is managed at the Mystira platform level (e.g., via their interactive app/dashboard) rather than through a direct API-based registration prompt in the consuming application [3][1]. Applications trigger the flow by initiating an OIDC sign-in request, which offloads the registration and login process to the Mystira-hosted service [3].

Citations:


Make the signup intent change the IDP prompt.

intent is only persisted, so both login and signup request /connect/authorize?prompt=login. Set prompt to the provider’s registration value for signup—typically prompt=create for OpenID Connect flows—to request account creation rather than login.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/app/auth/oidc.ts` around lines 61 - 82, Update the authorization URL
construction around the `intent` and `authorizeUrl` symbols so the `prompt`
parameter uses the provider’s registration value (`create`) when `intent` is
signup, while retaining `login` for normal authentication. Keep the persisted
`StoredAuthRequest` behavior unchanged.

Comment thread website/app/auth/oidc.ts Outdated
authorizeUrl.searchParams.set("client_id", CODEFLOW_WEBSITE_CLIENT_ID);
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
authorizeUrl.searchParams.set("response_type", "code");
authorizeUrl.searchParams.set("scope", "openid profile email offline_access");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate oidc.ts =="
fd -a 'oidc\.ts$' . | sed 's#^\./##'

echo "== inspect website/app/auth/oidc.ts size and relevant lines =="
if [ -f website/app/auth/oidc.ts ]; then
  wc -l website/app/auth/oidc.ts
  sed -n '1,160p' website/app/auth/oidc.ts | nl -ba
else
  echo "website/app/auth/oidc.ts not found"
fi

echo "== search sessionStorage/refresh token/usages =="
rg -n "offline_access|refresh_token|sessionStorage|authorizeUrl|token" website/app/auth website -g '*.{js,jsx,ts,tsx}' || true

Repository: phoenixvc/codeflow-engine

Length of output: 361


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== inspect website/app/auth/oidc.ts =="
awk '{printf "%5d\t%s\n", NR, $0}' website/app/auth/oidc.ts | sed -n '1,140p'

echo "== search secure/session storage token usages =="
rg -n "offline_access|refresh_token|sessionStorage|authorizeUrl|token" website/app/auth website -g '*.{js,jsx,ts,tsx}' || true

echo "== git diff stat/name (if available) =="
git diff --stat website/app/auth/oidc.ts || true

Repository: phoenixvc/codeflow-engine

Length of output: 9314


Do not retain OIDC refresh tokens in browser-readable storage.

website/app/auth/oidc.ts:76 requests offline_access, and website/app/auth/oidc.ts:116-117 stores the complete token response in sessionStorage via CODEFLOW_SESSION_KEY, exposing refresh tokens to same-origin XSS. Use a BFF with HttpOnly session cookies, or omit offline_access for this browser-only client.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/app/auth/oidc.ts` at line 76, Update the OIDC authorization flow
around authorizeUrl and CODEFLOW_SESSION_KEY so refresh tokens are not requested
or stored in browser-readable sessionStorage: remove offline_access from the
requested scope for this browser-only client, unless the flow is migrated to a
BFF using HttpOnly session cookies.

Comment thread website/app/auth/oidc.ts
@JustAGhosT
JustAGhosT force-pushed the feat/codeflow-identity-login branch from 40c384c to 1f2141d Compare July 24, 2026 11:20
@JustAGhosT
JustAGhosT merged commit ff86491 into master Jul 24, 2026
9 checks passed
@JustAGhosT
JustAGhosT deleted the feat/codeflow-identity-login branch July 24, 2026 11:22
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.

1 participant