fix(encryptid): allow cross-platform authenticators on Linux

Registration was hardcoded to authenticatorAttachment: 'platform',
which rejects devices without a platform authenticator (common on
Linux desktops). Now only forces platform when available, otherwise
lets browser offer cross-platform options (security keys, phone as
authenticator). Also relaxed isEncryptIDAvailable() to only require
WebAuthn support, not platform auth specifically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-04-08 19:30:41 -04:00
parent ca45eb43d2
commit b2d443421e
3 changed files with 8 additions and 7 deletions

View File

@ -108,7 +108,7 @@ import { getRecoveryManager } from './recovery';
*/
export async function isEncryptIDAvailable(): Promise<boolean> {
const caps = await detectCapabilities();
return caps.webauthn && caps.platformAuthenticator;
return caps.webauthn;
}
/**

View File

@ -565,10 +565,11 @@ app.post('/api/register/start', async (c) => {
{ alg: -257, type: 'public-key' }, // RS256
],
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
requireResidentKey: true,
userVerification: 'required',
// Don't force 'platform' — let the browser offer cross-platform
// authenticators (security keys, phone) on devices without platform auth
},
timeout: 60000,
attestation: 'none',
@ -1773,7 +1774,6 @@ app.post('/api/account/device/start', async (c) => {
{ alg: -257, type: 'public-key' },
],
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
requireResidentKey: true,
userVerification: 'required',
@ -2902,7 +2902,7 @@ app.get('/guardian', (c) => {
{ alg: -7, type: 'public-key' },
{ alg: -257, type: 'public-key' },
],
authenticatorSelection: { authenticatorAttachment: 'platform', residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
authenticatorSelection: { residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
attestation: 'none',
timeout: 60000,
},
@ -7727,7 +7727,7 @@ app.get('/', (c) => {
{ alg: -7, type: 'public-key' },
{ alg: -257, type: 'public-key' },
],
authenticatorSelection: { authenticatorAttachment: 'platform', residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
authenticatorSelection: { residentKey: 'required', requireResidentKey: true, userVerification: 'required' },
attestation: 'none',
timeout: 60000,
extensions: { credProps: true, ...prfExtension },

View File

@ -178,8 +178,9 @@ export async function registerPasskey(
// Require user verification (biometric/PIN)
userVerification: cfg.userVerification,
// Force platform authenticator (Windows Hello, Touch ID, etc.)
authenticatorAttachment: 'platform',
// Prefer platform authenticator, but allow cross-platform (security keys,
// phone-as-authenticator) on devices without one (e.g. Linux desktops)
...(platformAvailable ? { authenticatorAttachment: 'platform' as const } : {}),
},
// Don't request attestation (privacy)