@warlock.js/auth 5.34.1 → 5.34.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to `@warlock.js/auth` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.34.3 - 2026-10-20
8
+
9
+ ### Changed
10
+
11
+ - Condensed the package agent skill description to at most 450 characters, with API names and package routing guidance.
12
+
13
+ ## 5.34.2 - 2026-10-19
14
+
15
+ ### Fixed
16
+
17
+ - Merge package orientation into the grouped skill index and remove the duplicate overview topic; preserve that orientation in generated LLM projections.
18
+
7
19
  ## 5.32.0 - 2026-10-18
8
20
 
9
21
  ### Changed
package/llms-full.txt CHANGED
@@ -4,7 +4,60 @@
4
4
 
5
5
  > Generated artifact. Concatenates every SKILL.md and reference file under `@warlock.js/auth/skills/`. Re-run `node scripts/generate-llms.mjs` after any change.
6
6
 
7
- ## auth-basics `@warlock.js/auth/auth-basics/SKILL.md`
7
+ ## Package orientation
8
+
9
+ ---
10
+ description: 'JWT authentication, refresh rotation, sessions, OTP and passkeys for Warlock apps. Exports `Auth`, `authService`, `authMiddleware`, `currentUser` and `GoogleProvider`. Use for "log in", "protect a route", "reset a password", "sign in with Google" or multiple user types. Not this package → @warlock.js/access for roles and permission policies; @warlock.js/core for general middleware; @warlock.js/seal for input rules.'
11
+ ---
12
+
13
+ # @warlock.js/auth
14
+
15
+ A user model extends the `Auth` base model and declares a `userType`. `authService.login(Model, credentials)` verifies the password and issues persisted access + refresh tokens; `authMiddleware("user")` gates routes per type. Refresh tokens rotate within a token family, with replay detection. Server-only, and requires `@warlock.js/core`.
16
+
17
+ ## The 80% path
18
+
19
+ 1. Start with `auth-basics.md` for the shape of config and models.
20
+ 2. Extend `Auth` for your user model: `customize-user-type.md`, `register-user.md`.
21
+ 3. Log in / out: `handle-login-and-logout.md`; token lifecycle: `manage-tokens.md`.
22
+ 4. Guard routes: `protect-routes.md`.
23
+ 5. Harden: `throttle-login-attempts.md`, `verify-email-and-reset-password.md`.
24
+ 6. Social sign-in: `login-with-providers.md`; CLI (JWT secret, token cleanup): `run-auth-commands.md`.
25
+
26
+ ## Conventions and pitfalls
27
+
28
+ - Tokens are persisted rows, not stateless JWTs alone; revoking a family invalidates its refresh and access rows.
29
+ - `authMiddleware()` with no argument resolves the configured default user type. Be explicit when an app has several.
30
+ - Not for session-cookie auth; this is JWT-based.
31
+ - Do not value-import this package from client code; `@warlock.js/web` builds refuse it (type-only imports are fine).
32
+ - Generate the JWT secret with the bundled command rather than inventing one.
33
+ - Custom token storage is a supported extension point: `customize-token-storage.md`.
34
+
35
+ ## When to reach for it
36
+
37
+ - You're building a Warlock app that needs login, protected routes, and token-based sessions.
38
+ - You need **multiple user types** (admins + regular users, or client/vendor/staff personas) gated separately on the same auth system.
39
+ - You want refresh-token **rotation + replay detection** out of the box rather than hand-rolling token security.
40
+
41
+ Skip if you're not on `@warlock.js/core` (the package depends on it), or if you need session-cookie auth rather than JWTs.
42
+
43
+ ## The mental model in one paragraph
44
+
45
+ Your user model extends the `Auth` base model and declares its `userType`. A login flows through `authService.login(Model, credentials, deviceInfo?)`: it verifies the password, issues a persisted access + refresh pair, and fires events. `authMiddleware("user")` is a typed hard gate; `authMiddleware()` resolves the configured default type; the object form selects header/cookie credentials, `optional`, and a page-local redirect. Refresh rotation uses a durable token family: family revocation invalidates its refresh and associated access rows. CLI commands generate the JWT secret and clean up expired tokens.
46
+
47
+ ## What this package deliberately doesn't do
48
+
49
+ - **Session-cookie auth.** It's JWT/token-based. If you need server-side sessions, this isn't it.
50
+ - **OAuth / social login / SSO.** No provider adapters here — wire those at the controller layer and create the user through this package's models.
51
+ - **Authorization / roles / permissions (RBAC).** It authenticates (who you are) and gates by user _type_, not fine-grained permissions. Build RBAC on top.
52
+ - **Standalone use.** It depends on `@warlock.js/core` for routing, models (Cascade), and config.
53
+
54
+ ## See also
55
+
56
+ - The `warlock-conventions` topic of the `warlock-js-core` skill — the framework auth runs inside (routing, middleware, config).
57
+ - The `cascade-basics` topic of the `warlock-js-cascade` skill — the ORM behind the `Auth`, `AccessToken`, and `RefreshToken` models.
58
+
59
+
60
+ ## auth-basics `@warlock.js/auth/skills/auth-basics/SKILL.md`
8
61
 
9
62
  ---
10
63
  name: auth-basics
@@ -125,7 +178,7 @@ Two values that look right and are not:
125
178
  - Don't run `auth.cleanup` from app boot. Schedule it (cron, scheduler) as a periodic task — see the `scheduler-basics` topic of the `warlock-js-scheduler` skill.
126
179
 
127
180
 
128
- ## customize-token-storage `@warlock.js/auth/customize-token-storage/SKILL.md`
181
+ ## customize-token-storage `@warlock.js/auth/skills/customize-token-storage/SKILL.md`
129
182
 
130
183
  ---
131
184
  name: customize-token-storage
@@ -294,7 +347,7 @@ If you rename a column, override the statics **and these getters** so they map t
294
347
  - The `define-model` topic of the `warlock-js-cascade` skill — extending models and schemas.
295
348
 
296
349
 
297
- ## customize-user-type `@warlock.js/auth/customize-user-type/SKILL.md`
350
+ ## customize-user-type `@warlock.js/auth/skills/customize-user-type/SKILL.md`
298
351
 
299
352
  ---
300
353
  name: customize-user-type
