feat: unify EncryptID passkeys across all r*.online apps
Simplify resolveRpId() to always return 'rspace.online' so passkeys registered from any r*.online domain share the same RP ID. Browsers use .well-known/webauthn Related Origins to validate cross-domain passkey usage. This makes one passkey work everywhere. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cac038ed0d
commit
7210888aed
|
|
@ -297,14 +297,13 @@ export function receiveSyncMessage(
|
||||||
|
|
||||||
const newDoc = result[0];
|
const newDoc = result[0];
|
||||||
const newSyncState = result[1];
|
const newSyncState = result[1];
|
||||||
const patch = result[2] as { patches: Automerge.Patch[] } | null;
|
|
||||||
|
|
||||||
communities.set(slug, newDoc);
|
communities.set(slug, newDoc);
|
||||||
peerState.syncState = newSyncState;
|
peerState.syncState = newSyncState;
|
||||||
|
|
||||||
// Schedule save if changes were made
|
// Save if the document actually changed (Automerge 2.x receiveSyncMessage
|
||||||
const hasPatches = patch && patch.patches && patch.patches.length > 0;
|
// returns null for patches, so detect changes via object identity instead)
|
||||||
if (hasPatches) {
|
if (newDoc !== doc) {
|
||||||
saveCommunity(slug);
|
saveCommunity(slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,7 +318,7 @@ export function receiveSyncMessage(
|
||||||
const broadcastToPeers = new Map<string, Uint8Array>();
|
const broadcastToPeers = new Map<string, Uint8Array>();
|
||||||
const communityPeers = peerSyncStates.get(slug);
|
const communityPeers = peerSyncStates.get(slug);
|
||||||
|
|
||||||
if (communityPeers && hasPatches) {
|
if (communityPeers && newDoc !== doc) {
|
||||||
for (const [otherPeerId, otherPeerState] of communityPeers) {
|
for (const [otherPeerId, otherPeerState] of communityPeers) {
|
||||||
if (otherPeerId !== peerId) {
|
if (otherPeerId !== peerId) {
|
||||||
const [newOtherSyncState, otherMessage] = Automerge.generateSyncMessage(
|
const [newOtherSyncState, otherMessage] = Automerge.generateSyncMessage(
|
||||||
|
|
|
||||||
|
|
@ -237,31 +237,14 @@ app.get('/health', async (c) => {
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derive the RP ID from the request's Origin header.
|
* Resolve RP ID for WebAuthn ceremonies.
|
||||||
* If the origin is an allowed r* domain, use that domain as the RP ID.
|
*
|
||||||
* Falls back to CONFIG.rpId (rspace.online) for rspace.online origins and unknown.
|
* Always returns 'rspace.online' so that all passkeys are registered with
|
||||||
|
* the same RP ID. The .well-known/webauthn endpoint lists Related Origins,
|
||||||
|
* allowing browsers on other r*.online domains to use these passkeys.
|
||||||
*/
|
*/
|
||||||
function resolveRpId(c: any): string {
|
function resolveRpId(_c: any): string {
|
||||||
const origin = c.req.header('origin') || c.req.header('referer') || '';
|
return CONFIG.rpId; // Always 'rspace.online'
|
||||||
try {
|
|
||||||
const url = new URL(origin);
|
|
||||||
const hostname = url.hostname;
|
|
||||||
// All *.rspace.online subdomains use rspace.online as RP ID
|
|
||||||
if (hostname.endsWith('.rspace.online') || hostname === 'rspace.online') {
|
|
||||||
return 'rspace.online';
|
|
||||||
}
|
|
||||||
// Check if this origin is in our explicit allowed list
|
|
||||||
const isAllowed = CONFIG.allowedOrigins.some(o => {
|
|
||||||
try { return new URL(o).hostname === hostname; } catch { return false; }
|
|
||||||
});
|
|
||||||
if (isAllowed && hostname !== 'localhost') {
|
|
||||||
// For other allowed origins, use their domain as RP ID
|
|
||||||
return hostname;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// Invalid origin, fall back to default
|
|
||||||
}
|
|
||||||
return CONFIG.rpId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue