OPC Stack uses Better Auth for authentication and supports email and Google sign in.
Email sign in
Setup steps
- Buy a domain or use an existing domain
- Move domain DNS to Cloudflare and subdomain is supported like
mail.example.com - Sign up for Resend
- Add your domain in Resend and verify DNS records
- Create an API key
- Configure environment variables:
EMAIL_ENABLED=true
EMAIL_FROM=noreply@example.com
RESEND_API_KEY=re_xxx
Flow
User enters email
↓
Send verification code by Resend
↓
User enters verification code
↓
Verification passed and session is created
↓
Return token
Middleware
emailAuthMiddleware checks:
- whether
EMAIL_ENABLEDis true - whether
EMAIL_FROMandRESEND_API_KEYare configured - whether user email is verified
Google sign in
Setup steps
- Open Google Cloud Console
- Create OAuth 2.0 Client ID
- Set redirect URI:
https://your-domain.com/api/auth/callback/google - Configure environment variables:
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxx
Flow
User clicks Google sign in
↓
Redirect to Google consent page
↓
User grants permission
↓
Google redirects to /api/auth/callback/google
↓
Create or update user
↓
Create session and return token
Authentication middlewares
authMiddleware
Injects userId into ctx.variables and does not block request.
betaGateMiddleware
If BETA_CODE_ENABLED=true, checks whether user is bound to beta code.
Session management
Better Auth stores sessions in D1. d1SessionMiddleware injects db instance and handles bookmark for read consistency.
Frontend integration
// src/web/lib/auth.ts
import { createAuthClient } from 'better-auth/client'
export const authClient = createAuthClient({
baseURL: '/api/auth'
})
// Sign in
await authClient.signIn.email({
email: 'user@example.com',
callbackURL: '/'
})
// Sign out
await authClient.signOut()
// Get current user
const session = await authClient.getSession()
FAQ
Q: I cannot receive email verification code
Check Resend DNS records and inspect send logs in Resend dashboard.
Q: Google sign in fails with redirect_uri_mismatch
Ensure redirect URI configured in Google Cloud Console exactly matches the real callback URL.
Q: How to customize email template
Update emailAndPassword plugin config in src/api/auth/index.ts.