configuration

Auth and Secrets

Configure Better Auth, Turnstile, Resend, and Google OAuth for local and production environments.

Spinupmail's auth setup is split across Worker secrets, frontend environment variables, and a few provider dashboards. The README already covers the exact values and callback rules. This page condenses that flow into one setup guide.

Set the production Worker secrets

Run the secret commands from packages/backend and provide the real values when Wrangler prompts.

BashCLI command example
pnpm exec wrangler secret put BETTER_AUTH_BASE_URL
pnpm exec wrangler secret put BETTER_AUTH_SECRET
pnpm exec wrangler secret put INTEGRATION_SECRET_ENCRYPTION_KEY
pnpm exec wrangler secret put CORS_ORIGIN
pnpm exec wrangler secret put RESEND_API_KEY
pnpm exec wrangler secret put TURNSTILE_SECRET_KEY
pnpm exec wrangler secret put GOOGLE_CLIENT_ID
pnpm exec wrangler secret put GOOGLE_CLIENT_SECRET
SecretWhat it should contain
BETTER_AUTH_BASE_URLYour deployed auth endpoint, such as https://api.spinupmail.com/api/auth
BETTER_AUTH_SECRETA strong random secret, for example from openssl rand -base64 32
INTEGRATION_SECRET_ENCRYPTION_KEYBase64-encoded 32-byte key used to encrypt integration provider credentials (for example Telegram bot tokens), for example from openssl rand -base64 32
CORS_ORIGINComma-separated frontend origins, such as https://app.spinupmail.com
EXTENSION_REDIRECT_ORIGINSComma-separated exact extension redirect origins, such as https://<extension-id>.chromiumapp.org
RESEND_API_KEYResend API key used for verification and reset email
TURNSTILE_SECRET_KEYCloudflare Turnstile secret key
GOOGLE_CLIENT_IDGoogle OAuth web client ID
GOOGLE_CLIENT_SECRETGoogle OAuth web client secret

For integration provider setup and subscription flow, see Integrations.

Add local development secrets

For wrangler dev, create packages/backend/.dev.vars and keep it out of version control.

DotenvEnvironment variables
BETTER_AUTH_BASE_URL="http://localhost:8787/api/auth"
BETTER_AUTH_SECRET=""
INTEGRATION_SECRET_ENCRYPTION_KEY=""
CORS_ORIGIN="http://localhost:5173,http://127.0.0.1:5173"
EXTENSION_REDIRECT_ORIGINS="https://<your-extension-id>.chromiumapp.org"
RESEND_API_KEY=""
TURNSTILE_SECRET_KEY=""
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""

The frontend also needs the Turnstile site key locally:

DotenvEnvironment variables
VITE_TURNSTILE_SITE_KEY=<your site key>

Configure Turnstile and Resend

Turnstile protects the auth forms, while Resend delivers verification and password-reset email.

Turnstile

  1. Open the Cloudflare dashboard and create a Turnstile widget.
  2. Add the frontend hostnames that will render the widget, such as localhost, 127.0.0.1, and your production frontend domain.
  3. Keep the widget in managed mode.
  4. Save the generated keys.
  5. Put the secret key in the Worker as TURNSTILE_SECRET_KEY.
  6. Put the site key in the frontend as VITE_TURNSTILE_SITE_KEY.

Resend

  1. Add and verify your sending domain in Resend.
  2. Create an API key with permission to send email.
  3. Store it as the RESEND_API_KEY Worker secret.
  4. Set [vars].RESEND_FROM_EMAIL in packages/backend/wrangler.toml to a sender on that verified domain, such as Spinupmail <verify@mail.your-domain.com>.

Configure Google OAuth callbacks

Create a Google OAuth web client and use the frontend and backend URLs from your actual deployment.

Authorized JavaScript origins

  • http://127.0.0.1:5173
  • http://localhost:5173
  • https://<your-frontend-domain>.com

Authorized redirect URIs

  • http://localhost:8787/api/auth/callback/google
  • https://api.<your-domain>/api/auth/callback/google
  • https://<your-frontend-domain>/api/auth/callback/google only if your Worker is intentionally routed under /api/* on the same host

After Google issues the credentials, store them with:

BashCLI command example
pnpm exec wrangler secret put GOOGLE_CLIENT_ID
pnpm exec wrangler secret put GOOGLE_CLIENT_SECRET

For local development, also add GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET to packages/backend/.dev.vars.

Optional auth domain restriction

If you set AUTH_ALLOWED_EMAIL_DOMAIN in Worker vars, Spinupmail restricts email and Google-based auth to that domain. The Google flow also receives the same domain as a hosted-domain hint, which keeps the auth UX aligned with internal-only deployments.