fix: Amber login callback URL for HashRouter
BUG #1 (critical): buildCallbackUrl() was returning https://skate-spots.org/amber-callback?event= but the app uses HashRouter, so React Router never matched /amber-callback. Amber would open the callback URL in a new tab, land on the homepage, and AmberCallbackPage would never render — login was silently broken. Fixed to: https://skate-spots.org/#/amber-callback?event= BUG #2: AmberCallbackHandler (global, in App.tsx) was competing with AmberCallbackPage on the /amber-callback route, causing a race condition where the global handler could consume the pubkey before the page component. Fixed by detecting the hash path and early-returning when on /amber-callback. BONUS: openAmberForLogin() now persists amber_return_path from the current hash path so AmberCallbackPage can navigate back to where the user was. Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
parent
4f7852fec7
commit
59eda93641
2 changed files with 24 additions and 2 deletions
|
|
@ -40,6 +40,14 @@ export function AmberCallbackHandler() {
|
|||
console.log('[AmberCallback] Search:', window.location.search);
|
||||
console.log('[AmberCallback] Pre-captured event:', sessionStorage.getItem('amber_callback_event'));
|
||||
|
||||
// If we're already on the /amber-callback route, AmberCallbackPage handles
|
||||
// the processing — this global handler must stay silent to avoid a race.
|
||||
const hashPath = window.location.hash.replace(/^#/, '').split('?')[0];
|
||||
if (hashPath === '/amber-callback') {
|
||||
console.log('[AmberCallback] On /amber-callback route — deferring to AmberCallbackPage');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is an Amber callback
|
||||
const isCallback = isAmberCallback();
|
||||
console.log('[AmberCallback] isAmberCallback():', isCallback);
|
||||
|
|
|
|||
|
|
@ -270,9 +270,15 @@ function generateOperationId(): string {
|
|||
/**
|
||||
* Build the dedicated Amber callback URL.
|
||||
*
|
||||
* This app uses HashRouter, so ALL in-app routes live inside the hash fragment:
|
||||
* https://skate-spots.org/#/amber-callback
|
||||
*
|
||||
* Amber will open the callbackUrl in the browser after the user approves.
|
||||
* The URL must therefore use the hash-based path so React Router can match
|
||||
* the /amber-callback route and render AmberCallbackPage.
|
||||
*
|
||||
* In the Capacitor APK we must use the app's custom URI scheme so Android fires
|
||||
* an intent back into the app (not a browser navigation).
|
||||
* Web/PWA builds use the normal https origin.
|
||||
*
|
||||
* The app ID is `org.skatespots.app` — Capacitor registers this as a URI scheme
|
||||
* automatically via the `appId` in capacitor.config.ts.
|
||||
|
|
@ -285,7 +291,10 @@ function buildCallbackUrl(): string {
|
|||
// correct route inside the HashRouter.
|
||||
return 'org.skatespots.app://amber-callback?event=';
|
||||
}
|
||||
return `${window.location.origin}/amber-callback?event=`;
|
||||
// HashRouter: routes live in the # fragment, so the callback URL must be:
|
||||
// https://skate-spots.org/#/amber-callback?event=<result>
|
||||
// This is what Amber will open in the browser tab after user approves.
|
||||
return `${window.location.origin}/#/amber-callback?event=`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -336,6 +345,11 @@ export function openAmberForLogin(): void {
|
|||
|
||||
setAmberPendingOperation(pendingOp);
|
||||
|
||||
// Store the current hash path so AmberCallbackPage can navigate back here
|
||||
// after login (e.g. user was on /map and tapped Login → returns to /map).
|
||||
const currentPath = window.location.hash.replace(/^#/, '') || '/';
|
||||
localStorage.setItem('amber_return_path', currentPath);
|
||||
|
||||
// NIP-55 nostrsigner: URI — Amber opens, user approves, Amber calls callbackUrl
|
||||
const amberUrl = `nostrsigner:?compressionType=none&returnType=signature&type=get_public_key&callbackUrl=${encodeURIComponent(callbackUrl)}`;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue