From e65cfffefdcfed8eed4eef231e9c2b0fe57ba940 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 18 Feb 2026 10:49:35 +0000 Subject: [PATCH] feat: move EncryptID to auth.rspace.online, rebrand as rStack Identity Traefik routes auth.rspace.online (priority 150) with encryptid.jeffemmett.com fallback. Landing page rebranded as rStack Identity with rStack.online ecosystem tagline. Registration form now includes optional email for account recovery. JWT issuer and recovery URL updated. 14 r* apps listed. Co-Authored-By: Claude Opus 4.6 --- docker-compose.encryptid.yml | 5 +-- src/encryptid/server.ts | 69 ++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/docker-compose.encryptid.yml b/docker-compose.encryptid.yml index 44e2917..10223b5 100644 --- a/docker-compose.encryptid.yml +++ b/docker-compose.encryptid.yml @@ -21,12 +21,13 @@ services: - SMTP_USER=${SMTP_USER:-noreply@jeffemmett.com} - SMTP_PASS=${SMTP_PASS} - SMTP_FROM=${SMTP_FROM:-EncryptID } - - RECOVERY_URL=${RECOVERY_URL:-https://encryptid.jeffemmett.com/recover} + - RECOVERY_URL=${RECOVERY_URL:-https://auth.rspace.online/recover} labels: # Traefik auto-discovery - "traefik.enable=true" - - "traefik.http.routers.encryptid.rule=Host(`encryptid.jeffemmett.com`)" + - "traefik.http.routers.encryptid.rule=Host(`auth.rspace.online`) || Host(`encryptid.jeffemmett.com`)" - "traefik.http.routers.encryptid.entrypoints=web" + - "traefik.http.routers.encryptid.priority=150" - "traefik.http.services.encryptid.loadbalancer.server.port=3000" # Also serve from root domain for .well-known (WebAuthn Related Origins) - "traefik.http.routers.encryptid-wellknown.rule=Host(`jeffemmett.com`) && PathPrefix(`/.well-known/webauthn`)" diff --git a/src/encryptid/server.ts b/src/encryptid/server.ts index 4e91399..f33a33e 100644 --- a/src/encryptid/server.ts +++ b/src/encryptid/server.ts @@ -64,8 +64,9 @@ const CONFIG = { pass: process.env.SMTP_PASS || '', from: process.env.SMTP_FROM || 'EncryptID ', }, - recoveryUrl: process.env.RECOVERY_URL || 'https://encryptid.jeffemmett.com/recover', + recoveryUrl: process.env.RECOVERY_URL || 'https://auth.rspace.online/recover', allowedOrigins: [ + 'https://auth.rspace.online', 'https://encryptid.jeffemmett.com', 'https://jeffemmett.com', 'https://rspace.online', @@ -132,11 +133,11 @@ async function sendRecoveryEmail(to: string, token: string, username: string): P await smtpTransport.sendMail({ from: CONFIG.smtp.from, to, - subject: 'EncryptID — Account Recovery', + subject: 'rStack — Account Recovery', text: [ `Hi ${username},`, '', - 'A recovery request was made for your EncryptID account.', + 'A recovery request was made for your rStack account.', 'Use the link below to add a new passkey:', '', recoveryLink, @@ -144,7 +145,7 @@ async function sendRecoveryEmail(to: string, token: string, username: string): P 'This link expires in 30 minutes.', 'If you did not request this, you can safely ignore this email.', '', - '— EncryptID', + '— rStack Identity', ].join('\n'), html: ` @@ -156,11 +157,11 @@ async function sendRecoveryEmail(to: string, token: string, username: string): P
🔒
-

EncryptID

+

rStack Identity

Hi ${username},

-

A recovery request was made for your EncryptID account. Click below to add a new passkey:

+

A recovery request was made for your rStack account. Click below to add a new passkey:

Recover Account @@ -281,7 +282,7 @@ app.post('/api/register/start', async (c) => { * Complete registration - verify and store credential */ app.post('/api/register/complete', async (c) => { - const { challenge, credential, userId, username } = await c.req.json(); + const { challenge, credential, userId, username, email } = await c.req.json(); // Verify challenge const challengeRecord = await getChallenge(challenge); @@ -301,6 +302,11 @@ app.post('/api/register/complete', async (c) => { const did = `did:key:${userId.slice(0, 32)}`; await createUser(userId, username, username, did); + // Set recovery email if provided during registration + if (email && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { + await setUserEmail(userId, email); + } + const storedCredential: StoredCredential = { credentialId: credential.credentialId, publicKey: credential.publicKey, @@ -643,7 +649,7 @@ async function generateSessionToken(userId: string, username: string): Promise { - EncryptID — Account Recovery + rStack Identity — Account Recovery