fix: change WebAuthn RP ID from jeffemmett.com to rspace.online
The RP ID jeffemmett.com caused "relying party ID is not a registrable domain suffix" errors on *.rspace.online subdomains. Related Origins also exceeded the 5 eTLD+1 browser limit with 18+ domains listed. Now rspace.online is the RP ID, so all *.rspace.online subdomains (including cca.rspace.online) are valid automatically. The Related Origins file only lists non-rspace.online r* ecosystem domains. Also points rspace-header auth URL to auth.rspace.online. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
73aee64401
commit
9f39e2393b
|
|
@ -29,8 +29,8 @@ services:
|
||||||
- "traefik.http.routers.encryptid.entrypoints=web"
|
- "traefik.http.routers.encryptid.entrypoints=web"
|
||||||
- "traefik.http.routers.encryptid.priority=150"
|
- "traefik.http.routers.encryptid.priority=150"
|
||||||
- "traefik.http.services.encryptid.loadbalancer.server.port=3000"
|
- "traefik.http.services.encryptid.loadbalancer.server.port=3000"
|
||||||
# Also serve from root domain for .well-known (WebAuthn Related Origins)
|
# Also serve from RP ID domain for .well-known (WebAuthn Related Origins)
|
||||||
- "traefik.http.routers.encryptid-wellknown.rule=Host(`jeffemmett.com`) && PathPrefix(`/.well-known/webauthn`)"
|
- "traefik.http.routers.encryptid-wellknown.rule=Host(`rspace.online`) && PathPrefix(`/.well-known/webauthn`)"
|
||||||
- "traefik.http.routers.encryptid-wellknown.entrypoints=web"
|
- "traefik.http.routers.encryptid-wellknown.entrypoints=web"
|
||||||
- "traefik.http.routers.encryptid-wellknown.priority=200"
|
- "traefik.http.routers.encryptid-wellknown.priority=200"
|
||||||
- "traefik.http.routers.encryptid-wellknown.service=encryptid"
|
- "traefik.http.routers.encryptid-wellknown.service=encryptid"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SESSION_KEY = 'encryptid_session';
|
const SESSION_KEY = 'encryptid_session';
|
||||||
const ENCRYPTID_URL = 'https://encryptid.jeffemmett.com';
|
const ENCRYPTID_URL = 'https://auth.rspace.online';
|
||||||
|
|
||||||
interface SessionState {
|
interface SessionState {
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,9 @@
|
||||||
{
|
{
|
||||||
"origins": [
|
"origins": [
|
||||||
"https://rspace.online",
|
|
||||||
"https://app.rspace.online",
|
|
||||||
"https://dev.rspace.online",
|
|
||||||
"https://rwallet.online",
|
"https://rwallet.online",
|
||||||
"https://app.rwallet.online",
|
|
||||||
"https://rvote.online",
|
"https://rvote.online",
|
||||||
"https://app.rvote.online",
|
|
||||||
"https://rmaps.online",
|
"https://rmaps.online",
|
||||||
"https://app.rmaps.online",
|
|
||||||
"https://rfiles.online",
|
"https://rfiles.online",
|
||||||
"https://app.rfiles.online",
|
"https://rnotes.online"
|
||||||
"https://encryptid.jeffemmett.com",
|
|
||||||
"https://jeffemmett.com",
|
|
||||||
"https://canvas.jeffemmett.com",
|
|
||||||
"http://localhost:3000",
|
|
||||||
"http://localhost:5173"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,26 @@ const server = Bun.serve<WSData>({
|
||||||
return new Response("WebSocket upgrade failed", { status: 400 });
|
return new Response("WebSocket upgrade failed", { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serve .well-known/webauthn for WebAuthn Related Origins
|
||||||
|
// RP ID is rspace.online — *.rspace.online subdomains are automatic,
|
||||||
|
// this file lists non-rspace.online origins that should also be allowed.
|
||||||
|
if (url.pathname === "/.well-known/webauthn") {
|
||||||
|
return Response.json({
|
||||||
|
origins: [
|
||||||
|
"https://rwallet.online",
|
||||||
|
"https://rvote.online",
|
||||||
|
"https://rmaps.online",
|
||||||
|
"https://rfiles.online",
|
||||||
|
"https://rnotes.online",
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
"Cache-Control": "public, max-age=3600",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// API routes
|
// API routes
|
||||||
if (url.pathname.startsWith("/api/")) {
|
if (url.pathname.startsWith("/api/")) {
|
||||||
return handleAPI(req, url);
|
return handleAPI(req, url);
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import {
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
port: process.env.PORT || 3000,
|
port: process.env.PORT || 3000,
|
||||||
rpId: 'jeffemmett.com',
|
rpId: 'rspace.online',
|
||||||
rpName: 'EncryptID',
|
rpName: 'EncryptID',
|
||||||
jwtSecret: (() => {
|
jwtSecret: (() => {
|
||||||
const secret = process.env.JWT_SECRET;
|
const secret = process.env.JWT_SECRET;
|
||||||
|
|
@ -66,10 +66,14 @@ const CONFIG = {
|
||||||
},
|
},
|
||||||
recoveryUrl: process.env.RECOVERY_URL || 'https://auth.rspace.online/recover',
|
recoveryUrl: process.env.RECOVERY_URL || 'https://auth.rspace.online/recover',
|
||||||
allowedOrigins: [
|
allowedOrigins: [
|
||||||
'https://auth.rspace.online',
|
// rspace.online — RP ID domain and all subdomains
|
||||||
'https://encryptid.jeffemmett.com',
|
|
||||||
'https://jeffemmett.com',
|
|
||||||
'https://rspace.online',
|
'https://rspace.online',
|
||||||
|
'https://auth.rspace.online',
|
||||||
|
'https://cca.rspace.online',
|
||||||
|
'https://demo.rspace.online',
|
||||||
|
'https://app.rspace.online',
|
||||||
|
'https://dev.rspace.online',
|
||||||
|
// r* ecosystem apps (each *.online is an eTLD+1 — Related Origins limit is 5)
|
||||||
'https://rwallet.online',
|
'https://rwallet.online',
|
||||||
'https://rvote.online',
|
'https://rvote.online',
|
||||||
'https://rmaps.online',
|
'https://rmaps.online',
|
||||||
|
|
@ -84,11 +88,7 @@ const CONFIG = {
|
||||||
'https://rstack.online',
|
'https://rstack.online',
|
||||||
'https://rpubs.online',
|
'https://rpubs.online',
|
||||||
'https://rauctions.online',
|
'https://rauctions.online',
|
||||||
'https://shop.mycofi.earth',
|
// Development
|
||||||
'https://canvas.jeffemmett.com',
|
|
||||||
'https://press.jeffemmett.com',
|
|
||||||
'https://cart.jeffemmett.com',
|
|
||||||
'https://cart.mycofi.earth',
|
|
||||||
'http://localhost:3000',
|
'http://localhost:3000',
|
||||||
'http://localhost:5173',
|
'http://localhost:5173',
|
||||||
],
|
],
|
||||||
|
|
@ -205,10 +205,14 @@ app.use('*', cors({
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Serve .well-known/webauthn for Related Origins
|
// Serve .well-known/webauthn for Related Origins
|
||||||
|
// Only list non-rspace.online origins here — *.rspace.online subdomains are
|
||||||
|
// automatically valid because rspace.online is the RP ID.
|
||||||
|
// Keep to max 5 eTLD+1 labels to stay within browser limits.
|
||||||
app.get('/.well-known/webauthn', (c) => {
|
app.get('/.well-known/webauthn', (c) => {
|
||||||
return c.json({
|
const nonRspaceOrigins = CONFIG.allowedOrigins.filter(
|
||||||
origins: CONFIG.allowedOrigins.filter(o => o.startsWith('https://')),
|
o => o.startsWith('https://') && !o.endsWith('.rspace.online') && o !== 'https://rspace.online'
|
||||||
});
|
);
|
||||||
|
return c.json({ origins: nonRspaceOrigins });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Health check — includes database connectivity
|
// Health check — includes database connectivity
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export interface EncryptIDConfig {
|
||||||
|
|
||||||
// Default configuration for EncryptID
|
// Default configuration for EncryptID
|
||||||
const DEFAULT_CONFIG: EncryptIDConfig = {
|
const DEFAULT_CONFIG: EncryptIDConfig = {
|
||||||
rpId: 'jeffemmett.com', // Root domain for Related Origins to work across subdomains
|
rpId: 'rspace.online', // Root domain — all *.rspace.online subdomains are valid
|
||||||
rpName: 'EncryptID',
|
rpName: 'EncryptID',
|
||||||
origin: typeof window !== 'undefined' ? window.location.origin : '',
|
origin: typeof window !== 'undefined' ? window.location.origin : '',
|
||||||
userVerification: 'required',
|
userVerification: 'required',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue