@mimird/auth
v0.1.0
Published
Copy-paste auth surface: HS256 JWT session, email + Google/GitHub login, signup, logout, optimistic route guard, styled forms.
Readme
@mimird/auth
A self-contained copy of the Mimird auth surface. Copy this whole folder into another Next 16 App Router app to get the same login. Nothing here links back to the host repo — every import inside the folder is relative.
What's included
- HS256 JWT session in httpOnly cookies (
session.ts) —jose. - Email/password login, signup, logout server actions (
actions.ts). - Google + GitHub OAuth plumbing (
oauth.ts) + the two route handlers. getCurrentUser()/getAccessToken()(auth.ts).- Optimistic route guard for the edge proxy (
next/proxy.ts). - Styled
LoginForm/SignupForm+ the shadcn/base-ui primitives they need (ui/), plus the design tokens (styles/auth-tokens.css). - Backend contract adapter (
backend-client.ts) — assumes a FastAPI-stylePOST /api/v1/auth/{login,signup,oauth}; adjustparseAuthResponsethere if your backend differs.
Layout
| Path | Role |
|---|---|
| config.ts | The one file to edit per app — env reads, cookie prefix, redirect paths, backend URL + auth paths, OAuth creds, demo user. |
| routing.ts | Cookie names + route paths with no server-only — imported by next/proxy.ts. config.ts re-exports it. |
| session.ts oauth.ts backend-client.ts auth.ts schemas.ts actions.ts types.ts | Server-side auth logic. |
| ui/ | Client form components + primitives/ (button, input, label, separator), cn.ts, icons.tsx. |
| next/ | Templates you copy into your app's app/ tree / repo root (see below). They import from ../ so they type-check here; fix the paths after copying. |
| styles/auth-tokens.css | CSS custom properties the ui/ classes reference. |
Wiring a target repo
Copy
packages/auth/into the target repo (e.g. atpackages/auth/).Install deps (peer + runtime):
bun add jose zod server-only lucide-react class-variance-authority clsx tailwind-merge @base-ui/reactRequires
next >= 16,react/react-dom>= 19 and Tailwind v4.Edit
config.ts— cookie prefix,afterLoginPath/loginPath/signupPath,protectedPrefixes,authApiPath, the*_DEFAULTSURLs. Editrouting.tstoo (it's the copy the proxy reads).Copy the
next/templates into place and fix their relative imports: | From | To | |---|---| |next/proxy.ts|<repo root>/proxy.ts| |next/api-oauth-start.ts|app/api/auth/oauth/[provider]/route.ts| |next/api-oauth-callback.ts|app/api/auth/callback/[provider]/route.ts| |next/auth-layout.tsx|app/(auth)/layout.tsx| |next/login-page.tsx|app/(auth)/login/page.tsx| |next/signup-page.tsx|app/(auth)/signup/page.tsx|Styles — in your
globals.css, after@import "tailwindcss";:@import "../packages/auth/styles/auth-tokens.css";Skip this if your app already defines shadcn-style tokens; if you already have your own
ui/primitives, deleteui/primitives/and repoint the imports inui/*.tsxinstead.Gate your protected area — in the layout that wraps logged-in routes:
import { getCurrentUser } from "../../packages/auth/auth"; import { loginPath } from "../../packages/auth/config"; const user = await getCurrentUser(); if (!user) redirect(loginPath);Wire
logoutfrompackages/auth/actionsinto a<form action={logout}>.Env vars (all server-side, no
NEXT_PUBLIC_):APP_ENV=dev|docker|production SESSION_SECRET=<random 32+ char string> # required in production API_URL=<backend origin> # optional; defaults per APP_ENV APP_URL=<this app's public origin> # optional; builds the OAuth redirect_uri GOOGLE_CLIENT_ID= / GOOGLE_CLIENT_SECRET= GITHUB_CLIENT_ID= / GITHUB_CLIENT_SECRET=Register
<APP_URL>/api/auth/callback/{google,github}as the OAuth redirect URI with each provider.Dev with no backend:
APP_ENV=devenables theDEMO_USERlogin inconfig.ts([email protected]/trading123) — change or remove it.
Notes
- OAuth provider endpoints, scopes and the
User-Agentare inlined inoauth.ts. - This is source-only: no build step, no
dist, not published. It's a copy. - The
forgot passwordlink inui/login-form.tsxis a dead/#placeholder.
