Supabase Auth and password recovery

Supabase owns passwords, recovery tokens, verification, and email delivery. The server calls Supabase's native Auth REST endpoints. There is no custom reset-token table, generated reset token, mail sender, or SMTP code in this app.

Configuration status

Implementation and branded templates are in the repository. A Supabase project, publishable key, production domain, and management access have not been supplied, so live Supabase settings and real email delivery have not been configured or verified.

Set SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, and APP_ORIGIN on the server. Production startup refuses to run without Supabase configured. For a local development server use APP_ORIGIN=http://127.0.0.1:4173. Add these exact development redirect URLs in Supabase Auth → URL Configuration:

For production, use the real HTTPS origin. The checked-in configuration script preserves existing redirect entries and SMTP settings, and applies the site URL, exact production recovery/confirmation redirects, and both email templates:

node scripts/configure-supabase-auth.mjs
node scripts/configure-supabase-auth.mjs --apply

The first command previews the target. The second uses SUPABASE_ACCESS_TOKEN from the environment. It verifies settings after applying. Do not commit access tokens. Alternatively paste supabase/templates/recovery.html into Auth → Email Templates → Reset password, and confirmation.html into Confirm signup. Subject: “Reset your Digital Walls password”.

Vercel

Connecting the Supabase integration in Vercel sets SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, and POSTGRES_URL. Runtime API traffic uses POSTGRES_URL on the transaction pooler (port 6543). Schema migrations at deploy/cold start use a session URL (port 5432 on the same pooler host, or POSTGRES_URL_NON_POOLING when reachable). Set DATABASE_URL only to override the runtime URI. Users, sessions, walls, share tokens, and image bytes are stored there.

Set APP_ORIGIN to the URL people open. Add these redirects for that origin in Auth → URL Configuration:

If DATABASE_URL is missing, the site still opens for guests and account routes respond with 503. They do not save accounts on Vercel's temporary disk.

Email delivery

Use Supabase's default email provider during development. It restricts recipients and sending volume; test with project-team addresses supported by that provider. Before public production, configure custom SMTP in Supabase, including sender identity/domain verification. No application code needs to change. The app never sends reset emails itself.

Flow

Forgot password → POST /api/password-reset → Supabase /recover → Supabase sends the branded email → /?auth=recovery → Continue verifies Supabase's token hash at /verify → new password form → Supabase /user update → app sessions invalidated → sign in with the new password.

The branded template passes Supabase's TokenHash; it is not an application-generated token. Verification waits for an explicit click, avoiding consumption by simple email-link previews. Token-bearing parameters are removed from browser history immediately. The default Supabase ConfirmationURL fragment callback is also supported. Expired links, mismatched passwords, provider rate limits, network failures, and missing configuration are visible.

Signup/login also use Supabase when configured. This is necessary so resetting a password changes the credential the app actually uses. Confirmation emails must be enabled for production. Use a 12-character minimum password policy in the Supabase dashboard as well as the frontend policy.

App sessions remain HttpOnly cookies. Supabase access/refresh tokens are stored server-side in the private database, refreshed as needed, and never returned in application API responses. Database backups contain authentication material and require the same restricted access as the database. Existing local-development sessions are refused when Supabase is enabled. A verified Supabase email can attach to a previously local account while preserving its board IDs and URLs; an existing different Supabase identity cannot claim it.

The previous local password implementation is disabled by default and available only to isolated automated tests with ALLOW_LOCAL_AUTH_FOR_TESTS=1. It has no password recovery and cannot run in production. Normal development uses Supabase Auth and its default email provider. Existing development passwords are not migrated to Supabase; register/confirm the same email with Supabase to retain that account's boards.

Guest retention

Guest boards are stored on the device. Clicking Sign up / save board records the draft and intended account email before authentication. The draft survives signup errors and email confirmation. On successful sign-in with that email it creates a private owned board, uploads images, and saves all content. The local draft is removed only after a successful server save. An interrupted transfer remembers its destination board for retry. Browser/device changes cannot carry an unsynced guest draft; finish signup in the same browser to claim it.

Verification still required with the real project

Request an email using the default provider; open the branded link; reject mismatching passwords; set a new password; verify the old password fails and the new one succeeds. Retry an expired/used link. Verify production redirects and then repeat delivery with custom SMTP before public launch. Automated adapter tests use an injected provider response and do not prove live email delivery.

References: Supabase Auth REST API, email templates, SMTP, management configuration.