Skip to content

OpenConceptLab/ocl_issues#2857 | "Sign in and start mapping" works on the first try for visitors from openconceptlab.org - #87

Merged
paynejd merged 3 commits into
mainfrom
ocl_issues-2857-signin-redirect
Sep 30, 2026
Merged

paynejd merged 3 commits into
mainfrom
ocl_issues-2857-signin-redirect

Conversation

@paynejd

@paynejd paynejd commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

closes OpenConceptLab/ocl_issues#2857

Links from openconceptlab.org land on #/?referrer=…. Sign in and start mapping, the account menu's Sign in, and the 401 page's sign-in link used the whole page URL, query string included, as the OIDC redirect_uri, but the callback rebuilt it for the code exchange from the path alone. Keycloak refused the exchange with "Incorrect redirect_uri", and retrying from the callback page carried its stale state and code into the next sign-in.

Same fix as TBv3, OpenConceptLab/oclweb3#58 (OpenConceptLab/ocl_issues#2856), including the follow-ups from its Codex review:

  • Sign-in always uses LOGIN_REDIRECT_URL. The page to return to (its hash route, query included) waits in this tab's sessionStorage until the callback has exchanged the code.
  • That page wins over next. The callback still uses next to rebuild the redirect_uri for sign-ins started before this deploy.
  • Sign-up and password reset clear a page left by an abandoned sign-in, and /oidc/login, /signin and /signup are never return pages, in any letter case or percent-encoding.

OIDLoginCallback.jsx was identical in both apps and gets the same diff. The utils.js diff matches line for line, blank lines aside.

Verified

  • Before, on production (test account): from https://map.openconceptlab.org/#/?referrer=https://openconceptlab.org/, Sign in and start mapping sent redirect_uri=https://map.openconceptlab.org/?referrer=https://openconceptlab.org/, the code exchange sent https://map.openconceptlab.org, and Keycloak answered "Incorrect redirect_uri".
  • After, on a local build of this branch against the production API and Keycloak, with a real sign-in through Sign in and start mapping from #/?referrer=https://openconceptlab.org/ and from #/: both got a token and returned to the page they started from, with the same redirect_uri at both steps and nothing left in sessionStorage.
  • The return-page guard, run from the file's own code: the same 22 cases as oclweb3#58, all passing.
  • eslint src --ext .jsx,.js is clean.

🤖 Generated with Claude Code

…orks on the first try for visitors from openconceptlab.org

Links from openconceptlab.org land on #/?referrer=…, and sign-in used
the page URL, query string included, as the OIDC redirect_uri. The
callback rebuilt the redirect_uri for the code exchange from the path
alone, so Keycloak refused the exchange with "Incorrect redirect_uri",
and retrying from the callback page carried its stale state and code
into the next sign-in.

Same fix as TBv3 (OpenConceptLab/oclweb3#58, ocl_issues#2856): sign-in
always uses LOGIN_REDIRECT_URL, and the page to return to (its hash
route) waits in this tab's sessionStorage. That page wins over next,
which the callback still uses to rebuild the redirect_uri for sign-ins
started before this deploy. Sign-up and password reset clear a page
left by an abandoned sign-in, and /oidc/login, /signin and /signup are
never return pages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Codex adversarial review, pass 1 (codex-cli 0.159.2, commit 8fb9cc8)

No blocking issue found. One nonblocking correctness finding:

  • P2 — Auth-route exclusion is case-sensitive, but routing is not. src/common/utils.js:873
    Open /#/signin?returnTo=<encoded https://mapper.example/#/OIDC/login>, then complete sign-in. The helper stores /OIDC/login; the callback restores it, and React Router matches the callback component. With no code, that component does nothing, leaving the user on an empty callback page. /Signin similarly survives validation and triggers another login round trip. I reproduced the mismatch using the actual helper and installed router.
    Suggested fix: make the exclusion case-insensitive and apply the same validation when consuming the stored route.

The remaining checks found no new regression:

  • WaitListing, UserMenu, Error401, and forced logout preserve ordinary project routes and hash queries. The callback toast uses the current URL after navigation.
  • The preview splash returns to the authenticated project list; templateFrom survives sign-in. forceLoginUser still drops query parameters before calling the helper—existing behavior.
  • Old, query-free path-based sign-ins retain the next=/path exchange behavior. Old query-bearing sign-ins remain subject to the original mismatch; this change cannot repair those already-issued redirects.
  • Register/reset clear the stored route. Cross-tab completion retains the existing sign-in prompt behavior.
  • Stored routes are assigned only to window.location.hash; I found no external redirect or executable injection introduced here. New flows overwrite/clear leftovers, and code-bearing callbacks consume them.
  • The fixed root redirect works with the existing index.html rewrite and next=/ fallback.

Reviewed git diff origin/main...HEAD for commit 8fb9cc8. No files edited. Verification was source tracing and focused Node checks; no live Keycloak flow was exercised.

paynejd and others added 2 commits September 30, 2026 12:50
…case-insensitively, like the router

From the Codex review: the router matches /SIGNUP and /OIDC/login the
same as their lowercase forms, and /signin#section slipped past the
delimiters. The guard now tests the path before any ? or #, ignoring
case.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…th once, like the router

From the Codex review: history decodes a route path once before the
router matches it, so /%73ignin or /%53IGNUP opened the sign-in or
sign-up page after all. The guard now checks the decoded path, and a
malformed encoding, which would make the router throw, isn't saved.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Codex adversarial review, pass 2 (codex-cli 0.159.2, commit 5407db6)

Nothing blocking remains in PR #87.

Reviewed git diff origin/main...HEAD (both commits) and git show HEAD. The newest fix resolves the mixed-case auth-route bypass and /signin#section bypass.

All 14 in-memory guard checks passed, confirming preservation of ordinary hash routes with queries, nested routes, and referrer values containing literal or encoded #. Canonical login redirect and register/reset cleanup checks also passed.

Re-reviewed the full diff and callback flow; found no additional blockers. No files changed.

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Codex adversarial review, pass 3 (codex-cli 0.159.2, commit f69292a)

Nothing blocking remains. I re-reviewed all three commits with git diff origin/main...HEAD and the newest fix with git show HEAD. No nonblocking findings either.

Verified against the installed history/router and the actual guard and callback code:

  • /%73ignin, /%53IGNUP, and encoded /oidc/login paths are rejected.
  • Malformed path encoding clears the saved return page.
  • /orgs/My%20Org/, queries, and referrers containing encoded or literal # retain the original route.
  • One-time consumption and legacy callback fallbacks work.

All 308 unit tests passed. No files were edited. This was local verification; a live Keycloak round trip was not exercised.

@paynejd
paynejd merged commit 7221d5f into main Sep 30, 2026
2 checks passed
@paynejd
paynejd deleted the ocl_issues-2857-signin-redirect branch September 30, 2026 23:34
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.

Mapper: "Sign in and start mapping" fails with "Incorrect redirect_uri" for visitors from openconceptlab.org

1 participant