diff --git a/src/login.ts b/src/login.ts index 01c3d3d..f295323 100644 --- a/src/login.ts +++ b/src/login.ts @@ -78,7 +78,10 @@ export async function login( interval: number; }; - const verificationUri = `${new URL(base).origin}/activate`; + // Points at the API, which redirects to the dashboard SPA — the CLI only + // knows the API origin, and the approval page lives on the app. The code + // travels in the link so following it is a single confirmation. + const verificationUri = `${base}/device?code=${encodeURIComponent(userCode)}`; onPrompt(userCode, verificationUri); const deadline = now() + expiresIn * 1000; diff --git a/tests/login.test.ts b/tests/login.test.ts index 0c0a6a0..ea1a202 100644 --- a/tests/login.test.ts +++ b/tests/login.test.ts @@ -47,7 +47,12 @@ describe('login', () => { const result = await login(config(), onPrompt, { fetchImpl: fetchImpl as never, ...noSleep }); expect(result.status).toBe('approved'); - expect(onPrompt).toHaveBeenCalledWith('WDJB-MJHT', 'https://api.patchstack.com/activate'); + // The API redirects this to the dashboard SPA; the code rides along so + // following the link is one confirmation rather than a retype. + expect(onPrompt).toHaveBeenCalledWith( + 'WDJB-MJHT', + 'https://api.patchstack.com/monitor/pulse/device?code=WDJB-MJHT', + ); // Both fields: approving rotates the one secret block-logs use too, so // leaving apiKey behind would break block-log reporting.