fix(auth): force platform authenticator + redirect disabled modules
Force authenticatorAttachment: 'platform' across all WebAuthn registration flows to prevent USB security key prompts. Redirect browser navigations to space root when accessing disabled modules instead of returning JSON error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
15f7e759d1
commit
6491681e3e
|
|
@ -673,6 +673,7 @@ export function showAuthModal(callbacks?: Partial<AuthModalCallbacks>): void {
|
|||
{ alg: -257, type: 'public-key' as const },
|
||||
],
|
||||
authenticatorSelection: {
|
||||
authenticatorAttachment: 'platform',
|
||||
residentKey: 'required',
|
||||
requireResidentKey: true,
|
||||
userVerification: 'required',
|
||||
|
|
|
|||
|
|
@ -2056,6 +2056,11 @@ for (const mod of getAllModules()) {
|
|||
const doc = getDocumentData(space);
|
||||
if (mod.id !== "rspace") {
|
||||
if (doc?.meta?.enabledModules && !doc.meta.enabledModules.includes(mod.id)) {
|
||||
// Redirect browser navigations to space root; return JSON error for API calls
|
||||
const accept = c.req.header("Accept") || "";
|
||||
if (accept.includes("text/html")) {
|
||||
return c.redirect(`https://${space}.rspace.online/`);
|
||||
}
|
||||
return c.json({ error: "Module not enabled for this space" }, 404);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ export class RStackIdentity extends HTMLElement {
|
|||
{ alg: -7, type: "public-key" as const },
|
||||
{ alg: -257, type: "public-key" as const },
|
||||
],
|
||||
authenticatorSelection: { residentKey: "required", requireResidentKey: true, userVerification: "required" },
|
||||
authenticatorSelection: { authenticatorAttachment: "platform", residentKey: "required", requireResidentKey: true, userVerification: "required" },
|
||||
attestation: "none",
|
||||
timeout: 60000,
|
||||
},
|
||||
|
|
@ -1127,7 +1127,7 @@ export class RStackIdentity extends HTMLElement {
|
|||
{ alg: -7, type: "public-key" as const },
|
||||
{ alg: -257, type: "public-key" as const },
|
||||
],
|
||||
authenticatorSelection: { residentKey: "required", requireResidentKey: true, userVerification: "required" },
|
||||
authenticatorSelection: { authenticatorAttachment: "platform", residentKey: "required", requireResidentKey: true, userVerification: "required" },
|
||||
attestation: "none",
|
||||
timeout: 60000,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -546,6 +546,7 @@ app.post('/api/register/start', async (c) => {
|
|||
{ alg: -257, type: 'public-key' }, // RS256
|
||||
],
|
||||
authenticatorSelection: {
|
||||
authenticatorAttachment: 'platform',
|
||||
residentKey: 'required',
|
||||
requireResidentKey: true,
|
||||
userVerification: 'required',
|
||||
|
|
@ -1524,6 +1525,7 @@ app.post('/api/account/device/start', async (c) => {
|
|||
{ alg: -257, type: 'public-key' },
|
||||
],
|
||||
authenticatorSelection: {
|
||||
authenticatorAttachment: 'platform',
|
||||
residentKey: 'required',
|
||||
requireResidentKey: true,
|
||||
userVerification: 'required',
|
||||
|
|
@ -2438,7 +2440,7 @@ app.get('/guardian', (c) => {
|
|||
{ alg: -7, type: 'public-key' },
|
||||
{ alg: -257, type: 'public-key' },
|
||||
],
|
||||
authenticatorSelection: { residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
|
||||
authenticatorSelection: { authenticatorAttachment: 'platform', residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
|
||||
attestation: 'none',
|
||||
timeout: 60000,
|
||||
},
|
||||
|
|
@ -7083,7 +7085,7 @@ app.get('/', (c) => {
|
|||
{ alg: -7, type: 'public-key' },
|
||||
{ alg: -257, type: 'public-key' },
|
||||
],
|
||||
authenticatorSelection: { residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
|
||||
authenticatorSelection: { authenticatorAttachment: 'platform', residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
|
||||
attestation: 'none',
|
||||
timeout: 60000,
|
||||
extensions: { credProps: true, ...prfExtension },
|
||||
|
|
|
|||
|
|
@ -178,8 +178,8 @@ export async function registerPasskey(
|
|||
// Require user verification (biometric/PIN)
|
||||
userVerification: cfg.userVerification,
|
||||
|
||||
// Prefer platform authenticator but allow cross-platform
|
||||
authenticatorAttachment: platformAvailable ? 'platform' : undefined,
|
||||
// Force platform authenticator (Windows Hello, Touch ID, etc.)
|
||||
authenticatorAttachment: 'platform',
|
||||
},
|
||||
|
||||
// Don't request attestation (privacy)
|
||||
|
|
|
|||
Loading…
Reference in New Issue