@@ -468,7 +521,7 @@ abstract class Auth<TSchema> extends Model<TSchema> implements Authenticable {
468
521
  - The `define-model` topic of the `warlock-js-cascade` skill — `@RegisterModel`, models in general
469
522
 
470
523
 
471
- ## handle-login-and-logout `@warlock.js/auth/handle-login-and-logout/SKILL.md`
524
+ ## handle-login-and-logout `@warlock.js/auth/skills/handle-login-and-logout/SKILL.md`
472
525
 
473
526
  ---
474
527
  name: handle-login-and-logout
@@ -670,7 +723,7 @@ Full event list: `login.attempt`, `login.success`, `login.failed`, `logout`, `lo
670
723
  For cookie sessions read by `@warlock.js/web` pages, log in with `authService.loginWithSessionCookies(request, response, Model, credentials)`. It requires a same-origin `Origin`/`Referer` even without cookies (login CSRF) and sets the access and refresh cookies (`auth.cookie.name`, `auth.cookie.refreshName`, `Path=/`). To share a session across subdomains, configure `auth.cookie.cookieDomain(request)` to return (for example) `".example.com"`; return `undefined` for host-only cookies. With `cookieDomain` configured, always pass the request to cookie helpers so they select the same Domain: `authService.setSessionCookies(response, tokens, request)`, `authService.clearSessionCookies(response, request)`, and `authService.clearAuthCookie(response, options, request)`. Omitting it throws `CookieDomainRequestRequiredError`. Domain clears also remove the legacy host-only names. Resolve pages with `pageSession({ project })` (`web.session`); header beats cookie; `auth.session.maxAge` defaults to `"30d"`. A page session with multiple `userTypes` cannot renew its cookie: the resolver only supplies a renewal user type when exactly one type is allowed, so it reads the session but skips automatic renewal. Multi-instance: share the JWT secret and the cache store, keep clocks in sync.
671
724
 
672
725
 
673
- ## login-with-providers `@warlock.js/auth/login-with-providers/SKILL.md`
726
+ ## login-with-providers `@warlock.js/auth/skills/login-with-providers/SKILL.md`
674
727
 
675
728
  ---
676
729
  name: login-with-providers
@@ -982,7 +1035,7 @@ router.post(
982
1035
  - The `define-channel` topic of the `warlock-js-notifications` skill: an SMS/WhatsApp channel
983
1036
 
984
1037
 
985
- ## manage-tokens `@warlock.js/auth/manage-tokens/SKILL.md`
1038
+ ## manage-tokens `@warlock.js/auth/skills/manage-tokens/SKILL.md`
986
1039
 
987
1040
  ---
988
1041
  name: manage-tokens
@@ -1182,94 +1235,7 @@ The package signs access and refresh tokens with independent secrets — `config
1182
1235
  - The `scheduler-basics` topic of the `warlock-js-scheduler` skill — scheduling cleanup
1183
1236
 
1184
1237
 
1185
- ## overview `@warlock.js/auth/overview/SKILL.md`
1186
-
1187
- ---
1188
- name: overview
1189
- description: "@warlock.js/auth overview for orientation and choosing the focused skill for the task."
1190
- ---
1191
-
1192
- # `@warlock.js/auth` — overview
1193
-
1194
- JWT authentication for Warlock apps. You get a base `Auth` model your user types extend, an `authMiddleware` route gate, an `authService` that runs login/logout/refresh (with refresh-token rotation and replay detection), persisted access + refresh tokens, multi-user-type support, lifecycle events, and two bundled CLI commands.
1195
-
1196
- Coupled to `@warlock.js/core` — you're inside a Warlock project before this package makes sense.
1197
-
1198
- Server-only: `package.json` declares `"warlock": { "environment": "server" }`. `@warlock.js/web`'s build refuses app client code that value-imports this package; type-only imports are allowed, and server loaders/controllers/modules are unaffected.
1199
-
1200
- ## When to reach for it
1201
-
1202
- - You're building a Warlock app that needs login, protected routes, and token-based sessions.
1203
- - You need **multiple user types** (admins + regular users, or client/vendor/staff personas) gated separately on the same auth system.
1204
- - You want refresh-token **rotation + replay detection** out of the box rather than hand-rolling token security.
1205
-
1206
- Skip if you're not on `@warlock.js/core` (the package depends on it), or if you need session-cookie auth rather than JWTs.
1207
-
1208
- ## The mental model in one paragraph
1209
-
1210
- Your user model extends the `Auth` base model and declares its `userType`. A login flows through `authService.login(Model, credentials, deviceInfo?)`: it verifies the password, issues a persisted access + refresh pair, and fires events. `authMiddleware("user")` is a typed hard gate; `authMiddleware()` resolves the configured default type; the object form selects header/cookie credentials, `optional`, and a page-local redirect. Refresh rotation uses a durable token family: family revocation invalidates its refresh and associated access rows. CLI commands generate the JWT secret and clean up expired tokens.
1211
-
1212
- ## Skills index
1213
-
1214
- Nine task skills. Most apps need `auth-basics` + `protect-routes` + `handle-login-and-logout`.
1215
-
1216
- ### Foundations
1217
-
1218
- #### `auth-basics`
1219
-
1220
- Start here. The `Auth` base model, `authMiddleware` gate, `authService` (login/logout/refresh), AccessToken + RefreshToken persistence, multi-user-type support.
1221
-
1222
- ### The flows
1223
-
1224
- #### `handle-login-and-logout`
1225
-
1226
- `authService.login(Model, credentials, deviceInfo?)` — verify password, issue the token pair, fire events. `authService.logout(user, accessToken?, refreshToken?)` — revoke tokens. For your `POST /login` and `POST /logout` controllers.
1227
-
1228
- #### `register-user`
1229
-
1230
- Sign up a new user and issue the first token pair — `User.create({ ...password: await hashPassword(plain) })` then `authService.createTokenPair(user)`. For `POST /register`.
1231
-
1232
- #### `protect-routes`
1233
-
1234
- `authMiddleware` object and legacy overloads: typed/default hard gates, optional resolution, credential source, and page-local redirects. Sets `request.locals.user` + `request.decodedAccessToken` when a user resolves.
1235
-
1236
- ### Going deeper
1237
-
1238
- #### `manage-tokens`
1239
-
1240
- The token lifecycle — `generateAccessToken`, `createRefreshToken`, `createTokenPair`, `refreshTokens` (rotation + replay detection), `revokeAllTokens`, `revokeTokenFamily`, `cleanupExpiredTokens`, `getActiveSessions`. For custom login/registration, token revocation, "logout everywhere", and scheduled cleanup.
1241
-
1242
- #### `customize-user-type`
1243
-
1244
- Support multiple user types in one system — each `Auth` subclass overrides `userType`, `config.auth.userType.<slug>` maps the slug to a model class, `authMiddleware("admin")` / `authMiddleware(["admin", "staff"])` gates per type.
1245
-
1246
- #### `customize-token-storage`
1247
-
1248
- Override the persisted `AccessToken` / `RefreshToken` models to add columns (multi-tenant `organization_id`), rename, or change storage — extend the model + schema and register it under `config.auth.accessToken.model` / `config.auth.refreshToken.model`.
1249
-
1250
- #### `throttle-login-attempts`
1251
-
1252
- Brute-force / credential-stuffing protection — `loginThrottleMiddleware()` counts only failed logins, resets on success, locks per-account + per-IP after a threshold, and rejects pre-controller with 429. Cache-backed, fails open on a cache outage.
1253
-
1254
- #### `run-auth-commands`
1255
-
1256
- Two CLI commands — `warlock jwt.generate` (strong JWT secret → `.env`) and `warlock auth.cleanup` (remove expired refresh tokens). Register via `registerJWTSecretGeneratorCommand()` and `registerAuthCleanupCommand()`.
1257
-
1258
- ## What this package deliberately doesn't do
1259
-
1260
- - **Session-cookie auth.** It's JWT/token-based. If you need server-side sessions, this isn't it.
1261
- - **OAuth / social login / SSO.** No provider adapters here — wire those at the controller layer and create the user through this package's models.
1262
- - **Authorization / roles / permissions (RBAC).** It authenticates (who you are) and gates by user _type_, not fine-grained permissions. Build RBAC on top.
1263
- - **Standalone use.** It depends on `@warlock.js/core` for routing, models (Cascade), and config.
1264
-
1265
- ## See also
1266
-
1267
- - The `warlock-conventions` topic of the `warlock-js-core` skill — the framework auth runs inside (routing, middleware, config).
1268
- - The `cascade-basics` topic of the `warlock-js-cascade` skill — the ORM behind the `Auth`, `AccessToken`, and `RefreshToken` models.
1269
- - `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview` topic becomes `.claude/skills/warlock-js-auth/overview.md`.
1270
-
1271
-
1272
- ## protect-routes `@warlock.js/auth/protect-routes/SKILL.md`
1238
+ ## protect-routes `@warlock.js/auth/skills/protect-routes/SKILL.md`
1273
1239
 
1274
1240
  ---
1275
1241
  name: protect-routes
@@ -1451,7 +1417,7 @@ The middleware uses the framework's `response.unauthorized({...})` shape. To ove
1451
1417
 
1452
1418
  That last one is the difference between a role check and an authorization model: without it, an account-creation endpoint gated on `authMiddleware("admin")` is a privilege-escalation path.
1453
1419
 
1454
- Install `@warlock.js/access` (the `overview` topic of the `warlock-js-access` skill) for that. It layers RBAC plus per-permission ABAC policies over the same authenticated user:
1420
+ Install `@warlock.js/access` (the `warlock-js-access` skill index) for that. It layers RBAC plus per-permission ABAC policies over the same authenticated user:
1455
1421
 
1456
1422
  ```ts
1457
1423
  import { router, type RequestHandler } from "@warlock.js/core";
@@ -1582,10 +1548,10 @@ This is an Origin check, not a double-submit CSRF token — cheaper, and closes
1582
1548
  - The `customize-user-type` topic — config and multi-user-type semantics
1583
1549
  - The `handle-login-and-logout` topic — where the access token gets issued in the first place
1584
1550
  - The `throttle-login-attempts` topic — brute-force throttle to stack in front of the login route
1585
- - The `overview` topic of the `warlock-js-access` skill — permissions, roles, and who-may-act-on-whom policies, when user-type gating isn't enough
1551
+ - The `warlock-js-access` skill index — permissions, roles, and who-may-act-on-whom policies, when user-type gating isn't enough
1586
1552
 
1587
1553
 
1588
- ## register-user `@warlock.js/auth/register-user/SKILL.md`
1554
+ ## register-user `@warlock.js/auth/skills/register-user/SKILL.md`
1589
1555
 
1590
1556
  ---
1591
1557
  name: register-user
@@ -1736,7 +1702,7 @@ Cleaner alternative: emit your own `user.registered` event from the controller a
1736
1702
  - The `define-model` topic of the `warlock-js-cascade` skill — `toJsonColumns` / `resource` for public output
1737
1703
 
1738
1704
 
1739
- ## run-auth-commands `@warlock.js/auth/run-auth-commands/SKILL.md`
1705
+ ## run-auth-commands `@warlock.js/auth/skills/run-auth-commands/SKILL.md`
1740
1706
 
1741
1707
  ---
1742
1708
  name: run-auth-commands
@@ -1899,7 +1865,7 @@ Register it the same way as the bundled commands — call the factory inside `de
1899
1865
  - The `scheduler-basics` topic of the `warlock-js-scheduler` skill — in-process scheduling
1900
1866
 
1901
1867
 
1902
- ## throttle-login-attempts `@warlock.js/auth/throttle-login-attempts/SKILL.md`
1868
+ ## throttle-login-attempts `@warlock.js/auth/skills/throttle-login-attempts/SKILL.md`
1903
1869
 
1904
1870
  ---
1905
1871
  name: throttle-login-attempts
@@ -2051,7 +2017,7 @@ They compose. For a hard ceiling on request volume _and_ failure-aware account l
2051
2017
  - The `use-middleware` topic of the `warlock-js-core` skill — `middleware.rateLimit` and the built-in middleware suite.
2052
2018
 
2053
2019
 
2054
- ## verify-email-and-reset-password `@warlock.js/auth/verify-email-and-reset-password/SKILL.md`
2020
+ ## verify-email-and-reset-password `@warlock.js/auth/skills/verify-email-and-reset-password/SKILL.md`
2055
2021
 
2056
2022
  ---
2057
2023
  name: verify-email-and-reset-password
package/llms.txt CHANGED
@@ -6,15 +6,15 @@
6
6
 
7
7
  ## Skills
8
8
 
9
- - [auth-basics](@warlock.js/auth/auth-basics/SKILL.md): Start here for @warlock.js/auth configuration, user models, credentials, and application session flows.
10
- - [customize-token-storage](@warlock.js/auth/customize-token-storage/SKILL.md): Override the persisted AccessToken / RefreshToken models to add columns (multi-tenant `organization_id`, device metadata), rename, or change storage — without forking the package. Extend the model + `schema.extend(...)`, register it under `config.auth.accessToken.model` / `config.auth.refreshToken.model`, override `issue()` to populate the new column, and add a migration. Triggers: `accessToken.model`, `refreshToken.model`, `AccessToken.issue`, `RefreshToken.issue`, `accessTokenSchema`, `refreshTokenSchema`, "add a column to the token table", "multi-tenant tokens", "organization_id on access token", "override the token model", "custom token storage"; typical import `import { AccessToken, accessTokenSchema } from "@warlock.js/auth"`. Skip: multiple user TYPES (not token storage) — the `customize-user-type` topic; the token lifecycle API — the `manage-tokens` topic; the config blocks themselves — the `auth-basics` topic.
11
- - [customize-user-type](@warlock.js/auth/customize-user-type/SKILL.md): Support multiple user types (user / admin / client / staff) in one auth system — each Auth subclass overrides userType, config.auth.userType.<slug> maps slug to model class, authMiddleware('admin') gates per type. Triggers: `Auth`, `userType`, `config.auth.userType`, `Authenticable`, `@RegisterModel`, `confirmPassword`; "add admins and users", "multiple user types", "separate client and vendor personas", "per-type login"; typical import `import { Auth } from "@warlock.js/auth"`. Skip: `authMiddleware` semantics — the `protect-routes` topic; login flow — the `handle-login-and-logout` topic; RBAC libs `casl`, `accesscontrol`, `rbac`.
12
- - [handle-login-and-logout](@warlock.js/auth/handle-login-and-logout/SKILL.md): Run the full login flow via authService.login(Model, credentials, deviceInfo?) — verify password, create access + refresh token pair, fire events. Logout via authService.logout(user, accessToken?, refreshToken?) revokes tokens. Triggers: `authService.login`, `authService.logout`, `authService.attemptLogin`, `authService.refreshTokens`, `authService.revokeAllTokens`, `authEvents`; "build a login endpoint", "POST /login controller", "logout from all devices", "verify credentials and issue tokens"; typical import `import { authService, authEvents } from "@warlock.js/auth"`. Skip: token internals — the `manage-tokens` topic; sign-up — the `register-user` topic; competing libs `passport-local`, `next-auth` credentials.
13
- - [login-with-providers](@warlock.js/auth/login-with-providers/SKILL.md): Log in without a password — Google (OIDC code + PKCE + state + nonce, id_token verified with `jose`), GitHub, Discord, LinkedIn, Apple (`form_post` callback), Facebook and X, passkeys (WebAuthn via `@simplewebauthn/server`) and phone one-time codes (delivered through a `@warlock.js/notifications` channel). Every method ends in `authService.completeLogin(user)`, the same tokens, rows and events as password login. `startProviderLogin`, `completeProviderLogin`, `generatePasskeyRegistrationOptions`, `verifyPasskeyRegistration`, `generatePasskeyAuthenticationOptions`, `verifyPasskeyAuthentication`, `requestOtp`, `verifyOtp`, `otpRequestThrottleMiddleware`, `otpVerifyThrottleMiddleware`, `AuthProvider`. Triggers: "login with Google", "sign in with Google", "login with GitHub", "Sign in with Apple", "login with Discord", "login with LinkedIn", "login with Facebook", "login with X", `auth.providers.github`, "OAuth", "OIDC", "passkeys", "WebAuthn", "passwordless", "SMS code login", "WhatsApp OTP", "phone login", `warlock add auth-google`, `warlock add auth-passkeys`, `AuthProviderSdkMissingError`, `InvalidProviderCallbackError`, `ProviderEmailNotVerifiedError`, `InvalidPasskeyError`, `EC009`, `EC010`, `EC011`, `auth.providers`, `auth.passkeys`, `auth.otp`; typical import `import { completeProviderLogin, verifyOtp } from "@warlock.js/auth"`. Skip: password login — the `handle-login-and-logout` topic; email tokens — the `verify-email-and-reset-password` topic; defining an SMS channel — the `define-channel` topic of the `warlock-js-notifications` skill.
14
- - [manage-tokens](@warlock.js/auth/manage-tokens/SKILL.md): Token lifecycle — generateAccessToken, createRefreshToken, createTokenPair, refreshTokens (with rotation + replay detection), revokeAllTokens, revokeTokenFamily, cleanupExpiredTokens, getActiveSessions. Triggers: `createTokenPair`, `refreshTokens`, `revokeTokenFamily`, `cleanupExpiredTokens`, `getActiveSessions`, `jwt.generate`, `jwt.verify`, `AccessToken`, `RefreshToken`; "rotate refresh tokens", "detect token replay", "logout from all devices", "list active sessions", "clean up expired tokens"; typical import `import { authService, jwt } from "@warlock.js/auth"`. Skip: login flow — the `handle-login-and-logout` topic; CLI cleanup — the `run-auth-commands` topic; competing libs `jsonwebtoken`, `jose`, `fast-jwt`.
15
- - [overview](@warlock.js/auth/overview/SKILL.md): @warlock.js/auth overview for orientation and choosing the focused skill for the task.
16
- - [protect-routes](@warlock.js/auth/protect-routes/SKILL.md): Gate HTTP routes via authMiddleware(allowedUserType) — the argument is required and a valid token is always required: [] allows any authenticated user, a user-type restricts to those types. Sets request.locals.user + request.decodedAccessToken on success, 401 on failure. Triggers: `authMiddleware`, `request.locals.user`, `request.decodedAccessToken`, `AuthErrorCodes`, `MissingAccessToken`, `InvalidAccessToken`; "how do I protect a route", "restrict route by user type", "require any logged-in user"; typical import `import { authMiddleware } from "@warlock.js/auth"`. Skip: multi-user-type config — the `customize-user-type` topic; issuing the token — the `handle-login-and-logout` topic; competing libs `passport`, `express-jwt`, `next-auth` middleware.
17
- - [register-user](@warlock.js/auth/register-user/SKILL.md): Sign up a new user and issue the initial token pair — User.create({...password: await hashPassword(plain)}) then authService.createTokenPair(user). Triggers: `User.create`, `hashPassword`, `verifyPassword`, `authService.createTokenPair`, `toJsonColumns`, `strongPassword`, `authEvents`; "build a register endpoint", "POST /register controller", "sign up a new user", "hash password on signup", "email verification flow"; typical import `import { authService } from "@warlock.js/auth"; import { hashPassword } from "@warlock.js/core"`. Skip: login — the `handle-login-and-logout` topic; token internals — the `manage-tokens` topic; competing libs `bcrypt`, `bcryptjs`, `argon2`.
18
- - [run-auth-commands](@warlock.js/auth/run-auth-commands/SKILL.md): Three bundled CLI commands — warlock jwt.generate (creates strong JWT secret + writes to .env), warlock auth.cleanup (removes expired refresh tokens), and warlock auth.purge-never-expiring (finds and revokes token rows that can never expire). Register via registerJWTSecretGeneratorCommand(), registerAuthCleanupCommand() and registerAuthPurgeNeverExpiringCommand(). Triggers: `registerJWTSecretGeneratorCommand`, `registerAuthCleanupCommand`, `registerAuthPurgeNeverExpiringCommand`, `warlock jwt.generate`, `warlock auth.cleanup`, `warlock auth.purge-never-expiring`, `cleanupExpiredTokens`, `purgeNeverExpiringTokens`, `command`; "token never expires", "no exp claim", "Invalid Date expires_at"; "generate JWT secret", "bootstrap .env JWT_SECRET", "cron job for expired tokens", "schedule auth cleanup"; typical import `import { registerJWTSecretGeneratorCommand, registerAuthCleanupCommand, registerAuthPurgeNeverExpiringCommand } from "@warlock.js/auth"`. Skip: programmatic cleanup — the `manage-tokens` topic; in-process scheduling — the `scheduler-basics` topic of the `warlock-js-scheduler` skill; competing tools `dotenv-cli`, `node-cron`.
19
- - [throttle-login-attempts](@warlock.js/auth/throttle-login-attempts/SKILL.md): Brute-force / credential-stuffing protection via `loginThrottleMiddleware` — a failure-aware route gate that counts only failed logins (resets on success), locks per-account and per-source after a threshold, and rejects pre-controller with 429 so the DB lookup and bcrypt verify are skipped. Cache-backed (shared across replicas), fixed-window, fails open on a cache outage. Triggers: `loginThrottleMiddleware`, `AuthErrorCodes.TooManyAttempts`, `EC004`, "rate limit login", "brute force protection", "lock account after failed logins", "throttle login attempts", "too many login attempts 429"; typical import `import { loginThrottleMiddleware } from "@warlock.js/auth"`. Skip: generic per-route request rate limiting that counts every request (use core `middleware.rateLimit`); gating a route by auth — the `protect-routes` topic; issuing tokens — the `handle-login-and-logout` topic.
20
- - [verify-email-and-reset-password](@warlock.js/auth/verify-email-and-reset-password/SKILL.md): Email verification and password reset with hashed, single-use, expiring, purpose-bound tokens delivered through `@warlock.js/notifications` — `sendEmailVerification(user)`, `verifyEmail(token)`, `requestPasswordReset(Model, email)`, `resetPassword(token, newPassword)`, the `requireVerifiedEmail()` guard, and the `tokenIssueThrottleMiddleware` / `tokenConsumeThrottleMiddleware` presets. Reset revokes every access token, refresh token and cookie session; a reset request answers the same for unknown emails. Triggers: `sendEmailVerification`, `verifyEmail`, `requestPasswordReset`, `resetPassword`, `requireVerifiedEmail`, `isEmailVerified`, `OneTimeToken`, `InvalidOneTimeTokenError`, `EmailNotVerifiedError`, `NotificationsUnavailableError`, `EC007`, `EC008`, `auth.verification`, `auth.passwordReset`; "verify email", "confirm email address", "forgot password", "reset password link", "block unverified users", "resend verification email"; typical import `import { requestPasswordReset, resetPassword } from "@warlock.js/auth"`. Skip: sign-up itself — the `register-user` topic; login throttling — the `throttle-login-attempts` topic; defining notifications — the `define-notification` topic of the `warlock-js-notifications` skill.
9
+ - [Package orientation](@warlock.js/auth/skills/index.md): JWT authentication, refresh rotation, sessions, OTP and passkeys for Warlock apps. Exports `Auth`, `authService`, `authMiddleware`, `currentUser` and `GoogleProvider`. Use for "log in", "protect a route", "reset a password", "sign in with Google" or multiple user types. Not this package → @warlock.js/access for roles and permission policies; @warlock.js/core for general middleware; @warlock.js/seal for input rules.
10
+ - [auth-basics](@warlock.js/auth/skills/auth-basics/SKILL.md): Start here for @warlock.js/auth configuration, user models, credentials, and application session flows.
11
+ - [customize-token-storage](@warlock.js/auth/skills/customize-token-storage/SKILL.md): Override the persisted AccessToken / RefreshToken models to add columns (multi-tenant `organization_id`, device metadata), rename, or change storage — without forking the package. Extend the model + `schema.extend(...)`, register it under `config.auth.accessToken.model` / `config.auth.refreshToken.model`, override `issue()` to populate the new column, and add a migration. Triggers: `accessToken.model`, `refreshToken.model`, `AccessToken.issue`, `RefreshToken.issue`, `accessTokenSchema`, `refreshTokenSchema`, "add a column to the token table", "multi-tenant tokens", "organization_id on access token", "override the token model", "custom token storage"; typical import `import { AccessToken, accessTokenSchema } from "@warlock.js/auth"`. Skip: multiple user TYPES (not token storage) — the `customize-user-type` topic; the token lifecycle API — the `manage-tokens` topic; the config blocks themselves — the `auth-basics` topic.
12
+ - [customize-user-type](@warlock.js/auth/skills/customize-user-type/SKILL.md): Support multiple user types (user / admin / client / staff) in one auth system — each Auth subclass overrides userType, config.auth.userType.<slug> maps slug to model class, authMiddleware('admin') gates per type. Triggers: `Auth`, `userType`, `config.auth.userType`, `Authenticable`, `@RegisterModel`, `confirmPassword`; "add admins and users", "multiple user types", "separate client and vendor personas", "per-type login"; typical import `import { Auth } from "@warlock.js/auth"`. Skip: `authMiddleware` semantics — the `protect-routes` topic; login flow — the `handle-login-and-logout` topic; RBAC libs `casl`, `accesscontrol`, `rbac`.
13
+ - [handle-login-and-logout](@warlock.js/auth/skills/handle-login-and-logout/SKILL.md): Run the full login flow via authService.login(Model, credentials, deviceInfo?) — verify password, create access + refresh token pair, fire events. Logout via authService.logout(user, accessToken?, refreshToken?) revokes tokens. Triggers: `authService.login`, `authService.logout`, `authService.attemptLogin`, `authService.refreshTokens`, `authService.revokeAllTokens`, `authEvents`; "build a login endpoint", "POST /login controller", "logout from all devices", "verify credentials and issue tokens"; typical import `import { authService, authEvents } from "@warlock.js/auth"`. Skip: token internals — the `manage-tokens` topic; sign-up — the `register-user` topic; competing libs `passport-local`, `next-auth` credentials.
14
+ - [login-with-providers](@warlock.js/auth/skills/login-with-providers/SKILL.md): Log in without a password — Google (OIDC code + PKCE + state + nonce, id_token verified with `jose`), GitHub, Discord, LinkedIn, Apple (`form_post` callback), Facebook and X, passkeys (WebAuthn via `@simplewebauthn/server`) and phone one-time codes (delivered through a `@warlock.js/notifications` channel). Every method ends in `authService.completeLogin(user)`, the same tokens, rows and events as password login. `startProviderLogin`, `completeProviderLogin`, `generatePasskeyRegistrationOptions`, `verifyPasskeyRegistration`, `generatePasskeyAuthenticationOptions`, `verifyPasskeyAuthentication`, `requestOtp`, `verifyOtp`, `otpRequestThrottleMiddleware`, `otpVerifyThrottleMiddleware`, `AuthProvider`. Triggers: "login with Google", "sign in with Google", "login with GitHub", "Sign in with Apple", "login with Discord", "login with LinkedIn", "login with Facebook", "login with X", `auth.providers.github`, "OAuth", "OIDC", "passkeys", "WebAuthn", "passwordless", "SMS code login", "WhatsApp OTP", "phone login", `warlock add auth-google`, `warlock add auth-passkeys`, `AuthProviderSdkMissingError`, `InvalidProviderCallbackError`, `ProviderEmailNotVerifiedError`, `InvalidPasskeyError`, `EC009`, `EC010`, `EC011`, `auth.providers`, `auth.passkeys`, `auth.otp`; typical import `import { completeProviderLogin, verifyOtp } from "@warlock.js/auth"`. Skip: password login — the `handle-login-and-logout` topic; email tokens — the `verify-email-and-reset-password` topic; defining an SMS channel — the `define-channel` topic of the `warlock-js-notifications` skill.
15
+ - [manage-tokens](@warlock.js/auth/skills/manage-tokens/SKILL.md): Token lifecycle — generateAccessToken, createRefreshToken, createTokenPair, refreshTokens (with rotation + replay detection), revokeAllTokens, revokeTokenFamily, cleanupExpiredTokens, getActiveSessions. Triggers: `createTokenPair`, `refreshTokens`, `revokeTokenFamily`, `cleanupExpiredTokens`, `getActiveSessions`, `jwt.generate`, `jwt.verify`, `AccessToken`, `RefreshToken`; "rotate refresh tokens", "detect token replay", "logout from all devices", "list active sessions", "clean up expired tokens"; typical import `import { authService, jwt } from "@warlock.js/auth"`. Skip: login flow — the `handle-login-and-logout` topic; CLI cleanup — the `run-auth-commands` topic; competing libs `jsonwebtoken`, `jose`, `fast-jwt`.
16
+ - [protect-routes](@warlock.js/auth/skills/protect-routes/SKILL.md): Gate HTTP routes via authMiddleware(allowedUserType) — the argument is required and a valid token is always required: [] allows any authenticated user, a user-type restricts to those types. Sets request.locals.user + request.decodedAccessToken on success, 401 on failure. Triggers: `authMiddleware`, `request.locals.user`, `request.decodedAccessToken`, `AuthErrorCodes`, `MissingAccessToken`, `InvalidAccessToken`; "how do I protect a route", "restrict route by user type", "require any logged-in user"; typical import `import { authMiddleware } from "@warlock.js/auth"`. Skip: multi-user-type config — the `customize-user-type` topic; issuing the token — the `handle-login-and-logout` topic; competing libs `passport`, `express-jwt`, `next-auth` middleware.
17
+ - [register-user](@warlock.js/auth/skills/register-user/SKILL.md): Sign up a new user and issue the initial token pair — User.create({...password: await hashPassword(plain)}) then authService.createTokenPair(user). Triggers: `User.create`, `hashPassword`, `verifyPassword`, `authService.createTokenPair`, `toJsonColumns`, `strongPassword`, `authEvents`; "build a register endpoint", "POST /register controller", "sign up a new user", "hash password on signup", "email verification flow"; typical import `import { authService } from "@warlock.js/auth"; import { hashPassword } from "@warlock.js/core"`. Skip: login — the `handle-login-and-logout` topic; token internals — the `manage-tokens` topic; competing libs `bcrypt`, `bcryptjs`, `argon2`.
18
+ - [run-auth-commands](@warlock.js/auth/skills/run-auth-commands/SKILL.md): Three bundled CLI commands — warlock jwt.generate (creates strong JWT secret + writes to .env), warlock auth.cleanup (removes expired refresh tokens), and warlock auth.purge-never-expiring (finds and revokes token rows that can never expire). Register via registerJWTSecretGeneratorCommand(), registerAuthCleanupCommand() and registerAuthPurgeNeverExpiringCommand(). Triggers: `registerJWTSecretGeneratorCommand`, `registerAuthCleanupCommand`, `registerAuthPurgeNeverExpiringCommand`, `warlock jwt.generate`, `warlock auth.cleanup`, `warlock auth.purge-never-expiring`, `cleanupExpiredTokens`, `purgeNeverExpiringTokens`, `command`; "token never expires", "no exp claim", "Invalid Date expires_at"; "generate JWT secret", "bootstrap .env JWT_SECRET", "cron job for expired tokens", "schedule auth cleanup"; typical import `import { registerJWTSecretGeneratorCommand, registerAuthCleanupCommand, registerAuthPurgeNeverExpiringCommand } from "@warlock.js/auth"`. Skip: programmatic cleanup — the `manage-tokens` topic; in-process scheduling — the `scheduler-basics` topic of the `warlock-js-scheduler` skill; competing tools `dotenv-cli`, `node-cron`.
19
+ - [throttle-login-attempts](@warlock.js/auth/skills/throttle-login-attempts/SKILL.md): Brute-force / credential-stuffing protection via `loginThrottleMiddleware` — a failure-aware route gate that counts only failed logins (resets on success), locks per-account and per-source after a threshold, and rejects pre-controller with 429 so the DB lookup and bcrypt verify are skipped. Cache-backed (shared across replicas), fixed-window, fails open on a cache outage. Triggers: `loginThrottleMiddleware`, `AuthErrorCodes.TooManyAttempts`, `EC004`, "rate limit login", "brute force protection", "lock account after failed logins", "throttle login attempts", "too many login attempts 429"; typical import `import { loginThrottleMiddleware } from "@warlock.js/auth"`. Skip: generic per-route request rate limiting that counts every request (use core `middleware.rateLimit`); gating a route by auth — the `protect-routes` topic; issuing tokens — the `handle-login-and-logout` topic.
20
+ - [verify-email-and-reset-password](@warlock.js/auth/skills/verify-email-and-reset-password/SKILL.md): Email verification and password reset with hashed, single-use, expiring, purpose-bound tokens delivered through `@warlock.js/notifications` — `sendEmailVerification(user)`, `verifyEmail(token)`, `requestPasswordReset(Model, email)`, `resetPassword(token, newPassword)`, the `requireVerifiedEmail()` guard, and the `tokenIssueThrottleMiddleware` / `tokenConsumeThrottleMiddleware` presets. Reset revokes every access token, refresh token and cookie session; a reset request answers the same for unknown emails. Triggers: `sendEmailVerification`, `verifyEmail`, `requestPasswordReset`, `resetPassword`, `requireVerifiedEmail`, `isEmailVerified`, `OneTimeToken`, `InvalidOneTimeTokenError`, `EmailNotVerifiedError`, `NotificationsUnavailableError`, `EC007`, `EC008`, `auth.verification`, `auth.passwordReset`; "verify email", "confirm email address", "forgot password", "reset password link", "block unverified users", "resend verification email"; typical import `import { requestPasswordReset, resetPassword } from "@warlock.js/auth"`. Skip: sign-up itself — the `register-user` topic; login throttling — the `throttle-login-attempts` topic; defining notifications — the `define-notification` topic of the `warlock-js-notifications` skill.
package/package.json CHANGED
@@ -12,13 +12,13 @@
12
12
  "ms": "^2.1.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "@warlock.js/fs": "5.34.1",
16
- "@warlock.js/cache": "5.34.1",
17
- "@warlock.js/cascade": "5.34.1",
18
- "@warlock.js/core": "5.34.1",
19
- "@warlock.js/logger": "5.34.1",
20
- "@warlock.js/seal": "5.34.1",
21
- "@warlock.js/notifications": "5.34.1",
15
+ "@warlock.js/fs": "5.34.3",
16
+ "@warlock.js/cache": "5.34.3",
17
+ "@warlock.js/cascade": "5.34.3",
18
+ "@warlock.js/core": "5.34.3",
19
+ "@warlock.js/logger": "5.34.3",
20
+ "@warlock.js/seal": "5.34.3",
21
+ "@warlock.js/notifications": "5.34.3",
22
22
  "@simplewebauthn/server": "^13.1.0",
23
23
  "jose": "^6.1.0"
24
24
  },
@@ -48,7 +48,7 @@
48
48
  ],
49
49
  "author": "hassanzohdy",
50
50
  "license": "MIT",
51
- "version": "5.34.1",
51
+ "version": "5.34.3",
52
52
  "type": "module",
53
53
  "main": "./esm/index.mjs",
54
54
  "module": "./esm/index.mjs",
package/skills/index.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: 'JWT authentication for Warlock apps: login/logout, refresh-token rotation, protected routes, multiple user types. Exports `Auth`, `authService`, `authMiddleware`, `authEvents`, `currentUser`, `loginThrottleMiddleware`, `requireVerifiedEmail`, `GoogleProvider`, `AuthErrorCodes`. Use for: "log a user in and issue tokens", "protect this route", "add an admin user type", "rate-limit login attempts", "verify email / reset password", "sign in with Google". Not this package: general route middleware lives in @warlock.js/core; request-body validation is @warlock.js/seal.'
2
+ description: 'JWT authentication, refresh rotation, sessions, OTP and passkeys for Warlock apps. Exports `Auth`, `authService`, `authMiddleware`, `currentUser` and `GoogleProvider`. Use for "log in", "protect a route", "reset a password", "sign in with Google" or multiple user types. Not this package → @warlock.js/access for roles and permission policies; @warlock.js/core for general middleware; @warlock.js/seal for input rules.'
3
3
  ---
4
4
 
5
5
  # @warlock.js/auth
@@ -8,7 +8,7 @@ A user model extends the `Auth` base model and declares a `userType`. `authServi
8
8
 
9
9
  ## The 80% path
10
10
 
11
- 1. Orient with `overview.md`, then `auth-basics.md` for the shape of config and models.
11
+ 1. Start with `auth-basics.md` for the shape of config and models.
12
12
  2. Extend `Auth` for your user model: `customize-user-type.md`, `register-user.md`.
13
13
  3. Log in / out: `handle-login-and-logout.md`; token lifecycle: `manage-tokens.md`.
14
14
  4. Guard routes: `protect-routes.md`.
@@ -23,3 +23,27 @@ A user model extends the `Auth` base model and declares a `userType`. `authServi
23
23
  - Do not value-import this package from client code; `@warlock.js/web` builds refuse it (type-only imports are fine).
24
24
  - Generate the JWT secret with the bundled command rather than inventing one.
25
25
  - Custom token storage is a supported extension point: `customize-token-storage.md`.
26
+
27
+ ## When to reach for it
28
+
29
+ - You're building a Warlock app that needs login, protected routes, and token-based sessions.
30
+ - You need **multiple user types** (admins + regular users, or client/vendor/staff personas) gated separately on the same auth system.
31
+ - You want refresh-token **rotation + replay detection** out of the box rather than hand-rolling token security.
32
+
33
+ Skip if you're not on `@warlock.js/core` (the package depends on it), or if you need session-cookie auth rather than JWTs.
34
+
35
+ ## The mental model in one paragraph
36
+
37
+ Your user model extends the `Auth` base model and declares its `userType`. A login flows through `authService.login(Model, credentials, deviceInfo?)`: it verifies the password, issues a persisted access + refresh pair, and fires events. `authMiddleware("user")` is a typed hard gate; `authMiddleware()` resolves the configured default type; the object form selects header/cookie credentials, `optional`, and a page-local redirect. Refresh rotation uses a durable token family: family revocation invalidates its refresh and associated access rows. CLI commands generate the JWT secret and clean up expired tokens.
38
+
39
+ ## What this package deliberately doesn't do
40
+
41
+ - **Session-cookie auth.** It's JWT/token-based. If you need server-side sessions, this isn't it.
42
+ - **OAuth / social login / SSO.** No provider adapters here — wire those at the controller layer and create the user through this package's models.
43
+ - **Authorization / roles / permissions (RBAC).** It authenticates (who you are) and gates by user _type_, not fine-grained permissions. Build RBAC on top.
44
+ - **Standalone use.** It depends on `@warlock.js/core` for routing, models (Cascade), and config.
45
+
46
+ ## See also
47
+
48
+ - The `warlock-conventions` topic of the `warlock-js-core` skill — the framework auth runs inside (routing, middleware, config).
49
+ - The `cascade-basics` topic of the `warlock-js-cascade` skill — the ORM behind the `Auth`, `AccessToken`, and `RefreshToken` models.
@@ -178,7 +178,7 @@ The middleware uses the framework's `response.unauthorized({...})` shape. To ove
178
178
 
179
179
  That last one is the difference between a role check and an authorization model: without it, an account-creation endpoint gated on `authMiddleware("admin")` is a privilege-escalation path.
180
180
 
181
- Install `@warlock.js/access` (the `overview` topic of the `warlock-js-access` skill) for that. It layers RBAC plus per-permission ABAC policies over the same authenticated user:
181
+ Install `@warlock.js/access` (the `warlock-js-access` skill index) for that. It layers RBAC plus per-permission ABAC policies over the same authenticated user:
182
182
 
183
183
  ```ts
184
184
  import { router, type RequestHandler } from "@warlock.js/core";
@@ -309,4 +309,4 @@ This is an Origin check, not a double-submit CSRF token — cheaper, and closes
309
309
  - The `customize-user-type` topic — config and multi-user-type semantics
310
310
  - The `handle-login-and-logout` topic — where the access token gets issued in the first place
311
311
  - The `throttle-login-attempts` topic — brute-force throttle to stack in front of the login route
312
- - The `overview` topic of the `warlock-js-access` skill — permissions, roles, and who-may-act-on-whom policies, when user-type gating isn't enough
312
+ - The `warlock-js-access` skill index — permissions, roles, and who-may-act-on-whom policies, when user-type gating isn't enough
@@ -1,83 +0,0 @@
1
- ---
2
- name: overview
3
- description: "@warlock.js/auth overview for orientation and choosing the focused skill for the task."
4
- ---
5
-
6
- # `@warlock.js/auth` — overview
7
-
8
- JWT authentication for Warlock apps. You get a base `Auth` model your user types extend, an `authMiddleware` route gate, an `authService` that runs login/logout/refresh (with refresh-token rotation and replay detection), persisted access + refresh tokens, multi-user-type support, lifecycle events, and two bundled CLI commands.
9
-
10
- Coupled to `@warlock.js/core` — you're inside a Warlock project before this package makes sense.
11
-
12
- Server-only: `package.json` declares `"warlock": { "environment": "server" }`. `@warlock.js/web`'s build refuses app client code that value-imports this package; type-only imports are allowed, and server loaders/controllers/modules are unaffected.
13
-
14
- ## When to reach for it
15
-
16
- - You're building a Warlock app that needs login, protected routes, and token-based sessions.
17
- - You need **multiple user types** (admins + regular users, or client/vendor/staff personas) gated separately on the same auth system.
18
- - You want refresh-token **rotation + replay detection** out of the box rather than hand-rolling token security.
19
-
20
- Skip if you're not on `@warlock.js/core` (the package depends on it), or if you need session-cookie auth rather than JWTs.
21
-
22
- ## The mental model in one paragraph
23
-
24
- Your user model extends the `Auth` base model and declares its `userType`. A login flows through `authService.login(Model, credentials, deviceInfo?)`: it verifies the password, issues a persisted access + refresh pair, and fires events. `authMiddleware("user")` is a typed hard gate; `authMiddleware()` resolves the configured default type; the object form selects header/cookie credentials, `optional`, and a page-local redirect. Refresh rotation uses a durable token family: family revocation invalidates its refresh and associated access rows. CLI commands generate the JWT secret and clean up expired tokens.
25
-
26
- ## Skills index
27
-
28
- Nine task skills. Most apps need `auth-basics` + `protect-routes` + `handle-login-and-logout`.
29
-
30
- ### Foundations
31
-
32
- #### `auth-basics`
33
-
34
- Start here. The `Auth` base model, `authMiddleware` gate, `authService` (login/logout/refresh), AccessToken + RefreshToken persistence, multi-user-type support.
35
-
36
- ### The flows
37
-
38
- #### `handle-login-and-logout`
39
-
40
- `authService.login(Model, credentials, deviceInfo?)` — verify password, issue the token pair, fire events. `authService.logout(user, accessToken?, refreshToken?)` — revoke tokens. For your `POST /login` and `POST /logout` controllers.
41
-
42
- #### `register-user`
43
-
44
- Sign up a new user and issue the first token pair — `User.create({ ...password: await hashPassword(plain) })` then `authService.createTokenPair(user)`. For `POST /register`.
45
-
46
- #### `protect-routes`
47
-
48
- `authMiddleware` object and legacy overloads: typed/default hard gates, optional resolution, credential source, and page-local redirects. Sets `request.locals.user` + `request.decodedAccessToken` when a user resolves.
49
-
50
- ### Going deeper
51
-
52
- #### `manage-tokens`
53
-
54
- The token lifecycle — `generateAccessToken`, `createRefreshToken`, `createTokenPair`, `refreshTokens` (rotation + replay detection), `revokeAllTokens`, `revokeTokenFamily`, `cleanupExpiredTokens`, `getActiveSessions`. For custom login/registration, token revocation, "logout everywhere", and scheduled cleanup.
55
-
56
- #### `customize-user-type`
57
-
58
- Support multiple user types in one system — each `Auth` subclass overrides `userType`, `config.auth.userType.<slug>` maps the slug to a model class, `authMiddleware("admin")` / `authMiddleware(["admin", "staff"])` gates per type.
59
-
60
- #### `customize-token-storage`
61
-
62
- Override the persisted `AccessToken` / `RefreshToken` models to add columns (multi-tenant `organization_id`), rename, or change storage — extend the model + schema and register it under `config.auth.accessToken.model` / `config.auth.refreshToken.model`.
63
-
64
- #### `throttle-login-attempts`
65
-
66
- Brute-force / credential-stuffing protection — `loginThrottleMiddleware()` counts only failed logins, resets on success, locks per-account + per-IP after a threshold, and rejects pre-controller with 429. Cache-backed, fails open on a cache outage.
67
-
68
- #### `run-auth-commands`
69
-
70
- Two CLI commands — `warlock jwt.generate` (strong JWT secret → `.env`) and `warlock auth.cleanup` (remove expired refresh tokens). Register via `registerJWTSecretGeneratorCommand()` and `registerAuthCleanupCommand()`.
71
-
72
- ## What this package deliberately doesn't do
73
-
74
- - **Session-cookie auth.** It's JWT/token-based. If you need server-side sessions, this isn't it.
75
- - **OAuth / social login / SSO.** No provider adapters here — wire those at the controller layer and create the user through this package's models.
76
- - **Authorization / roles / permissions (RBAC).** It authenticates (who you are) and gates by user _type_, not fine-grained permissions. Build RBAC on top.
77
- - **Standalone use.** It depends on `@warlock.js/core` for routing, models (Cascade), and config.
78
-
79
- ## See also
80
-
81
- - The `warlock-conventions` topic of the `warlock-js-core` skill — the framework auth runs inside (routing, middleware, config).
82
- - The `cascade-basics` topic of the `warlock-js-cascade` skill — the ORM behind the `Auth`, `AccessToken`, and `RefreshToken` models.
83
- - `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview` topic becomes `.claude/skills/warlock-js-auth/overview.md`.