From abf1b7bb5b598fa670e470124803d02040ef4aaa Mon Sep 17 00:00:00 2001 From: Tomokazu Tantaka Date: Mon, 16 Feb 2026 13:52:10 +0900 Subject: [PATCH 1/2] feat(web): add force password change redirect page Add /auth/force-password-change route that handles the redirect flow for Auth0 password change during login. The page preserves the Auth0 session state across the password change flow so users only need to log in once. Co-Authored-By: Claude Opus 4.6 --- .../ForcePasswordChange/index.tsx | 42 +++++++++++++++++++ web/src/services/routing/index.tsx | 7 ++++ 2 files changed, 49 insertions(+) create mode 100644 web/src/classic/components/pages/Authentication/ForcePasswordChange/index.tsx diff --git a/web/src/classic/components/pages/Authentication/ForcePasswordChange/index.tsx b/web/src/classic/components/pages/Authentication/ForcePasswordChange/index.tsx new file mode 100644 index 000000000..23ab6069f --- /dev/null +++ b/web/src/classic/components/pages/Authentication/ForcePasswordChange/index.tsx @@ -0,0 +1,42 @@ +import { useEffect } from "react"; + +import Loading from "@reearth/classic/components/atoms/Loading"; +import { getAuthInfo } from "@reearth/services/config"; + +const STORAGE_KEY = "reearth_password_change_state"; + +const ForcePasswordChangePage: React.FC = () => { + useEffect(() => { + const params = new URLSearchParams(window.location.search); + const ticket = params.get("ticket"); + const state = params.get("state"); + + if (ticket && state) { + // Coming from Auth0 Post-Login Action redirect. + // Save state to sessionStorage so we can resume the login flow after password change. + sessionStorage.setItem(STORAGE_KEY, state); + // Redirect to Auth0's password change page. + window.location.href = ticket; + return; + } + + // Coming back from Auth0 password change page (result_url redirect). + const savedState = sessionStorage.getItem(STORAGE_KEY); + if (savedState) { + sessionStorage.removeItem(STORAGE_KEY); + const authInfo = getAuthInfo(); + if (authInfo?.auth0Domain) { + // Redirect back to Auth0 to complete the login flow. + window.location.href = `https://${authInfo.auth0Domain}/continue?state=${savedState}`; + return; + } + } + + // Fallback: redirect to top page. + window.location.href = "/"; + }, []); + + return ; +}; + +export default ForcePasswordChangePage; diff --git a/web/src/services/routing/index.tsx b/web/src/services/routing/index.tsx index 0e6420f84..10414e1cb 100644 --- a/web/src/services/routing/index.tsx +++ b/web/src/services/routing/index.tsx @@ -22,6 +22,9 @@ const LoginPage = lazy(() => import("@reearth/classic/components/pages/Authentic const PasswordResetPage = lazy( () => import("@reearth/classic/components/pages/Authentication/PasswordReset"), ); +const ForcePasswordChangePage = lazy( + () => import("@reearth/classic/components/pages/Authentication/ForcePasswordChange"), +); const SignupPage = lazy( () => import("@reearth/classic/components/pages/Authentication/SignupPage"), @@ -57,6 +60,10 @@ export const AppRoutes = () => { index: true, element: , }, + { + path: "auth/force-password-change", + element: , + }, { path: "auth/*", element: , From d36aa57c074d13972f0ba95083be88a696d12260 Mon Sep 17 00:00:00 2001 From: Tomokazu Tantaka Date: Mon, 16 Feb 2026 15:14:48 +0900 Subject: [PATCH 2/2] remove cluade.json --- .claude/settings.local.json | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 000000000..d676cd8a3 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,29 @@ +{ + "permissions": { + "allow": [ + "Bash(xargs cat:*)", + "Bash(find:*)", + "Bash(go env:*)", + "Bash(git checkout:*)", + "Bash(git add:*)", + "Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(reearth/dev\\): use reearth-classic-account as REEARTH_DB_ACCOUNT in dev\n\nDev environment should use a separate account database \\(reearth-classic-account\\)\nto avoid MongoDB schema validation conflicts. Prod remains reearth-account.\n\n- Add reearth_db_account variable to reearth_classic_api module \\(default: reearth-account\\)\n- Set reearth_db_account to reearth-classic-account in dev reearth_classic_api\n- Set databases.account to reearth-classic-account in dev reearth_cloud\n\nCo-Authored-By: Claude Opus 4.6 \nEOF\n\\)\")", + "Bash(git push:*)", + "Bash(gh pr create:*)", + "Bash(grep:*)", + "Bash(git commit -m \"$\\(cat <<''EOF''\nfix\\(reearth/dev\\): grant reearth role access to reearth-classic-account database\n\nThe classic API uses reearth-classic-account as DB_Account, but the\nreearth custom DB role only had permissions for reearth and\nreearth-account databases, causing MongoDB Unauthorized errors on\nuser lookups during authentication.\n\nCo-Authored-By: Claude Opus 4.6 \nEOF\n\\)\")", + "Bash(gh pr close:*)", + "Bash(git fetch:*)", + "Bash(git cherry-pick:*)", + "Bash(gh pr edit:*)", + "Bash(gh pr view:*)", + "Bash(gh run list:*)", + "Bash(git pull:*)", + "Bash(git commit -m \"$\\(cat <<''EOF''\nfeat\\(reearth/dev\\): add reearth-classic-db role and revert reearth role\n\n- Revert the reearth custom role to remove reearth-classic-account\n \\(the reearth-db secret uses reearth-visualizer user, not reearth\\)\n- Add new reearth-classic-db custom role with access to reearth and\n reearth-classic-account databases for the classic API\n\nCo-Authored-By: Claude Opus 4.6 \nEOF\n\\)\")", + "Bash(git commit:*)", + "Bash(gh run watch:*)", + "Bash(gcloud run services describe:*)", + "Bash(python3:*)", + "Bash(gcloud run revisions list:*)" + ] + } +}