@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 +12 -0
- package/llms-full.txt +66 -100
- package/llms.txt +12 -12
- package/package.json +8 -8
- package/skills/index.md +26 -2
- package/skills/protect-routes/SKILL.md +2 -2
- package/skills/overview/SKILL.md +0 -83
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
|
-
##
|
|
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
|
-
##
|
|
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 `
|
|
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 `
|
|
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
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [customize-
|
|
12
|
-
- [
|
|
13
|
-
- [login-
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
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.
|
|
16
|
-
"@warlock.js/cache": "5.34.
|
|
17
|
-
"@warlock.js/cascade": "5.34.
|
|
18
|
-
"@warlock.js/core": "5.34.
|
|
19
|
-
"@warlock.js/logger": "5.34.
|
|
20
|
-
"@warlock.js/seal": "5.34.
|
|
21
|
-
"@warlock.js/notifications": "5.34.
|
|
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.
|
|
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
|
|
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.
|
|
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 `
|
|
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 `
|
|
312
|
+
- The `warlock-js-access` skill index — permissions, roles, and who-may-act-on-whom policies, when user-type gating isn't enough
|
package/skills/overview/SKILL.md
DELETED
|
@@ -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`.
|