mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-08-14 14:57:28 +00:00
fix(pwa): return the caller's own host in the CLI device-flow URLs (#105)
`logicsrc login --device` told users to open https://logicsrc-credentials-production.up.railway.app/cli/device even when they had reached the app on the real domain. /cli/device/code built verification_uri from `config.origin`, which is a single fixed value read from $PUBLIC_ORIGIN, so the response was wrong for every hostname except the one that variable happened to name. Derive the origin from the request instead: whatever host the CLI called is the host it gets sent back to. Express honours X-Forwarded-Proto/Host here because server.mjs sets `trust proxy` behind Railway's TLS terminator. Deliberately scoped to the two device-flow URLs. The WebAuthn expectedOrigin in passkey.mjs stays pinned to config.origin — validating a signature against a host the caller supplied would defeat the check. Note this fixes which URL is *printed*; the host still has to route to this service for the link to load. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0510d86f85
commit
60c0cbfbce
3 changed files with 83 additions and 2 deletions
|
|
@ -17,6 +17,7 @@ import { token, sha256 } from "../lib/crypto.mjs";
|
|||
import { page, footer, appBar, esc } from "../lib/html.mjs";
|
||||
import { requireAuth, csrfInput } from "../lib/session.mjs";
|
||||
import { createApiKey, bearer, userForApiKey } from "../lib/apikey.mjs";
|
||||
import { requestOrigin } from "../lib/origin.mjs";
|
||||
import { config } from "../config.mjs";
|
||||
|
||||
export const cliRouter = Router();
|
||||
|
|
@ -127,11 +128,14 @@ cliRouter.post("/cli/device/code", async (req, res) => {
|
|||
`INSERT INTO cli_device_codes (device_code_hash,user_code,name,status,created_at,expires_at) VALUES (?,?,?,'pending',?,?)`,
|
||||
[sha256(deviceCode), code, name, now, now + DEVICE_TTL_MS]
|
||||
);
|
||||
// Echo back the host the CLI actually called us on, not $PUBLIC_ORIGIN — the
|
||||
// user is told to open this link, and it has to be a domain they can reach.
|
||||
const origin = requestOrigin(req, config.origin);
|
||||
res.json({
|
||||
device_code: deviceCode,
|
||||
user_code: code,
|
||||
verification_uri: `${config.origin}/cli/device`,
|
||||
verification_uri_complete: `${config.origin}/cli/device?user_code=${encodeURIComponent(code)}`,
|
||||
verification_uri: `${origin}/cli/device`,
|
||||
verification_uri_complete: `${origin}/cli/device?user_code=${encodeURIComponent(code)}`,
|
||||
expires_in: Math.floor(DEVICE_TTL_MS / 1000),
|
||||
interval: DEVICE_POLL_SECONDS
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue