sentri 1.0.6 → 1.1.0
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/README.md +107 -21
- package/dist/client.d.ts +12 -10
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/errors/AuthError.d.ts +9 -8
- package/dist/errors/AuthError.d.ts.map +1 -1
- package/dist/errors/AuthError.js +9 -8
- package/dist/errors/AuthError.js.map +1 -1
- package/dist/libs/token.d.ts +5 -4
- package/dist/libs/token.d.ts.map +1 -1
- package/dist/libs/token.js +3 -2
- package/dist/libs/token.js.map +1 -1
- package/dist/middleware/protect.d.ts +14 -4
- package/dist/middleware/protect.d.ts.map +1 -1
- package/dist/middleware/protect.js +24 -6
- package/dist/middleware/protect.js.map +1 -1
- package/dist/middleware/router.d.ts +5 -2
- package/dist/middleware/router.d.ts.map +1 -1
- package/dist/middleware/router.js +29 -5
- package/dist/middleware/router.js.map +1 -1
- package/dist/services/auth.d.ts +3 -1
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +7 -3
- package/dist/services/auth.js.map +1 -1
- package/dist/types/auth.d.ts +50 -8
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js.map +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# sentri
|
|
2
2
|
|
|
3
|
-
Auth and authorization library for Express + PostgreSQL. Provides JWT-based authentication with refresh token rotation, role-based access control, fine-grained permission checks, and a pre-built Express router — all behind a single typed client.
|
|
3
|
+
Auth and authorization library for Express + PostgreSQL. Provides JWT-based authentication with session-bound access tokens, refresh token rotation, role-based access control, fine-grained permission checks, and a pre-built Express router — all behind a single typed client.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -99,7 +99,7 @@ npx sentri generate drizzle
|
|
|
99
99
|
import { createAuth } from 'sentri';
|
|
100
100
|
|
|
101
101
|
export const auth = createAuth({
|
|
102
|
-
secret: process.env.JWT_SECRET!, // required — keep in env
|
|
102
|
+
secret: process.env.JWT_SECRET!, // required — keep in env, min 32 chars
|
|
103
103
|
validRoles: ['user', 'admin'] as const, // required — use `as const` for type safety
|
|
104
104
|
adapter: myAdapter, // required — see Adapter Interface
|
|
105
105
|
|
|
@@ -109,6 +109,10 @@ export const auth = createAuth({
|
|
|
109
109
|
algorithm: 'HS256', // default: 'HS256' — also 'HS384' | 'HS512'
|
|
110
110
|
saltRounds: 12, // default: 12 (bcrypt rounds, min 10)
|
|
111
111
|
|
|
112
|
+
// Restrict POST /register to callers that supply X-Api-Key header.
|
|
113
|
+
// When set, only requests with this exact key can create new accounts.
|
|
114
|
+
apiKey: process.env.REGISTER_API_KEY, // optional
|
|
115
|
+
|
|
112
116
|
cookie: { // optional — enables httpOnly cookie for refresh token
|
|
113
117
|
secure: process.env.NODE_ENV === 'production',
|
|
114
118
|
// name: 'refresh_token', // default: 'refresh_token'
|
|
@@ -119,7 +123,7 @@ export const auth = createAuth({
|
|
|
119
123
|
|
|
120
124
|
// router: { // optional — replace built-in service logic per route
|
|
121
125
|
// login: async (input) => { ... },
|
|
122
|
-
//
|
|
126
|
+
// register: async (input) => { ... },
|
|
123
127
|
// refresh: async (refreshToken) => { ... },
|
|
124
128
|
// logout: async (refreshToken) => { ... },
|
|
125
129
|
// logoutAll: async (userId) => { ... },
|
|
@@ -134,6 +138,50 @@ When `cookie` is configured, the refresh token is stored in an httpOnly cookie a
|
|
|
134
138
|
|
|
135
139
|
---
|
|
136
140
|
|
|
141
|
+
## apiKey — Restricting Registration
|
|
142
|
+
|
|
143
|
+
By default `POST /register` is open to the public. This can be a security risk when your application allows role selection at registration time — any caller could register themselves as `admin`.
|
|
144
|
+
|
|
145
|
+
Set `apiKey` in your config to lock the endpoint:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
export const auth = createAuth({
|
|
149
|
+
// ...
|
|
150
|
+
apiKey: process.env.REGISTER_API_KEY!,
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Requests to `POST /register` must then include the header:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
X-Api-Key: <value of REGISTER_API_KEY>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Requests without the header, or with the wrong value, receive HTTP 401 `UNAUTHORIZED`. Keep the API key in an environment variable and share it only with trusted services (your back-office panel, CI scripts, etc.).
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Session-Bound Access Tokens
|
|
165
|
+
|
|
166
|
+
Since version 1.1.0, access tokens embed the `sessionId` of the session that was created at login. The `protect()` middleware validates this session against the database on every request.
|
|
167
|
+
|
|
168
|
+
**What this means in practice:**
|
|
169
|
+
|
|
170
|
+
- `POST /logout` deletes the session. Any access token issued during that login is immediately rejected — even if it has not expired yet.
|
|
171
|
+
- `POST /logout-all` deletes **all** sessions for the user. Every access token across all devices is immediately rejected.
|
|
172
|
+
- Tokens issued before 1.1.0 (without the `sessionId` claim) are still accepted but bypass session validation — plan a rolling upgrade if you need strict enforcement for existing tokens.
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
Login → session created → access token embeds sessionId
|
|
176
|
+
Request → protect() verifies JWT → checks session exists → ✓ allowed
|
|
177
|
+
Logout → session deleted
|
|
178
|
+
Request → protect() verifies JWT → session not found → ✗ 401 UNAUTHORIZED
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
> **Trade-off:** `protect()` now performs one additional database read per request. For most applications this is negligible. If you need to avoid any per-request DB access, keep `accessExpiresIn` short (e.g. `'5m'`) and rely on token expiry instead — but note that tokens will remain valid for up to `accessExpiresIn` after logout.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
137
185
|
## Custom Route Handlers
|
|
138
186
|
|
|
139
187
|
The `router` field in config lets you replace the built-in service logic for individual routes while the router still handles request parsing, input validation, and response formatting.
|
|
@@ -159,9 +207,9 @@ export const auth = createAuth({
|
|
|
159
207
|
return defaultLogin(input);
|
|
160
208
|
},
|
|
161
209
|
|
|
162
|
-
// Send a welcome email after
|
|
163
|
-
|
|
164
|
-
const result = await
|
|
210
|
+
// Send a welcome email after registration
|
|
211
|
+
register: async (input) => {
|
|
212
|
+
const result = await defaultRegister(input);
|
|
165
213
|
if (result.success) {
|
|
166
214
|
await emailService.sendWelcome(input.identifier);
|
|
167
215
|
}
|
|
@@ -184,7 +232,7 @@ export const auth = createAuth({
|
|
|
184
232
|
|
|
185
233
|
| Key | Signature | Must return |
|
|
186
234
|
|---|---|---|
|
|
187
|
-
| `
|
|
235
|
+
| `register` | `(input: SignupInput) => Promise<SignupResult>` | `SignupResult` |
|
|
188
236
|
| `login` | `(input: LoginInput) => Promise<AuthResult>` | `AuthResult` |
|
|
189
237
|
| `refresh` | `(refreshToken: string) => Promise<RefreshResult>` | `RefreshResult` |
|
|
190
238
|
| `logout` | `(refreshToken: string \| undefined) => Promise<void>` | `void` |
|
|
@@ -258,11 +306,12 @@ export const adapter = createAdapter(db);
|
|
|
258
306
|
|
|
259
307
|
### Endpoints
|
|
260
308
|
|
|
261
|
-
#### `POST /
|
|
309
|
+
#### `POST /register`
|
|
262
310
|
|
|
263
|
-
Register a new user. Does **not** issue tokens — call `/login` after
|
|
311
|
+
Register a new user. Does **not** issue tokens — call `/login` after registration.
|
|
264
312
|
|
|
265
313
|
```
|
|
314
|
+
Headers: X-Api-Key: <key> (required when config.apiKey is set)
|
|
266
315
|
Body: { identifier, password, roles?: string[] }
|
|
267
316
|
Returns: { user: { id, identifier, roles } }
|
|
268
317
|
Status: 201
|
|
@@ -310,7 +359,7 @@ Returns: null
|
|
|
310
359
|
Status: 200
|
|
311
360
|
```
|
|
312
361
|
|
|
313
|
-
Safe to call even if the cookie is missing or the token is already expired.
|
|
362
|
+
After logout, any access token bound to this session is immediately rejected by `protect()`. Safe to call even if the cookie is missing or the token is already expired.
|
|
314
363
|
|
|
315
364
|
---
|
|
316
365
|
|
|
@@ -324,6 +373,8 @@ Returns: null
|
|
|
324
373
|
Status: 200
|
|
325
374
|
```
|
|
326
375
|
|
|
376
|
+
All access tokens across all devices are immediately rejected by `protect()` after this call.
|
|
377
|
+
|
|
327
378
|
---
|
|
328
379
|
|
|
329
380
|
#### `GET /me`
|
|
@@ -355,7 +406,7 @@ Status: 200
|
|
|
355
406
|
|
|
356
407
|
### `auth.protect()`
|
|
357
408
|
|
|
358
|
-
Verifies the `Authorization: Bearer <token>` header and injects `request.user` into the request.
|
|
409
|
+
Verifies the `Authorization: Bearer <token>` header, confirms the session is still active in the database, and injects `request.user` into the request.
|
|
359
410
|
|
|
360
411
|
```typescript
|
|
361
412
|
router.get('/dashboard', auth.protect(), (request, response) => {
|
|
@@ -363,6 +414,11 @@ router.get('/dashboard', auth.protect(), (request, response) => {
|
|
|
363
414
|
});
|
|
364
415
|
```
|
|
365
416
|
|
|
417
|
+
Returns HTTP 401 if:
|
|
418
|
+
- The `Authorization` header is missing or malformed
|
|
419
|
+
- The token signature is invalid or the token is expired
|
|
420
|
+
- The session embedded in the token has been revoked (logout)
|
|
421
|
+
|
|
366
422
|
---
|
|
367
423
|
|
|
368
424
|
### `auth.authorize(...roles)`
|
|
@@ -467,11 +523,11 @@ All errors thrown by the library are instances of `AuthError` with a machine-rea
|
|
|
467
523
|
| Code | HTTP | Meaning |
|
|
468
524
|
|---|---|---|
|
|
469
525
|
| `INVALID_CREDENTIALS` | 401 | Wrong identifier or password |
|
|
470
|
-
| `USER_ALREADY_EXISTS` | 409 |
|
|
526
|
+
| `USER_ALREADY_EXISTS` | 409 | Registration with duplicate identifier |
|
|
471
527
|
| `USER_NOT_FOUND` | 404 | Operation on a non-existent user |
|
|
472
528
|
| `TOKEN_EXPIRED` | 401 | JWT `exp` claim is in the past |
|
|
473
529
|
| `TOKEN_INVALID` | 401 | JWT signature invalid or malformed |
|
|
474
|
-
| `UNAUTHORIZED` | 401 | No valid access token
|
|
530
|
+
| `UNAUTHORIZED` | 401 | No valid access token, revoked session, or invalid API key |
|
|
475
531
|
| `FORBIDDEN` | 403 | Authenticated but missing required role |
|
|
476
532
|
| `INVALID_ROLE` | 400 | Role name not in `validRoles` |
|
|
477
533
|
| `VALIDATION_ERROR` | 400 | Missing or invalid input field |
|
|
@@ -482,17 +538,47 @@ The built-in router converts all `AuthError` instances to the standard envelope
|
|
|
482
538
|
```typescript
|
|
483
539
|
import { AuthError } from 'sentri';
|
|
484
540
|
|
|
541
|
+
const AUTH_ERROR_STATUS: Record<string, number> = {
|
|
542
|
+
UNAUTHORIZED: 401,
|
|
543
|
+
TOKEN_EXPIRED: 401,
|
|
544
|
+
TOKEN_INVALID: 401,
|
|
545
|
+
INVALID_CREDENTIALS: 401,
|
|
546
|
+
FORBIDDEN: 403,
|
|
547
|
+
USER_NOT_FOUND: 404,
|
|
548
|
+
USER_ALREADY_EXISTS: 409,
|
|
549
|
+
INVALID_ROLE: 400,
|
|
550
|
+
VALIDATION_ERROR: 400,
|
|
551
|
+
CONFIGURATION_ERROR: 500,
|
|
552
|
+
};
|
|
553
|
+
|
|
485
554
|
app.use((error, _request, response, next) => {
|
|
486
555
|
if (error instanceof AuthError) {
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
:
|
|
490
|
-
|
|
491
|
-
: error.code
|
|
492
|
-
:
|
|
493
|
-
|
|
494
|
-
|
|
556
|
+
const statusCode = AUTH_ERROR_STATUS[error.code] ?? 500;
|
|
557
|
+
return response.status(statusCode).json({
|
|
558
|
+
error: true,
|
|
559
|
+
statusCode,
|
|
560
|
+
code: error.code,
|
|
561
|
+
message: error.message,
|
|
562
|
+
data: null,
|
|
563
|
+
});
|
|
495
564
|
}
|
|
496
565
|
next(error);
|
|
497
566
|
});
|
|
498
567
|
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Migration from 1.0.x
|
|
572
|
+
|
|
573
|
+
### Breaking changes
|
|
574
|
+
|
|
575
|
+
| What changed | Action required |
|
|
576
|
+
|---|---|
|
|
577
|
+
| `POST /signup` renamed to `POST /register` | Update all client-side calls |
|
|
578
|
+
| `RouterHandlers.signup` renamed to `RouterHandlers.register` | Update config if you used a custom signup handler |
|
|
579
|
+
| `protect()` now performs one DB read per request | Ensure your adapter's `session.findById` is indexed on session ID |
|
|
580
|
+
|
|
581
|
+
### New features
|
|
582
|
+
|
|
583
|
+
- **Session-bound tokens** — access tokens are immediately invalidated after logout without waiting for expiry.
|
|
584
|
+
- **`apiKey` config** — lock `POST /register` to trusted callers via `X-Api-Key` header.
|
package/dist/client.d.ts
CHANGED
|
@@ -15,11 +15,11 @@ export interface AuthClient<TRole extends string = string> {
|
|
|
15
15
|
* Express middleware factory that enforces authentication.
|
|
16
16
|
*
|
|
17
17
|
* Reads the `Authorization: Bearer <token>` header, verifies the access token,
|
|
18
|
-
* and injects the decoded payload as `
|
|
18
|
+
* and injects the decoded payload as `request.user`. Calls `next(AuthError)` on failure.
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
|
-
* router.get('/me', auth.protect(), (
|
|
22
|
-
*
|
|
21
|
+
* router.get('/me', auth.protect(), (request, response) => {
|
|
22
|
+
* response.json(request.user);
|
|
23
23
|
* });
|
|
24
24
|
*/
|
|
25
25
|
protect(): RequestHandler;
|
|
@@ -47,7 +47,7 @@ export interface AuthClient<TRole extends string = string> {
|
|
|
47
47
|
* // User can only update their own profile
|
|
48
48
|
* router.put('/users/:id',
|
|
49
49
|
* auth.protect(),
|
|
50
|
-
* auth.permit((
|
|
50
|
+
* auth.permit((request) => request.user!.id === request.params['id']),
|
|
51
51
|
* handler,
|
|
52
52
|
* );
|
|
53
53
|
*
|
|
@@ -57,9 +57,9 @@ export interface AuthClient<TRole extends string = string> {
|
|
|
57
57
|
* auth.protect(),
|
|
58
58
|
* auth.permit({
|
|
59
59
|
* roles: ['admin'],
|
|
60
|
-
* check: async (
|
|
61
|
-
* const post = await db.post.findUnique({ where: { id:
|
|
62
|
-
* return post?.authorId ===
|
|
60
|
+
* check: async (request) => {
|
|
61
|
+
* const post = await db.post.findUnique({ where: { id: request.params['id'] } });
|
|
62
|
+
* return post?.authorId === request.user!.id;
|
|
63
63
|
* },
|
|
64
64
|
* }),
|
|
65
65
|
* handler,
|
|
@@ -84,11 +84,13 @@ export interface AuthClient<TRole extends string = string> {
|
|
|
84
84
|
/**
|
|
85
85
|
* Returns a pre-built Express Router with all standard auth endpoints mounted:
|
|
86
86
|
*
|
|
87
|
-
* - `POST /
|
|
87
|
+
* - `POST /register` — register a new user, returns `{ user }`.
|
|
88
|
+
* Requires `X-Api-Key` header when `config.apiKey` is set.
|
|
88
89
|
* - `POST /login` — authenticate, sets refresh token cookie, returns `{ accessToken, user }`
|
|
89
90
|
* - `POST /refresh` — reads refresh token from cookie, returns `{ accessToken }`
|
|
90
|
-
* - `POST /logout` — invalidate current session
|
|
91
|
-
*
|
|
91
|
+
* - `POST /logout` — invalidate the current session; any access token bound to
|
|
92
|
+
* this session is immediately rejected by `protect()`.
|
|
93
|
+
* - `POST /logout-all` — invalidate all sessions for the user (requires valid access token)
|
|
92
94
|
* - `GET /me` — return the authenticated user
|
|
93
95
|
* - `POST /users/:userId/roles` — assign roles (requires admin)
|
|
94
96
|
*
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACvD;;;;;;;;;;OAUG;IACH,OAAO,IAAI,cAAc,CAAC;IAE1B;;;;;;;;;OASG;IACH,SAAS,CAAC,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;IAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,CAAC;IAC3C,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC;IAEtD,oEAAoE;IACpE,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7C,kEAAkE;IAClE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9D,uDAAuD;IACvD,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;IAElD,kDAAkD;IAClD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5C,mFAAmF;IACnF,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,mFAAmF;IACnF,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzD
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACvD;;;;;;;;;;OAUG;IACH,OAAO,IAAI,cAAc,CAAC;IAE1B;;;;;;;;;OASG;IACH,SAAS,CAAC,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;IAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,CAAC;IAC3C,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC;IAEtD,oEAAoE;IACpE,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7C,kEAAkE;IAClE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9D,uDAAuD;IACvD,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;IAElD,kDAAkD;IAClD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5C,mFAAmF;IACnF,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,mFAAmF;IACnF,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzD;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,IAAI,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EACtD,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,GACxB,UAAU,CAAC,KAAK,CAAC,CAgBnB"}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAkH1D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,UAAU,CACxB,MAAyB;IAEzB,cAAc,CAAC,MAAoB,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAoB,CAAC,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAoB,CAAC;QAC5C,SAAS,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;QAC5C,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC;QACjE,cAAc,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC;QAC5D,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,OAAmB,EAAE,MAAoB,CAAC;QACxF,gBAAgB,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAoB,CAAC;QAClF,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAoB,CAAoB;QAC/F,kBAAkB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAoB,CAAC;QAC9E,MAAM,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC;QACtC,MAAM,EAAE,CAAC,cAAkD,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC;KACvF,CAAC;AACJ,CAAC"}
|
|
@@ -17,19 +17,20 @@ export type AuthErrorCode = 'INVALID_CREDENTIALS' | 'USER_NOT_FOUND' | 'USER_ALR
|
|
|
17
17
|
* Error class thrown by the library for all authentication and authorization failures.
|
|
18
18
|
*
|
|
19
19
|
* Carries a machine-readable `code` that lets you distinguish error types without
|
|
20
|
-
* string-matching on the message
|
|
20
|
+
* string-matching on the message.
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
|
-
* import { AuthError } from '
|
|
23
|
+
* import { AuthError } from 'sentri';
|
|
24
24
|
*
|
|
25
|
-
* app.use((
|
|
26
|
-
* if (
|
|
27
|
-
* const status =
|
|
28
|
-
*
|
|
25
|
+
* app.use((error, _request, response, next) => {
|
|
26
|
+
* if (error instanceof AuthError) {
|
|
27
|
+
* const status =
|
|
28
|
+
* error.code === 'UNAUTHORIZED' ? 401
|
|
29
|
+
* : error.code === 'FORBIDDEN' ? 403
|
|
29
30
|
* : 400;
|
|
30
|
-
*
|
|
31
|
+
* response.status(status).json({ error: error.code, message: error.message });
|
|
31
32
|
* } else {
|
|
32
|
-
* next(
|
|
33
|
+
* next(error);
|
|
33
34
|
* }
|
|
34
35
|
* });
|
|
35
36
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthError.d.ts","sourceRoot":"","sources":["../../src/errors/AuthError.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,eAAe,GACf,eAAe,GACf,WAAW,GACX,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B
|
|
1
|
+
{"version":3,"file":"AuthError.d.ts","sourceRoot":"","sources":["../../src/errors/AuthError.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,qBAAqB,GACrB,eAAe,GACf,eAAe,GACf,WAAW,GACX,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,SAAgB,IAAI,EAAE,aAAa,CAAC;gBAExB,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;CAKjD"}
|
package/dist/errors/AuthError.js
CHANGED
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
* Error class thrown by the library for all authentication and authorization failures.
|
|
3
3
|
*
|
|
4
4
|
* Carries a machine-readable `code` that lets you distinguish error types without
|
|
5
|
-
* string-matching on the message
|
|
5
|
+
* string-matching on the message.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
|
-
* import { AuthError } from '
|
|
8
|
+
* import { AuthError } from 'sentri';
|
|
9
9
|
*
|
|
10
|
-
* app.use((
|
|
11
|
-
* if (
|
|
12
|
-
* const status =
|
|
13
|
-
*
|
|
10
|
+
* app.use((error, _request, response, next) => {
|
|
11
|
+
* if (error instanceof AuthError) {
|
|
12
|
+
* const status =
|
|
13
|
+
* error.code === 'UNAUTHORIZED' ? 401
|
|
14
|
+
* : error.code === 'FORBIDDEN' ? 403
|
|
14
15
|
* : 400;
|
|
15
|
-
*
|
|
16
|
+
* response.status(status).json({ error: error.code, message: error.message });
|
|
16
17
|
* } else {
|
|
17
|
-
* next(
|
|
18
|
+
* next(error);
|
|
18
19
|
* }
|
|
19
20
|
* });
|
|
20
21
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthError.js","sourceRoot":"","sources":["../../src/errors/AuthError.ts"],"names":[],"mappings":"AA0BA
|
|
1
|
+
{"version":3,"file":"AuthError.js","sourceRoot":"","sources":["../../src/errors/AuthError.ts"],"names":[],"mappings":"AA0BA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClB,IAAI,CAAgB;IAEpC,YAAY,IAAmB,EAAE,OAAe;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/libs/token.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type { AuthConfig, AuthUser } from '../types/auth.js';
|
|
1
|
+
import type { AccessTokenPayload, AuthConfig, AuthUser } from '../types/auth.js';
|
|
2
2
|
/**
|
|
3
|
-
* Sign a short-lived access token containing the user's identity and
|
|
3
|
+
* Sign a short-lived access token containing the user's identity, roles, and
|
|
4
|
+
* the session ID that `protect()` uses to verify the session is still active.
|
|
4
5
|
*
|
|
5
6
|
* Uses the access-specific secret derived from config and the configured
|
|
6
7
|
* `accessExpiresIn` duration and HMAC algorithm.
|
|
7
8
|
*
|
|
8
|
-
* @param payload - The {@link
|
|
9
|
+
* @param payload - The {@link AccessTokenPayload} to embed (id, identifier, roles, sessionId).
|
|
9
10
|
* @param config - Auth configuration used to derive the secret and options.
|
|
10
11
|
* @returns Compact JWT string.
|
|
11
12
|
*/
|
|
12
|
-
export declare function signAccessToken(payload: AuthUser, config: AuthConfig): string;
|
|
13
|
+
export declare function signAccessToken(payload: AuthUser | AccessTokenPayload, config: AuthConfig): string;
|
|
13
14
|
/**
|
|
14
15
|
* Sign a long-lived refresh token bound to a specific session ID.
|
|
15
16
|
*
|
package/dist/libs/token.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/libs/token.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/libs/token.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAqEjF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,QAAQ,GAAG,kBAAkB,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAIlG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAI9E;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,CAI7E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAI3F"}
|
package/dist/libs/token.js
CHANGED
|
@@ -58,12 +58,13 @@ function verify(token, secret, algorithm) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Sign a short-lived access token containing the user's identity and
|
|
61
|
+
* Sign a short-lived access token containing the user's identity, roles, and
|
|
62
|
+
* the session ID that `protect()` uses to verify the session is still active.
|
|
62
63
|
*
|
|
63
64
|
* Uses the access-specific secret derived from config and the configured
|
|
64
65
|
* `accessExpiresIn` duration and HMAC algorithm.
|
|
65
66
|
*
|
|
66
|
-
* @param payload - The {@link
|
|
67
|
+
* @param payload - The {@link AccessTokenPayload} to embed (id, identifier, roles, sessionId).
|
|
67
68
|
* @param config - Auth configuration used to derive the secret and options.
|
|
68
69
|
* @returns Compact JWT string.
|
|
69
70
|
*/
|
package/dist/libs/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/libs/token.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,EAAE,EAAoB,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,MAAc;IACnC,OAAO;QACL,MAAM,EAAE,GAAG,MAAM,SAAS;QAC1B,OAAO,EAAE,GAAG,MAAM,UAAU;KAC7B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,IAAI,CACX,OAAe,EACf,MAAc,EACd,SAA0B,EAC1B,SAAsC;IAEtC,MAAM,OAAO,GAAgB;QAC3B,SAAS,EAAE,SAAyD;QACpE,SAAS;KACV,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,MAAM,CACb,KAAa,EACb,MAAc,EACd,SAAsC;IAEtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACvE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,gCAAgC,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,OAAY,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,SAAS;YAAE,MAAM,GAAG,CAAC;QACxC,IAAI,GAAG,YAAY,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,eAAe,EAAE,+BAA+B,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/libs/token.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import type { RequestHandler } from 'express';
|
|
2
2
|
import type { AuthConfig } from '../types/auth.js';
|
|
3
3
|
/**
|
|
4
|
-
* Express middleware factory that enforces JWT authentication.
|
|
4
|
+
* Express middleware factory that enforces JWT authentication and session validity.
|
|
5
5
|
*
|
|
6
6
|
* Reads the `Authorization: Bearer <token>` header, verifies the access token,
|
|
7
7
|
* and attaches the decoded payload to `req.user`. Calls `next(AuthError)` on
|
|
8
8
|
* any failure so your error handler can convert it to an HTTP response.
|
|
9
9
|
*
|
|
10
|
+
* Since sentri 1.1.0 access tokens embed a `sessionId` claim. When this claim
|
|
11
|
+
* is present, `protect()` performs a lightweight database lookup
|
|
12
|
+
* (`adapter.session.findById`) to confirm the session is still active. This
|
|
13
|
+
* means a user who has logged out (or been logged out from all devices) cannot
|
|
14
|
+
* use an access token that was issued before the logout — even if the token has
|
|
15
|
+
* not yet expired.
|
|
16
|
+
*
|
|
17
|
+
* Tokens issued before 1.1.0 (without the `sessionId` claim) are still accepted
|
|
18
|
+
* but bypass the session check.
|
|
19
|
+
*
|
|
10
20
|
* Must be used **before** `authorize()` or `permit()`.
|
|
11
21
|
*
|
|
12
|
-
* @param config - Auth configuration
|
|
22
|
+
* @param config - Auth configuration (secret, algorithm, adapter).
|
|
13
23
|
* @returns An Express `RequestHandler` that populates `req.user` on success.
|
|
14
24
|
*
|
|
15
25
|
* @example
|
|
16
|
-
* router.get('/profile', protect(config), (
|
|
17
|
-
*
|
|
26
|
+
* router.get('/profile', protect(config), (request, response) => {
|
|
27
|
+
* response.json(request.user);
|
|
18
28
|
* });
|
|
19
29
|
*/
|
|
20
30
|
export declare function protect(config: AuthConfig): RequestHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect.d.ts","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"protect.d.ts","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,KAAK,EAAsB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,CAwB1D"}
|
|
@@ -1,31 +1,49 @@
|
|
|
1
1
|
import { AuthError } from '../errors/AuthError.js';
|
|
2
2
|
import { verifyAccessToken } from '../libs/token.js';
|
|
3
3
|
/**
|
|
4
|
-
* Express middleware factory that enforces JWT authentication.
|
|
4
|
+
* Express middleware factory that enforces JWT authentication and session validity.
|
|
5
5
|
*
|
|
6
6
|
* Reads the `Authorization: Bearer <token>` header, verifies the access token,
|
|
7
7
|
* and attaches the decoded payload to `req.user`. Calls `next(AuthError)` on
|
|
8
8
|
* any failure so your error handler can convert it to an HTTP response.
|
|
9
9
|
*
|
|
10
|
+
* Since sentri 1.1.0 access tokens embed a `sessionId` claim. When this claim
|
|
11
|
+
* is present, `protect()` performs a lightweight database lookup
|
|
12
|
+
* (`adapter.session.findById`) to confirm the session is still active. This
|
|
13
|
+
* means a user who has logged out (or been logged out from all devices) cannot
|
|
14
|
+
* use an access token that was issued before the logout — even if the token has
|
|
15
|
+
* not yet expired.
|
|
16
|
+
*
|
|
17
|
+
* Tokens issued before 1.1.0 (without the `sessionId` claim) are still accepted
|
|
18
|
+
* but bypass the session check.
|
|
19
|
+
*
|
|
10
20
|
* Must be used **before** `authorize()` or `permit()`.
|
|
11
21
|
*
|
|
12
|
-
* @param config - Auth configuration
|
|
22
|
+
* @param config - Auth configuration (secret, algorithm, adapter).
|
|
13
23
|
* @returns An Express `RequestHandler` that populates `req.user` on success.
|
|
14
24
|
*
|
|
15
25
|
* @example
|
|
16
|
-
* router.get('/profile', protect(config), (
|
|
17
|
-
*
|
|
26
|
+
* router.get('/profile', protect(config), (request, response) => {
|
|
27
|
+
* response.json(request.user);
|
|
18
28
|
* });
|
|
19
29
|
*/
|
|
20
30
|
export function protect(config) {
|
|
21
|
-
return (request, _response, next) => {
|
|
31
|
+
return async (request, _response, next) => {
|
|
22
32
|
const authHeader = request.headers['authorization'];
|
|
23
33
|
if (!authHeader?.startsWith('Bearer ')) {
|
|
24
34
|
return next(new AuthError('UNAUTHORIZED', 'Missing or malformed Authorization header'));
|
|
25
35
|
}
|
|
26
36
|
const token = authHeader.slice(7);
|
|
27
37
|
try {
|
|
28
|
-
|
|
38
|
+
const payload = verifyAccessToken(token, config);
|
|
39
|
+
request.user = { id: payload.id, identifier: payload.identifier, roles: payload.roles };
|
|
40
|
+
// Session-bound validation: reject the request if the session was revoked (logout).
|
|
41
|
+
if (payload.sessionId) {
|
|
42
|
+
const session = await config.adapter.session.findById(payload.sessionId);
|
|
43
|
+
if (!session) {
|
|
44
|
+
return next(new AuthError('UNAUTHORIZED', 'Session has been revoked'));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
29
47
|
next();
|
|
30
48
|
}
|
|
31
49
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD
|
|
1
|
+
{"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,OAAO,CAAC,MAAkB;IACxC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE,2CAA2C,CAAC,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAuB,CAAC;YACvE,OAAO,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAExF,oFAAoF;YACpF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACzE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -6,10 +6,10 @@ import type { AuthConfig } from '../types/auth.js';
|
|
|
6
6
|
* Mount it once and all routes are ready:
|
|
7
7
|
*
|
|
8
8
|
* ```
|
|
9
|
-
* POST /
|
|
9
|
+
* POST /register — register a new user (protected by X-Api-Key when config.apiKey is set)
|
|
10
10
|
* POST /login — authenticate and get tokens
|
|
11
11
|
* POST /refresh — rotate refresh token
|
|
12
|
-
* POST /logout — invalidate current session
|
|
12
|
+
* POST /logout — invalidate current session; access tokens issued before logout become invalid
|
|
13
13
|
* POST /logout-all — invalidate all sessions for the authenticated user
|
|
14
14
|
* GET /me — return the currently authenticated user
|
|
15
15
|
* POST /users/:userId/roles — assign roles (admin only)
|
|
@@ -20,6 +20,9 @@ import type { AuthConfig } from '../types/auth.js';
|
|
|
20
20
|
* When `cookie` is set in config, the refresh token is stored in an httpOnly
|
|
21
21
|
* cookie automatically — no `cookie-parser` needed.
|
|
22
22
|
*
|
|
23
|
+
* When `apiKey` is set in config, `POST /register` requires the caller to send
|
|
24
|
+
* an `X-Api-Key: <key>` header matching the configured value.
|
|
25
|
+
*
|
|
23
26
|
* When `router` is set in config, individual service functions can be replaced
|
|
24
27
|
* while the router still handles validation and response formatting.
|
|
25
28
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/middleware/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AAEjF,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/middleware/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AAEjF,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,kBAAkB,CAAC;AA+E5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,MAAM,CAwLxF"}
|
|
@@ -56,16 +56,28 @@ function clearCookie(response, config) {
|
|
|
56
56
|
const cookieConfig = config.cookie ?? {};
|
|
57
57
|
response.clearCookie(getCookieName(config), { path: cookieConfig.path ?? '/' });
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Validate the `X-Api-Key` header when `config.apiKey` is set.
|
|
61
|
+
* Throws `AuthError` with code `UNAUTHORIZED` on mismatch.
|
|
62
|
+
*/
|
|
63
|
+
function validateApiKey(request, config) {
|
|
64
|
+
if (!config.apiKey)
|
|
65
|
+
return;
|
|
66
|
+
const provided = request.headers['x-api-key'];
|
|
67
|
+
if (typeof provided !== 'string' || provided !== config.apiKey) {
|
|
68
|
+
throw new AuthError('UNAUTHORIZED', 'Invalid or missing API key');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
59
71
|
/**
|
|
60
72
|
* Creates a pre-built Express Router with all standard auth endpoints.
|
|
61
73
|
*
|
|
62
74
|
* Mount it once and all routes are ready:
|
|
63
75
|
*
|
|
64
76
|
* ```
|
|
65
|
-
* POST /
|
|
77
|
+
* POST /register — register a new user (protected by X-Api-Key when config.apiKey is set)
|
|
66
78
|
* POST /login — authenticate and get tokens
|
|
67
79
|
* POST /refresh — rotate refresh token
|
|
68
|
-
* POST /logout — invalidate current session
|
|
80
|
+
* POST /logout — invalidate current session; access tokens issued before logout become invalid
|
|
69
81
|
* POST /logout-all — invalidate all sessions for the authenticated user
|
|
70
82
|
* GET /me — return the currently authenticated user
|
|
71
83
|
* POST /users/:userId/roles — assign roles (admin only)
|
|
@@ -76,6 +88,9 @@ function clearCookie(response, config) {
|
|
|
76
88
|
* When `cookie` is set in config, the refresh token is stored in an httpOnly
|
|
77
89
|
* cookie automatically — no `cookie-parser` needed.
|
|
78
90
|
*
|
|
91
|
+
* When `apiKey` is set in config, `POST /register` requires the caller to send
|
|
92
|
+
* an `X-Api-Key: <key>` header matching the configured value.
|
|
93
|
+
*
|
|
79
94
|
* When `router` is set in config, individual service functions can be replaced
|
|
80
95
|
* while the router still handles validation and response formatting.
|
|
81
96
|
*
|
|
@@ -87,14 +102,23 @@ export function createAuthRouter(config) {
|
|
|
87
102
|
const router = Router();
|
|
88
103
|
// Resolve service functions — use custom override from config.router when provided, else fall back to the built-in service.
|
|
89
104
|
const baseConfig = config;
|
|
90
|
-
const
|
|
105
|
+
const registerFn = config.router?.register ?? ((input) => signup(input, baseConfig));
|
|
91
106
|
const loginFn = config.router?.login ?? ((input) => login(input, baseConfig));
|
|
92
107
|
const refreshFn = config.router?.refresh ?? ((token) => refresh(token, baseConfig));
|
|
93
108
|
const logoutFn = config.router?.logout ?? ((token) => token !== undefined ? logout(token, baseConfig) : Promise.resolve());
|
|
94
109
|
const logoutAllFn = config.router?.logoutAll ?? ((userId) => logoutAll(userId, baseConfig));
|
|
95
110
|
const assignRolesFn = config.router?.assignRoles ?? ((userId, roles) => assignRoles(userId, roles, baseConfig));
|
|
96
|
-
|
|
111
|
+
/**
|
|
112
|
+
* POST /register
|
|
113
|
+
*
|
|
114
|
+
* Register a new user. Does **not** issue tokens — call `/login` after registration.
|
|
115
|
+
*
|
|
116
|
+
* When `config.apiKey` is set the caller must supply the matching value in the
|
|
117
|
+
* `X-Api-Key` header, preventing arbitrary users from self-registering as admins.
|
|
118
|
+
*/
|
|
119
|
+
router.post('/register', async (request, response, next) => {
|
|
97
120
|
try {
|
|
121
|
+
validateApiKey(request, config);
|
|
98
122
|
const body = parseBody(request.body);
|
|
99
123
|
const { identifier, password, roles } = body;
|
|
100
124
|
if (typeof identifier !== 'string' || identifier.trim().length === 0) {
|
|
@@ -119,7 +143,7 @@ export function createAuthRouter(config) {
|
|
|
119
143
|
const input = rolesInput !== undefined
|
|
120
144
|
? { identifier: identifier.trim(), password, roles: rolesInput }
|
|
121
145
|
: { identifier: identifier.trim(), password };
|
|
122
|
-
const result = await
|
|
146
|
+
const result = await registerFn(input);
|
|
123
147
|
if (!result.success) {
|
|
124
148
|
fail(response, result.error);
|
|
125
149
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/middleware/router.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/middleware/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,6EAA6E;AAC7E,6EAA6E;AAC7E,wCAAwC;AACxC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAElC,SAAS,UAAU,CAAC,OAAe;IACjC,OAAO,IAAI,SAAS,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,EAAE,CAAI,QAAkB,EAAE,UAAkB,EAAE,OAAe,EAAE,IAAO;IAC7E,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,IAAI,CAAC,QAAkB,EAAE,KAAgB;IAChD,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACpG,CAAC;AAED,SAAS,SAAS,CAAC,IAAa;IAC9B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3F,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,6EAA6E,CAAC,CAAC;IACzH,CAAC;IACD,OAAO,IAA+B,CAAC;AACzC,CAAC;AAED,6EAA6E;AAC7E,SAAS,UAAU,CAAC,YAAgC,EAAE,IAAY;IAChE,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,IAAI,GAAG,YAAY;SACtB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SAChC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;IACrD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,SAAS,aAAa,CAAC,MAAkB;IACvC,OAAO,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,eAAe,CAAC;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,QAAkB,EAAE,KAAa,EAAE,MAAkB;IACtE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IACtD,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE;QAC5C,QAAQ,EAAE,YAAY,CAAC,QAAQ,IAAI,IAAI;QACvC,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,KAAK;QACpC,QAAQ,EAAE,YAAY,CAAC,QAAQ,IAAI,QAAQ;QAC3C,IAAI,EAAE,YAAY,CAAC,IAAI,IAAI,GAAG;QAC9B,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,QAAkB,EAAE,MAAkB;IACzD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,OAAgB,EAAE,MAAkB;IAC1D,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/D,MAAM,IAAI,SAAS,CAAC,cAAc,EAAE,4BAA4B,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,gBAAgB,CAAuB,MAAyB;IAC9E,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,4HAA4H;IAC5H,MAAM,UAAU,GAAG,MAAoB,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,IAAI,CAAC,CAAC,KAAkB,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IAClG,MAAM,OAAO,GAAM,MAAM,CAAC,MAAM,EAAE,KAAK,IAAO,CAAC,CAAC,KAAiB,EAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IACjG,MAAM,SAAS,GAAI,MAAM,CAAC,MAAM,EAAE,OAAO,IAAK,CAAC,CAAC,KAAa,EAAO,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IACnG,MAAM,QAAQ,GAAK,MAAM,CAAC,MAAM,EAAE,MAAM,IAAM,CAAC,CAAC,KAAyB,EAAE,EAAE,CAC3E,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACvE,MAAM,WAAW,GAAK,MAAM,CAAC,MAAM,EAAE,SAAS,IAAM,CAAC,CAAC,MAAc,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACxG,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,CAAC,MAAc,EAAE,KAAe,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IAElI;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACzD,IAAI,CAAC;YACH,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAEhC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YAE7C,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrE,MAAM,UAAU,CAAC,uDAAuD,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;gBAC9C,MAAM,UAAU,CAAC,8BAA8B,qBAAqB,aAAa,CAAC,CAAC;YACrF,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;gBAC1E,MAAM,UAAU,CAAC,6CAA6C,mBAAmB,aAAa,CAAC,CAAC;YAClG,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;gBAC1C,MAAM,UAAU,CAAC,4BAA4B,mBAAmB,aAAa,CAAC,CAAC;YACjF,CAAC;YACD,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,MAAM,UAAU,CAAC,iDAAiD,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC7E,MAAM,UAAU,CAAC,4BAA4B,CAAC,CAAC;YACjD,CAAC;YAED,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;YACzE,MAAM,KAAK,GAAG,UAAU,KAAK,SAAS;gBACpC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE;gBAChE,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;YAEvC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YAED,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,8BAA8B,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACtD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;YAEtC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrE,MAAM,UAAU,CAAC,uDAAuD,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;gBAC9C,MAAM,UAAU,CAAC,8BAA8B,qBAAqB,aAAa,CAAC,CAAC;YACrF,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1D,MAAM,UAAU,CAAC,sBAAsB,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;gBAC1C,MAAM,UAAU,CAAC,4BAA4B,mBAAmB,aAAa,CAAC,CAAC;YACjF,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAE1E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YAED,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACjD,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,kBAAkB,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAChG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YAChF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC;YAE3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAC9B,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YAED,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACjD,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,iBAAiB,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACvD,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YAChF,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC3B,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9B,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QAC5E,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,OAAO,CAAC,IAAK,CAAC,EAAE,CAAC,CAAC;YACpC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9B,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,sBAAsB,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QACvD,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAK,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;QACzG,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YACvB,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YAErE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,UAAU,CAAC,oBAAoB,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChD,MAAM,UAAU,CAAC,4CAA4C,CAAC,CAAC;YACjE,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACrD,MAAM,UAAU,CAAC,4BAA4B,CAAC,CAAC;YACjD,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,KAAiB,CAAC,CAAC;YAE9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YAED,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,6BAA6B,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,8EAA8E;IAC9E,MAAM,CAAC,GAAG,CAAC,CAAC,KAAc,EAAE,QAAiB,EAAE,QAAkB,EAAE,KAAmB,EAAE,EAAE;QACxF,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/services/auth.d.ts
CHANGED
|
@@ -19,7 +19,9 @@ export declare function signup(input: SignupInput, config: AuthConfig): Promise<
|
|
|
19
19
|
* Authenticate an existing user by identifier and plain-text password.
|
|
20
20
|
*
|
|
21
21
|
* Looks up the user, verifies the password with bcrypt, creates a new session,
|
|
22
|
-
* and issues a JWT access token + refresh token pair.
|
|
22
|
+
* and issues a JWT access token + refresh token pair. The access token embeds
|
|
23
|
+
* the session ID so that `protect()` can reject it immediately after logout
|
|
24
|
+
* without waiting for the token to expire.
|
|
23
25
|
*
|
|
24
26
|
* The failure response always uses code `INVALID_CREDENTIALS` regardless of
|
|
25
27
|
* whether the identifier or the password was wrong, preventing user enumeration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAExI;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAoBvB;AAED
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAExI;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAoBvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,KAAK,CACzB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,UAAU,CAAC,CAqBrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,OAAO,CAC3B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,aAAa,CAAC,CA+BxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAC1B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,iBAAiB,CAAC,CAiB5B"}
|
package/dist/services/auth.js
CHANGED
|
@@ -38,7 +38,9 @@ export async function signup(input, config) {
|
|
|
38
38
|
* Authenticate an existing user by identifier and plain-text password.
|
|
39
39
|
*
|
|
40
40
|
* Looks up the user, verifies the password with bcrypt, creates a new session,
|
|
41
|
-
* and issues a JWT access token + refresh token pair.
|
|
41
|
+
* and issues a JWT access token + refresh token pair. The access token embeds
|
|
42
|
+
* the session ID so that `protect()` can reject it immediately after logout
|
|
43
|
+
* without waiting for the token to expire.
|
|
42
44
|
*
|
|
43
45
|
* The failure response always uses code `INVALID_CREDENTIALS` regardless of
|
|
44
46
|
* whether the identifier or the password was wrong, preventing user enumeration.
|
|
@@ -61,7 +63,8 @@ export async function login(input, config) {
|
|
|
61
63
|
const expiresAt = new Date(Date.now() + parseExpiry(resolved.refreshExpiresIn));
|
|
62
64
|
const session = await resolved.adapter.session.create({ userId: found.id, expiresAt });
|
|
63
65
|
const user = { id: found.id, identifier: found.identifier, roles: found.roles };
|
|
64
|
-
|
|
66
|
+
// Embed sessionId in the access token so protect() can invalidate it on logout.
|
|
67
|
+
const accessToken = signAccessToken({ ...user, sessionId: session.id }, config);
|
|
65
68
|
const refreshToken = signRefreshToken(session.id, config);
|
|
66
69
|
return { success: true, accessToken, refreshToken, user };
|
|
67
70
|
}
|
|
@@ -103,7 +106,8 @@ export async function refresh(refreshToken, config) {
|
|
|
103
106
|
const expiresAt = new Date(Date.now() + parseExpiry(resolved.refreshExpiresIn));
|
|
104
107
|
const newSession = await resolved.adapter.session.create({ userId: session.userId, expiresAt });
|
|
105
108
|
const user = { id: session.user.id, identifier: session.user.identifier, roles: session.user.roles };
|
|
106
|
-
|
|
109
|
+
// Embed new sessionId in the rotated access token.
|
|
110
|
+
const newAccessToken = signAccessToken({ ...user, sessionId: newSession.id }, config);
|
|
107
111
|
const newRefreshToken = signRefreshToken(newSession.id, config);
|
|
108
112
|
return { success: true, accessToken: newAccessToken, refreshToken: newRefreshToken, user };
|
|
109
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG/D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,KAAkB,EAClB,MAAkB;IAElB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEvC,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IACzC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC,cAAc,EAAE,kBAAkB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IAC/G,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,EAAE,CAAC;IAChG,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IAExG,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IACnE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -7,6 +7,14 @@ export interface ApiResponse<T = null> {
|
|
|
7
7
|
message: string;
|
|
8
8
|
data: T | null;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* @internal Extended JWT payload decoded from an access token.
|
|
12
|
+
* Includes `sessionId` which is not exposed on `req.user` but is used
|
|
13
|
+
* by `protect()` to validate that the session is still active.
|
|
14
|
+
*/
|
|
15
|
+
export interface AccessTokenPayload<TRole extends string = string> extends AuthUser<TRole> {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
}
|
|
10
18
|
/** Maps an {@link AuthErrorCode} to its corresponding HTTP status code. */
|
|
11
19
|
export declare function authErrorStatus(code: AuthErrorCode): number;
|
|
12
20
|
/** Shape of a user row returned by the adapter — used internally by the library. */
|
|
@@ -124,22 +132,22 @@ export interface AuthAdapter {
|
|
|
124
132
|
*/
|
|
125
133
|
export interface RouterHandlers {
|
|
126
134
|
/**
|
|
127
|
-
* Replaces the default
|
|
135
|
+
* Replaces the default register service (`POST /register`).
|
|
128
136
|
*
|
|
129
137
|
* The router validates the request body (identifier, password, roles) first,
|
|
130
138
|
* then calls this function with the parsed input. Must return a `SignupResult`.
|
|
131
|
-
* If omitted, the library's built-in
|
|
139
|
+
* If omitted, the library's built-in registration logic runs instead.
|
|
132
140
|
*
|
|
133
141
|
* @example
|
|
134
|
-
*
|
|
135
|
-
* const result = await
|
|
142
|
+
* register: async (input) => {
|
|
143
|
+
* const result = await defaultRegister(input);
|
|
136
144
|
* if (result.success) {
|
|
137
145
|
* await emailService.sendWelcome(input.identifier);
|
|
138
146
|
* }
|
|
139
147
|
* return result;
|
|
140
148
|
* }
|
|
141
149
|
*/
|
|
142
|
-
|
|
150
|
+
register?: (input: SignupInput) => Promise<SignupResult>;
|
|
143
151
|
/**
|
|
144
152
|
* Replaces the default login service.
|
|
145
153
|
*
|
|
@@ -272,6 +280,28 @@ export interface AuthConfig<TRole extends string = string> {
|
|
|
272
280
|
validRoles: readonly TRole[];
|
|
273
281
|
/** ORM adapter that connects the library to your database. */
|
|
274
282
|
adapter: AuthAdapter;
|
|
283
|
+
/**
|
|
284
|
+
* API key required to call `POST /register`.
|
|
285
|
+
*
|
|
286
|
+
* When set, the `/register` endpoint expects an `X-Api-Key` header whose
|
|
287
|
+
* value matches this string exactly. Requests without the header, or with
|
|
288
|
+
* the wrong value, are rejected with HTTP 401 (`UNAUTHORIZED`).
|
|
289
|
+
*
|
|
290
|
+
* Use this to restrict self-registration — for example, only your own
|
|
291
|
+
* back-office service or admin panel should be able to create new accounts,
|
|
292
|
+
* so you never expose user registration to arbitrary callers.
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* createAuth({
|
|
296
|
+
* // ...
|
|
297
|
+
* apiKey: process.env.REGISTER_API_KEY!,
|
|
298
|
+
* });
|
|
299
|
+
*
|
|
300
|
+
* // Client must send:
|
|
301
|
+
* // POST /auth/register
|
|
302
|
+
* // X-Api-Key: <value of REGISTER_API_KEY>
|
|
303
|
+
*/
|
|
304
|
+
apiKey?: string;
|
|
275
305
|
/**
|
|
276
306
|
* Custom service functions for individual routes in the built-in auth router.
|
|
277
307
|
*
|
|
@@ -286,6 +316,12 @@ export interface AuthConfig<TRole extends string = string> {
|
|
|
286
316
|
* // verify OTP, then delegate to default or return custom result
|
|
287
317
|
* return { success: true, accessToken, refreshToken, user };
|
|
288
318
|
* },
|
|
319
|
+
* register: async (input) => {
|
|
320
|
+
* // send welcome email after successful registration
|
|
321
|
+
* const result = await defaultRegister(input);
|
|
322
|
+
* if (result.success) await emailService.sendWelcome(input.identifier);
|
|
323
|
+
* return result;
|
|
324
|
+
* },
|
|
289
325
|
* },
|
|
290
326
|
* });
|
|
291
327
|
*/
|
|
@@ -294,7 +330,7 @@ export interface AuthConfig<TRole extends string = string> {
|
|
|
294
330
|
* When set, the built-in router (`auth.router()`) stores the refresh token
|
|
295
331
|
* in an httpOnly cookie instead of returning it in the response body.
|
|
296
332
|
*
|
|
297
|
-
* The `refreshToken` field is omitted from `/login`, `/
|
|
333
|
+
* The `refreshToken` field is omitted from `/login`, `/register`, and `/refresh`
|
|
298
334
|
* responses. The `/logout` and `/logout-all` routes automatically clear the cookie.
|
|
299
335
|
*
|
|
300
336
|
* No extra middleware (e.g. `cookie-parser`) is required.
|
|
@@ -339,12 +375,18 @@ export interface CookieConfig {
|
|
|
339
375
|
*/
|
|
340
376
|
path?: string;
|
|
341
377
|
}
|
|
342
|
-
/**
|
|
378
|
+
/**
|
|
379
|
+
* The user payload injected as `req.user` after `protect()` runs.
|
|
380
|
+
*
|
|
381
|
+
* Access tokens issued by sentri >= 1.1.0 embed a `sessionId` that is
|
|
382
|
+
* validated against the database on every request. Tokens from older
|
|
383
|
+
* versions that lack this claim are accepted but bypass session validation.
|
|
384
|
+
*/
|
|
343
385
|
export interface AuthUser<TRole extends string = string> {
|
|
344
386
|
id: string;
|
|
345
387
|
/**
|
|
346
388
|
* The credential identifier for this user (email, username, phone, etc.).
|
|
347
|
-
* Reflects whatever value was passed as `identifier` at
|
|
389
|
+
* Reflects whatever value was passed as `identifier` at registration or login.
|
|
348
390
|
*/
|
|
349
391
|
identifier: string;
|
|
350
392
|
roles: TRole[];
|
package/dist/types/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvE,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,gFAAgF;AAChF,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,IAAI;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;CAChB;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAkB3D;AAID,oFAAoF;AACpF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAID;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE;QACJ;;;;;;WAMG;QACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;QACjE,qEAAqE;QACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;QACjD;;;WAGG;QACH,MAAM,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACtD;;;WAGG;QACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,CAAC;IACF,OAAO,EAAE;QACP;;;WAGG;QACH,MAAM,CAAC,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,IAAI,CAAA;SAAE,GAAG,OAAO,CAAC;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3E;;;WAGG;QACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,aAAa,GAAG;YAAE,IAAI,EAAE,UAAU,CAAA;SAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACpF,sEAAsE;QACtE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACzC,mFAAmF;QACnF,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACjD,CAAC;CACH;AAID;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;;;;;OAeG;IACH,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/types/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAqBA,2EAA2E;AAC3E,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,cAAc,CAAC;QACpB,KAAK,qBAAqB,CAAC;QAC3B,KAAK,eAAe,CAAC;QACrB,KAAK,eAAe;YAClB,OAAO,GAAG,CAAC;QACb,KAAK,WAAW;YACd,OAAO,GAAG,CAAC;QACb,KAAK,gBAAgB;YACnB,OAAO,GAAG,CAAC;QACb,KAAK,qBAAqB;YACxB,OAAO,GAAG,CAAC;QACb,KAAK,qBAAqB;YACxB,OAAO,GAAG,CAAC;QACb;YACE,OAAO,GAAG,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sentri",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Personal auth/authorization library for Express + Postgres",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -49,8 +49,11 @@
|
|
|
49
49
|
"vitest": "^4.1.9"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
+
"@prisma/adapter-pg": "^7.8.0",
|
|
53
|
+
"@prisma/client": "^7.8.0",
|
|
52
54
|
"bcrypt": "^6.0.0",
|
|
53
|
-
"jsonwebtoken": "^9.0.3"
|
|
55
|
+
"jsonwebtoken": "^9.0.3",
|
|
56
|
+
"sentri": "^1.0.6"
|
|
54
57
|
},
|
|
55
58
|
"peerDependencies": {
|
|
56
59
|
"express": ">=4.0.0"
|