@warlock.js/auth 5.34.1 → 5.34.2
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 +6 -0
- package/llms-full.txt +55 -89
- package/llms.txt +1 -1
- package/package.json +8 -8
- package/skills/index.md +25 -1
- package/skills/protect-routes/SKILL.md +2 -2
- package/skills/overview/SKILL.md +0 -83
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ 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.2 - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Merge package orientation into the grouped skill index and remove the duplicate overview topic; preserve that orientation in generated LLM projections.
|
|
12
|
+
|
|
7
13
|
## 5.32.0 - 2026-10-18
|
|
8
14
|
|
|
9
15
|
### Changed
|
package/llms-full.txt
CHANGED
|
@@ -4,6 +4,59 @@
|
|
|
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
|
+
## Package orientation
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
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.'
|
|
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
|
+
|
|
7
60
|
## auth-basics `@warlock.js/auth/auth-basics/SKILL.md`
|
|
8
61
|
|
|
9
62
|
---
|
|
@@ -1182,93 +1235,6 @@ 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
1238
|
## protect-routes `@warlock.js/auth/protect-routes/SKILL.md`
|
|
1273
1239
|
|
|
1274
1240
|
---
|
|
@@ -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,7 +1548,7 @@ 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
1554
|
## register-user `@warlock.js/auth/register-user/SKILL.md`
|
package/llms.txt
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
## Skills
|
|
8
8
|
|
|
9
|
+
- [Package orientation](@warlock.js/auth/skills/index.md): 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.
|
|
9
10
|
- [auth-basics](@warlock.js/auth/auth-basics/SKILL.md): Start here for @warlock.js/auth configuration, user models, credentials, and application session flows.
|
|
10
11
|
- [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
12
|
- [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
13
|
- [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
14
|
- [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
15
|
- [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
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
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
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`.
|
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.2",
|
|
16
|
+
"@warlock.js/cache": "5.34.2",
|
|
17
|
+
"@warlock.js/cascade": "5.34.2",
|
|
18
|
+
"@warlock.js/core": "5.34.2",
|
|
19
|
+
"@warlock.js/logger": "5.34.2",
|
|
20
|
+
"@warlock.js/seal": "5.34.2",
|
|
21
|
+
"@warlock.js/notifications": "5.34.2",
|
|
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.2",
|
|
52
52
|
"type": "module",
|
|
53
53
|
"main": "./esm/index.mjs",
|
|
54
54
|
"module": "./esm/index.mjs",
|
package/skills/index.md
CHANGED
|
@@ -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`.
|