Esposter

Auth

Authentication is OAuth-only through better-auth with the Drizzle adapter — Google, GitHub, and Facebook — mounted at the catch-all server/api/auth/[...].ts. Sessions are cookie-based; the Vue client reads them through authClient.useSession (better-auth's Vue plugin with the server's inferred additional fields, so user.biography is typed end-to-end).

How it works

flowchart LR
  login[login page\nGoogle / GitHub / Facebook] --> ba[better-auth handler\nserver/api/auth/...]
  ba --> pg[(users / sessions tables\nDrizzle adapter)]
  page[auth-gated page] --> mw[auth middleware\nsession? else /login]
  client[$trpc call] --> proc[standardAuthedProcedure]
  proc --> isAuthed[getIsAuthed + rate limiter\nsession → AuthedContext]
  proc --> plugin[achievementPlugin]
  • Route gatingdefinePageMeta({ middleware: "auth" }) redirects signed-out visitors to /login; the login page itself uses the inverse guest middleware. Everything else is public by default.
  • Procedure gatingstandardAuthedProcedure = publicProcedure + getIsAuthed(RateLimiterType.Standard) (session check + rate limiting in one middleware, yielding AuthedContext with getSessionPayload) + the achievement plugin. standardRateLimitedProcedure is the unauthenticated sibling for public reads. Room-scoped RBAC procedures build on top (see esbabbler RBAC).
  • Users table — better-auth owns the users/sessions schema; Esposter adds biography via additionalFields, validated by the Drizzle-derived Zod schema. better-auth's own endpoints share the standard rate-limiter budget.
  • Device identitygetDeviceId/getIsSameDevice fingerprint requests (push-subscription scoping), and generateToken mints the shared-secret tokens used by webhook delivery.

Key files

Paths relative to packages/app.

FileRole
server/auth.tsbetter-auth configuration
server/api/auth/[...].tsthe mounted auth handler
app/services/auth/authClient.tstyped Vue session client
app/middleware/auth.ts, app/middleware/guest.tsroute gating
server/trpc/middleware/getIsAuthed.tssession + rate-limit middleware
server/trpc/procedure/standardAuthedProcedure.tsthe standard authed chain
server/services/auth/device id + webhook token services

Notes

  • OAuth-only is deliberate — see users rejected: password auth.
  • Anonymous users are first-class where products support it (games persist to localStorage; the feed is readable rate-limited) — auth gates writing and personal state, not browsing.