When EncryptID server returns plain text errors (e.g. "Internal Server
Error"), the client's .json() calls threw SyntaxError which surfaced
as an ugly parse error to users. Add .catch() to all unsafe .json()
calls in session.ts, login-button.ts, and recovery.ts so auth
gracefully falls back to unsigned tokens instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a user logs out in one browser, all other sessions are now revoked
on their next page load or token refresh. Adds logged_out_at column to
users table, server-side revocation checks on verify/refresh endpoints,
and a new /api/session/logout endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Session manager now calls EncryptID /api/auth/start + /api/auth/complete
to get a properly signed JWT instead of creating unsigned local tokens.
This fixes 401 errors on /api/payments, /api/notifications, and other
authenticated endpoints that verify tokens via EncryptID server.
- Token refresh calls /api/session/refresh instead of extending unsigned tokens
- Server generateSessionToken now includes authTime, jti, recoveryConfigured
- rNetwork: /crm route renders folk-crm-view instead of iframe
- rNetwork: ?view=app redirects 301 to /crm (backward compat)
- rNetwork: graph viewer always uses API (removed hardcoded demo data)
- docker-compose: pass through TWENTY_API_TOKEN from Infisical
- rcart: add catalog product images
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- L-1: Remove internal error details from SIWE verify response
- L-2: Stop forwarding raw Safe API error bodies to clients (log server-side)
- L-3: Evict stale keys from nonce rate limiter to prevent memory leak
- L-4: Add input length/type guards on wallet-link verify body fields
- L-5: Sanitize and cap limit query param on Safe transfers route (max 200)
- L-6: Server recomputes addressHash from SIWE address instead of trusting
client-supplied value for dedup
- L-7: Reset LinkedWalletStore singleton on logout to clear cached keys
- I-1: Add X-Content-Type-Options, X-Frame-Options, Referrer-Policy headers
- I-9: Build EIP712Domain type array dynamically from domain fields in
ExternalSigner.signTypedData (was hardcoded to empty, dropping fields)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Users can now connect browser wallets (MetaMask, Rainbow, etc.) to their
EncryptID identity via SIWE ownership proof, and view linked wallet
balances in the unified rWallet viewer.
New files:
- eip6963.ts: EIP-6963 multi-provider discovery
- external-signer.ts: EIP-1193 provider wrapper for tx signing
- linked-wallets.ts: encrypted client-side store (same AES-256-GCM pattern)
Server: wallet-link nonce/verify/list/delete routes, linked_wallets table,
Safe add-owner-proposal endpoint, new session permissions.
UI: "My Wallets" section with provider picker, SIWE linking flow,
wallet type badges, and click-to-view for linked wallets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Derive a deterministic secp256k1 EOA from the passkey's PRF output via
HKDF-SHA256, enabling hardware-backed signing for x402 micropayments and
Safe treasury proposals without storing private keys.
Key changes:
- EOA key derivation with domain-separated HKDF (eoa-derivation.ts)
- Key manager integration with PRF-only EOA path (key-derivation.ts)
- Encrypted client-side wallet store for Safe associations (wallet-store.ts)
- Passkey-backed x402 signer replacing EVM_PRIVATE_KEY (passkey-signer.ts)
- Safe propose/confirm/execute proxy routes in rwallet (mod.ts)
- Wallet capability flag in JWT via users.wallet_address (server.ts)
- Payment operation permissions: x402, safe-propose, safe-execute (session.ts)
Privacy: Safe wallet associations stored client-side only (AES-256-GCM
encrypted localStorage). Server only knows user has wallet capability.
108 tests passing across 5 test suites.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part of the ridentity.online branding migration. The EncryptID auth
server is now accessible at auth.ridentity.online (with the legacy
encryptid.jeffemmett.com kept as a backward-compatible alias).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements the EncryptID identity system for the r-ecosystem:
- WebAuthn/Passkey authentication with PRF extension for key derivation
- Client-side cryptographic key derivation (AES-256, ECDSA P-256, Ed25519)
- Social recovery system with guardians (no seed phrases!)
- Session management with authentication levels
- Cross-app SSO via Related Origin Requests
- Web components: login button and guardian setup panel
- Hono server for authentication endpoints
- Docker deployment configuration
Domain: encryptid.jeffemmett.com
RP ID: jeffemmett.com (for cross-subdomain passkey usage)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>