add-auth
Skill50 starsChanged 20 days agoApache-2.0View on GitHub
Add NextAuth (Auth.js) authentication to an existing T3 project. One structured question decides the mode - admin (fixed login in env vars) or users (DB-backed email+password with signup, signin, account page, delete account, and optional forgot-password if email is configured). OAuth providers (Google, GitHub) are offered as optional add-ons AFTER the user-credentials baseline, never as a replacement. This skill is an orchestrator - it delegates the actual implementation to `_setup-auth-admin` or `_setup-auth-users` depending on the chosen mode.
- Reads credentials
4 other projects use a version of this.
Adopted by
Most recently taken up by
- flavien-ia/hypervibe-craftword for word, first seen Oct 25, 2026
- JoviDeCroock/prachttheir own version, first seen Oct 11, 2026
- dperezcabrera/pico-skillstheir own version, first seen Jul 29, 2026
- T4LEL/Claude-Arsenaltheir own version, first seen Jul 12, 2026
Other versions4 projects use a version of this.
Word for word · 1
- flavien-ia/hypervibe-craft★ 50100% same
Edited · 0
None found.
Wrote their own version · 3
- JoviDeCroock/pracht★ 106same name
- dperezcabrera/pico-skills★ 4same name
- T4LEL/Claude-Arsenal★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository89 other files it gives its agents.
- accessibilitySkill
- add-2faSkill
- add-agent-dashboardSkill
- add-aiSkill
- add-analyticsSkill
- add-automationSkill
- add-backup-dbSkill
- add-collabSkill
- add-cronSkill
- add-dark-modeSkill
- add-dbSkill
- add-domainSkill
- add-emailSkill
- add-github-authSkill
- add-google-authSkill
- add-i18nSkill
- _add-keyringSkill
- add-mapSkill
- add-notification-centerSkill
- add-push-notificationSkill
- add-pwaSkill
- add-roleSkill
- add-routineSkill
- add-storageSkill
- add-stripeSkill
- add-testSkill
- bootstrapSkill
- _check-depsSkill
- cleanSkill
- _collect-secretSkill
- _convert-to-turborepoSkill
- _create-agentSkill
- _create-cloudflare-workerSkill
- _create-contact-pageSkill
- _create-render-workerSkill
- _create-routineSkill
- _create-workflowSkill
- delete-projectSkill
- _detect-project-rootSkill
- _dns-brevoSkill
- _dns-cloudflareSkill
- _dns-gandiSkill
- _dns-godaddy-manualSkill
- _dns-hostingerSkill
- _dns-infomaniak-manualSkill
- _dns-ionos-manualSkill
- _dns-lwsSkill
- _dns-namecheapSkill
- _dns-ovhSkill
- _dns-porkbunSkill
- _dns-resendSkill
- _dns-squarespace-manualSkill
- eco-auditSkill
- _ensure-aiSkill
- _ensure-vaultSkill
- _generate-secretSkill
- geoSkill
- _get-secretSkill
- gscSkill
- _hash-passwordSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. 0 are common, 5 are distinctive, and 11 are very specific to this project.
0
Common
Most of the 3 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 12
Use plain, non-technical business language.
- Distinctive: line 13
When generating user-facing content for the scaffolded project (UI labels, emails, copy), write it in the user's language too.
- Very specific: line 22
Read the marker in src/server/auth.ts:
- Very specific: line 31
No file OR no marker → existing_modes = []
- Distinctive: line 39
No menu. Skip to Step 1.
- Very specific: line 93
If called from /bootstrap, the mode is already chosen → skip to Step 2.
- Very specific: line 109
If auth_mode = user-credentials: _check-deps db → if db_ok = false, propose /add-db then re-check.
- Very specific: line 124
No script - the risk of corrupting the existing auth.ts is too high.
- Very specific: line 136
Extend
password.ts: add hashPassword() (from the users template). - Very specific: line 139
Patch trpc.ts: - add protectedProcedure (and rateLimitedProcedure if missing).
- Very specific: line 141
Register in
root.ts: import + auth: authRouter,. - Distinctive: line 145
Update CLAUDE.md: - add the users sections in addition to the admin sections already present.
- Very specific: line 146
pnpm tsc --noEmit: - check that it compiles. - Very specific: line 155
Extend
password.ts: - add getAdminPasswordHash() from the admin template. - Very specific: line 166
Update CLAUDE.md: - add the admin section (the conventions of _setup-auth-admin Step 2, its "Admin structure" line included) in addition to …
- Distinctive: line 177
Update CLAUDE.md: - add the reset mention.
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Add Auth - Orchestrator
Communication
- Detect the user's language from the conversation (the user's own messages, anywhere in the session - not just this invocation: a bare slash command like
/bootstrapcarries no language signal by itself). If nothing in the conversation gives a signal, fall back to the OS locale (node -e "console.log(Intl.DateTimeFormat().resolvedOptions().locale)") before defaulting to English. ALWAYS reply in that language for every user-facing message: questions, progress, confirmations, summaries, errors - including any example text quoted in this skill, which is illustrative and must be translated, never sent verbatim. - Use plain, non-technical business language. Never expose internal script names (*.mjs) or jargon; describe actions in human terms.
- When generating user-facing content for the scaffolded project (UI labels, emails, copy), write it in the user's language too.
- Show progress as a short natural-language checklist (in-progress and done states).
Lightweight orchestrator. Detects the current state via the // hypervibe:auth-modes <list> marker at the top of src/server/auth.ts, proposes a contextual menu based on what is already installed, and delegates to the right sub-skill (_setup-auth-admin / _setup-auth-users) for fresh installs. For UPGRADES (adding the second mode when one already exists), Claude drives the contextual editing of auth.ts itself - see the UPGRADE Section.
Step 0 - Detect the current state and contextual menu
Read the marker in src/server/auth.ts:
if [ -f "<WEB_DIR>/src/server/auth.ts" ]; then
grep -E "^// hypervibe:auth-modes" "<WEB_DIR>/src/server/auth.ts" | head -1
fiParse:
- No file OR no marker →
existing_modes = [] // hypervibe:auth-modes admin→["admin"]// hypervibe:auth-modes users→["users"]// hypervibe:auth-modes admin, users→["admin","users"]auth.tspresent WITHOUT marker →["unknown"]
Case [] → fresh install
No menu. Skip to Step 1.
Case ["admin"] → menu
🔐 The admin login is already in place
- Also add a signup system for my users (both coexist)
- Change the admin password
- Start over from scratch (deletes auth.ts/password.ts/route.ts + AUTH_SECRET/ADMIN_* first)
- Something else
| Choice | Action |
| 1 | UPGRADE Section - Case A. |
| 2 | node "${CLAUDE_SKILL_DIR}/../../scripts/admin-password.mjs" rotate --project-dir "<WEB_DIR>" → a new password, written in a file of the user's downloads folder, only its hash pushed (ADMIN_PASSWORD_HASH_PROD). Give the user the file's path (file), never the password; it works once the site is deployed again. |
| 3 | List the files to delete manually, then ask to re-run. |
| 4 | Ask for clarification. |
Case ["users"] → menu
🔐 User signup is already in place
- Also add a separate admin login
- Add a Google sign-in
- Add a GitHub sign-in
- Enable password reset (forgot-password - only if email is configured)
- Start over from scratch
- Something else
| Choice | Action |
| 1 | UPGRADE Section - Case B. |
| 2 | Invoke add-google-auth. |
| 3 | Invoke add-github-auth. |
| 4 | _check-deps email ; if OK, UPGRADE Section - Case C. Otherwise point to /add-email. |
| 5 | List the files to delete (auth.ts, password.ts, auth router, /signin /signup /dashboard /account pages, NextAuth tables in the DB). |
| 6 | Ask for clarification. |
Case ["admin","users"] → menu
🔐 You have BOTH modes (admin + users)
- Change the admin password (same as admin case choice 2)
- Add Google (same as users case choice 2)
- Add GitHub (same as users case choice 3)
- Enable password reset (same as users case choice 4)
- Uninstall a mode - destructive, ask for explicit confirmation and guide manually
- Something else
Case ["unknown"] → pre-existing auth not recognized
⚠️ You already have a
src/server/auth.tsbut I do not recognize its origin (no hypervibe marker). Three options: (1) you tell me what you want to do and I guide you manually; (2) you confirm that I can overwrite and start over; (3) we stop.
Step 1 - Choose the mode (fresh install only)
If called from /bootstrap, the mode is already chosen → skip to Step 2. If standalone with an explicit arg (admin / users), use it. Otherwise AskUserQuestion:
What type of authentication does your project need?
- Just a protected admin interface (only you log in - content management, site admin)
- A system for your users (visitors create an account and sign in)
→ auth_mode = admin-credentials or user-credentials.
Why is email+pwd the baseline when there are users? It is the only 0-config system that works everywhere. OAuth (Google, GitHub) is a convenience added on top, never a replacement.
Step 2 - Prerequisites (fresh install only)
Invoke _detect-project-root → PROJECT_NAME, WEB_DIR, IS_MONOREPO, IS_NEXTJS. Abort if not Next.js.
If auth_mode = user-credentials: _check-deps db → if db_ok = false, propose /add-db then re-check.
Step 3 - Delegate to the sub-skill (fresh install)
auth_mode = admin-credentials→ invoke_setup-auth-adminwithWEB_DIR,IS_MONOREPO,PROJECT_NAME.auth_mode = user-credentials→ invoke_setup-auth-users.
The sub-skill handles the script + UserMenu (users mode) + CLAUDE.md + summary. When it hands control back, you are done - the orchestrator has nothing to add.
UPGRADE Section - Add a mode (Claude drives, no script)
No script - the risk of corrupting the existing auth.ts is too high. Claude reads the existing file, reads the reference templates in ${CLAUDE_SKILL_DIR}/../../templates/auth/, and patches contextually. Check pnpm tsc --noEmit at the end to validate.
Template paths in this section are relative to the PLUGIN ROOT, not to this skill's folder. Always resolve them through
${CLAUDE_SKILL_DIR}/../../templates/…, exactly as written below. Dropping that prefix makes the path resolve insideskills/add-auth/, where notemplates/folder exists, and the read fails with "No such file or directory".
Case A - Add users on top of an existing admin
Reference templates: ${CLAUDE_SKILL_DIR}/../../templates/auth/users/{auth.ts, password.ts, schema-additions.ts, schema-additions-reset-tokens.ts, auth-router*.ts, route.ts}.
Steps (all driven by Claude):
_check-deps db(DB required) ;_check-deps email(optional for reset).- Build the hybrid
auth.ts: marker →// hypervibe:auth-modes admin, users. ImportDrizzleAdapter, schema tables,eq,db. Module augmentationSession.user.id.authorize(credentials, request): the limit on sign-in attempts FIRST, before both paths (theTooManyAttemptsclass and its two lines, as both templates write them: never in the API route, whose 429 freezes the sign-in form), then the admin path (checkemail === ADMIN_USERNAME,getAdminPasswordHash), users path as FALLBACK (db.query.users.findFirst→verifyPassword). KeepisAdmin(). Add jwt/session callbacks. - Extend
password.ts: addhashPassword()(from the users template). KeepgetAdminPasswordHash+verifyPassword. - Patch schema.ts - like
setup-auth-users.mjsdoes in thepatchSchemastep: add the missing imports (text, integer, primaryKey, index, timestamppg-core,sqldrizzle-orm,AdapterAccounttype next-auth/adapters), append the 4 NextAuth tables (+password_reset_tokensif email_ok). pnpm db:push, afternode "${CLAUDE_SKILL_DIR}/../../scripts/neon/schema-drift.mjs"from<WEB_DIR>(read-only):--forceonly on exit0; on exit3stop and show the user what the push would delete.- Patch trpc.ts - add
protectedProcedure(andrateLimitedProcedureif missing). Take inspiration from thesetup-auth-users.mjsaddProtectedProcedurestep. - Create
src/server/api/routers/auth.tsfrom the right template (auth-router.tsorauth-router-with-reset-{provider}.ts). - Register in
root.ts: import +auth: authRouter,. - Create
src/app/api/auth/[...nextauth]/route.tsfrom the template (admin and users are identical). - Create the 4 users pages: signin (with
FORGOT_PASSWORD_LINKsubstituted), signup, dashboard, account (+ forgot/reset if email_ok). - Patch
layout.tsxfor the user-menu (best-effort, like_setup-auth-usersStep 2). - Update CLAUDE.md - add the users sections in addition to the admin sections already present.
pnpm tsc --noEmit- check that it compiles.- Summary: "User signup has been added on top of the admin login. The admin login keeps working and has priority in the authorize callback."
Case B - Add admin on top of an existing users
Reference templates: ${CLAUDE_SKILL_DIR}/../../templates/auth/admin/{auth.ts, password.ts} (for the snippets to integrate).
- Hash the DEV password and push it:
H=$(printf '%s' "Admin1234!" | node "<path>/hash-password.mjs") && [ -n "$H" ] && printf 'ADMIN_USERNAME=admin\nADMIN_PASSWORD_HASH_DEV=%s\n' "$H" | node "<path>/push-env-vars.mjs" --target=all --stdin. - The PROD password, never in the conversation:
node "<path>/admin-password.mjs" rotate --project-dir <app folder>. It generates it, writes it with the identifier and the sign-in page in a file of the user's downloads folder, and pushes onlyADMIN_PASSWORD_HASH_PROD. Its JSON gives the file's path (file), never the password: never read that file. Neverhash-password.mjs --generatehere: it prints the password where you read it. - Extend
password.ts- addgetAdminPasswordHash()from the admin template. KeephashPassword+verifyPassword. - Patch
auth.ts: marker →// hypervibe:auth-modes admin, users. ImportgetAdminPasswordHashfrom~/lib/password. Inauthorize(), after the limit on sign-in attempts (its first lines, kept as they are) and BEFORE the DB lookup, add the admin path:
Addif (process.env.ADMIN_USERNAME && email === process.env.ADMIN_USERNAME) { const hash = getAdminPasswordHash(); if (await verifyPassword(password, hash)) return { id: "admin", email, name: "Admin" }; return null; }export async function isAdmin() { return (await auth())?.user?.id === "admin"; }. 4b. The admin gate:node "${CLAUDE_SKILL_DIR}/../../scripts/admin-gate.mjs" --web-dir <WEB_DIR>. It writessrc/server/require-admin.ts, the check every admin page calls on its first line, and the middleware in front of/admin(src/middleware.ts, orsrc/proxy.tsfrom Next.js 16), never over a middleware the project already has: with"status":"existing"in its last line, merge by hand when that is safe or tell the person, as_setup-auth-adminsays. Every admin page created later starts withawait requireAdmin(): a check in a layout alone lets the page's content leave with its redirect. - Update CLAUDE.md - add the admin section (the conventions of
_setup-auth-adminStep 2, its "Admin structure" line included) in addition to the users sections. pnpm tsc --noEmit- check.- Summary: give the path of the file that holds the PROD credentials (open it, save the password in a password manager, delete the file), never the password; explain the coexistence in authorize.
Case C - Enable password reset on an existing users (email already OK)
- Append
password_reset_tokensto schema.ts from${CLAUDE_SKILL_DIR}/../../templates/auth/users/schema-additions-reset-tokens.ts. pnpm db:push.- Replace
src/server/api/routers/auth.tswith theauth-router-with-reset-{resend,brevo}.tstemplate (depending on the detected provider). - Create
/forgot-password/page.tsxand/reset-password/page.tsxfrom the templates. - Patch signin.tsx: replace
<span></span>(placeholder forFORGOT_PASSWORD_LINK) with the<Link href="/forgot-password" ...>Forgot password?</Link>. - Update CLAUDE.md - add the reset mention.
pnpm tsc --noEmit+ summary.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

