// Backend app for the {{projectName}} project. Read by `voltro dev`. // // This template wires REAL user authentication with @voltro/plugin-auth: // - `authRoutesPlugin(...)` mounts the password auth surface under /auth/* // (POST /auth/sign-up, /auth/sign-in, /auth/sign-out, GET /auth/csrf, // password-reset, magic-link, session management, …). It sets an HttpOnly // session cookie on success. // - `voltroPasswordStrategy(...)` runs in the AuthMiddleware chain: it reads // that session cookie off every rpc/ws call and resolves it to a typed // `Subject` — so handlers see the authenticated user via // `ctx.request.subject` (see actions/me.action.server.ts). // // `memoryUserStore()` keeps users/sessions in-process, so it boots with ZERO // infra. Swap it for `postgresUserStore({ sql })` (and `store: 'postgres'`) // for durable accounts. import { defineEnv, envVar } from '@voltro/env' import { authRoutesPlugin, memoryUserStore, voltroPasswordStrategy } from '@voltro/plugin-auth' export const env = defineEnv({ LOG_LEVEL: envVar.enum(['debug', 'info', 'warn', 'error'], { access: 'public', default: 'info' }), // The HMAC key that signs + verifies session cookies. // // `generate` means this project gets its OWN key: `voltro dev` mints one // into a gitignored `.env.local` on first boot. That is why no value ships // with this template — a shipped placeholder would be a signing key // published to everyone who downloads the template, and every session in // every deployment built from it would be forgeable. // // Your DEPLOYMENT still needs its own: `voltro secret generate session`. VOLTRO_SESSION_SECRET: envVar.secret({ generate: 'base64url', description: 'HMAC key that signs and verifies session cookies.', }), }) // In-process user store — zero infra. `postgresUserStore({ sql })` for durable. const userStore = memoryUserStore() export default { type: 'api' as const, name: '{{capProjectName}}{{capAppName}}', store: 'memory' as const, env, plugins: [ authRoutesPlugin({ store: userStore, // No `secret:` — the plugin reads VOLTRO_SESSION_SECRET when it handles a // request. Passing one here would mean reading process.env at config // time, which runs BEFORE the env gate and before `voltro dev` mints the // project's key, and that is exactly what tempts an app into a hardcoded // fallback. The strategy below resolves the same value the same way, so // the signing and verifying sides cannot drift. defaultTenantId: 'acme', // tenant new sign-ups land in successRedirect: '/', // where the browser-form flow redirects after sign-in // `Secure` cookies are HTTPS-only — so OFF in dev (http://localhost would // silently drop the session cookie), ON in production. This is what makes // the sign-in → session → authenticated-call loop actually work locally. cookieSecure: process.env.NODE_ENV === 'production', }), ], auth: { // Runs after the built-in signed-cookie strategy; resolves the session // cookie this app's /auth routes mint into the request's Subject. strategies: [voltroPasswordStrategy()], }, }