sentri 5.0.0 → 5.0.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/README.md +4 -1
- package/dist/adapters/elysia/index.cjs +1 -1
- package/dist/adapters/elysia/index.d.cts +18 -2
- package/dist/adapters/elysia/index.d.ts +18 -2
- package/dist/adapters/elysia/index.js +1 -1
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.d.cts +15 -2
- package/dist/adapters/express/index.d.ts +15 -2
- package/dist/adapters/express/index.js +1 -1
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.d.cts +18 -2
- package/dist/adapters/fastify/index.d.ts +18 -2
- package/dist/adapters/fastify/index.js +1 -1
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.d.cts +18 -2
- package/dist/adapters/hono/index.d.ts +18 -2
- package/dist/adapters/hono/index.js +1 -1
- package/dist/adapters/koa/index.cjs +1 -1
- package/dist/adapters/koa/index.d.cts +18 -2
- package/dist/adapters/koa/index.d.ts +18 -2
- package/dist/adapters/koa/index.js +1 -1
- package/dist/cli.cjs +25 -1
- package/dist/cli.js +25 -1
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.d.cts +2 -340
- package/dist/core/index.d.ts +2 -340
- package/dist/core/index.js +1 -1
- package/dist/index-CVb3-EnK.d.cts +386 -0
- package/dist/index-CVb3-EnK.d.ts +386 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -13,6 +13,9 @@ export const sentriAuth = createAuthExpress<Role>({
|
|
|
13
13
|
// -- Roles ------------------------------------------------------------------
|
|
14
14
|
validRoles: ['admin', 'user'],
|
|
15
15
|
|
|
16
|
+
// -- Identifiers ------------------------------------------------------------
|
|
17
|
+
validIdentifiers: ['email', 'username'],
|
|
18
|
+
|
|
16
19
|
// -- Database ---------------------------------------------------------------
|
|
17
20
|
dialect: new PostgresDialect({
|
|
18
21
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -26,6 +29,9 @@ export const sentriAuth = createAuthExpress<Role>({
|
|
|
26
29
|
saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
|
|
27
30
|
// apiKey: process.env.API_KEY, // uncomment to restrict POST /register
|
|
28
31
|
|
|
32
|
+
// -- Rate Limiting (optional) -----------------------------------------------
|
|
33
|
+
// rateLimit: { maxLoginAttempts: 5, maxRegisterAttempts: 5 },
|
|
34
|
+
|
|
29
35
|
// -- Redis (optional) -------------------------------------------------------
|
|
30
36
|
// redisUrl: process.env.REDIS_URL,
|
|
31
37
|
|
|
@@ -61,6 +67,9 @@ export const sentriAuth = createAuthFastify<Role>({
|
|
|
61
67
|
// -- Roles ------------------------------------------------------------------
|
|
62
68
|
validRoles: ['admin', 'user'],
|
|
63
69
|
|
|
70
|
+
// -- Identifiers ------------------------------------------------------------
|
|
71
|
+
validIdentifiers: ['email', 'username'],
|
|
72
|
+
|
|
64
73
|
// -- Database ---------------------------------------------------------------
|
|
65
74
|
dialect: new PostgresDialect({
|
|
66
75
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -74,6 +83,9 @@ export const sentriAuth = createAuthFastify<Role>({
|
|
|
74
83
|
saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
|
|
75
84
|
// apiKey: process.env.API_KEY,
|
|
76
85
|
|
|
86
|
+
// -- Rate Limiting (optional) -----------------------------------------------
|
|
87
|
+
// rateLimit: { maxLoginAttempts: 5, maxRegisterAttempts: 5 },
|
|
88
|
+
|
|
77
89
|
// -- Redis (optional) -------------------------------------------------------
|
|
78
90
|
// redisUrl: process.env.REDIS_URL,
|
|
79
91
|
|
|
@@ -109,6 +121,9 @@ export const sentriAuth = createAuthHono<Role>({
|
|
|
109
121
|
// -- Roles ------------------------------------------------------------------
|
|
110
122
|
validRoles: ['admin', 'user'],
|
|
111
123
|
|
|
124
|
+
// -- Identifiers ------------------------------------------------------------
|
|
125
|
+
validIdentifiers: ['email', 'username'],
|
|
126
|
+
|
|
112
127
|
// -- Database ---------------------------------------------------------------
|
|
113
128
|
dialect: new PostgresDialect({
|
|
114
129
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -122,6 +137,9 @@ export const sentriAuth = createAuthHono<Role>({
|
|
|
122
137
|
saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
|
|
123
138
|
// apiKey: process.env.API_KEY,
|
|
124
139
|
|
|
140
|
+
// -- Rate Limiting (optional) -----------------------------------------------
|
|
141
|
+
// rateLimit: { maxLoginAttempts: 5, maxRegisterAttempts: 5 },
|
|
142
|
+
|
|
125
143
|
// -- Redis (optional) -------------------------------------------------------
|
|
126
144
|
// redisUrl: process.env.REDIS_URL,
|
|
127
145
|
|
|
@@ -157,6 +175,9 @@ export const sentriAuth = createAuthElysia<Role>({
|
|
|
157
175
|
// -- Roles ------------------------------------------------------------------
|
|
158
176
|
validRoles: ['admin', 'user'],
|
|
159
177
|
|
|
178
|
+
// -- Identifiers ------------------------------------------------------------
|
|
179
|
+
validIdentifiers: ['email', 'username'],
|
|
180
|
+
|
|
160
181
|
// -- Database ---------------------------------------------------------------
|
|
161
182
|
dialect: new PostgresDialect({
|
|
162
183
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -183,6 +204,9 @@ export const sentriAuth = createAuthKoa<Role>({
|
|
|
183
204
|
// -- Roles ------------------------------------------------------------------
|
|
184
205
|
validRoles: ['admin', 'user'],
|
|
185
206
|
|
|
207
|
+
// -- Identifiers ------------------------------------------------------------
|
|
208
|
+
validIdentifiers: ['email', 'username'],
|
|
209
|
+
|
|
186
210
|
// -- Database ---------------------------------------------------------------
|
|
187
211
|
dialect: new PostgresDialect({
|
|
188
212
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -511,4 +535,4 @@ Examples:
|
|
|
511
535
|
npx sentri init client hono \u2192 client mode, hono adapter
|
|
512
536
|
`);}s(c,"help");async function l(e,o,t){if(fs.existsSync(e)){console.log(` skip ${t} (already exists)`);return}await promises.writeFile(e,o,"utf8"),console.log(` create ${t}`);}s(l,"writeIfNotExists");async function S(e,o){let t=["server","client"],i=["express","fastify","hono","elysia","koa"];t.includes(e)||(console.error(`Unknown mode: "${e}". Valid modes: ${t.join(", ")}`),process.exit(1)),i.includes(o)||(console.error(`Unknown adapter: "${o}". Valid adapters: ${i.join(", ")}`),process.exit(1));let a=process.cwd(),p=path.join(a,"src","lib");await promises.mkdir(p,{recursive:true});let u=g[e][o],d=e==="server"?A:R,m=E[e][o];console.log(`
|
|
513
537
|
Generating sentri ${e} mode files (${o})...
|
|
514
|
-
`),await l(path.join(p,"sentri.ts"),u,"src/lib/sentri.ts"),await l(path.join(a,".env.example"),d,".env.example"),console.log(m);}s(S,"init");var x=process.argv.slice(2),[r,k
|
|
538
|
+
`),await l(path.join(p,"sentri.ts"),u,"src/lib/sentri.ts"),await l(path.join(a,".env.example"),d,".env.example"),console.log(m);}s(S,"init");var x=process.argv.slice(2),[r,I,k]=x;(!r||r==="--help"||r==="-h")&&(c(),process.exit(0));r==="init"?S(I??"server",k??"express").catch(t=>{console.error(t),process.exit(1);}):(console.error(`Unknown command: ${r}`),c(),process.exit(1));
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,9 @@ export const sentriAuth = createAuthExpress<Role>({
|
|
|
13
13
|
// -- Roles ------------------------------------------------------------------
|
|
14
14
|
validRoles: ['admin', 'user'],
|
|
15
15
|
|
|
16
|
+
// -- Identifiers ------------------------------------------------------------
|
|
17
|
+
validIdentifiers: ['email', 'username'],
|
|
18
|
+
|
|
16
19
|
// -- Database ---------------------------------------------------------------
|
|
17
20
|
dialect: new PostgresDialect({
|
|
18
21
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -26,6 +29,9 @@ export const sentriAuth = createAuthExpress<Role>({
|
|
|
26
29
|
saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
|
|
27
30
|
// apiKey: process.env.API_KEY, // uncomment to restrict POST /register
|
|
28
31
|
|
|
32
|
+
// -- Rate Limiting (optional) -----------------------------------------------
|
|
33
|
+
// rateLimit: { maxLoginAttempts: 5, maxRegisterAttempts: 5 },
|
|
34
|
+
|
|
29
35
|
// -- Redis (optional) -------------------------------------------------------
|
|
30
36
|
// redisUrl: process.env.REDIS_URL,
|
|
31
37
|
|
|
@@ -61,6 +67,9 @@ export const sentriAuth = createAuthFastify<Role>({
|
|
|
61
67
|
// -- Roles ------------------------------------------------------------------
|
|
62
68
|
validRoles: ['admin', 'user'],
|
|
63
69
|
|
|
70
|
+
// -- Identifiers ------------------------------------------------------------
|
|
71
|
+
validIdentifiers: ['email', 'username'],
|
|
72
|
+
|
|
64
73
|
// -- Database ---------------------------------------------------------------
|
|
65
74
|
dialect: new PostgresDialect({
|
|
66
75
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -74,6 +83,9 @@ export const sentriAuth = createAuthFastify<Role>({
|
|
|
74
83
|
saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
|
|
75
84
|
// apiKey: process.env.API_KEY,
|
|
76
85
|
|
|
86
|
+
// -- Rate Limiting (optional) -----------------------------------------------
|
|
87
|
+
// rateLimit: { maxLoginAttempts: 5, maxRegisterAttempts: 5 },
|
|
88
|
+
|
|
77
89
|
// -- Redis (optional) -------------------------------------------------------
|
|
78
90
|
// redisUrl: process.env.REDIS_URL,
|
|
79
91
|
|
|
@@ -109,6 +121,9 @@ export const sentriAuth = createAuthHono<Role>({
|
|
|
109
121
|
// -- Roles ------------------------------------------------------------------
|
|
110
122
|
validRoles: ['admin', 'user'],
|
|
111
123
|
|
|
124
|
+
// -- Identifiers ------------------------------------------------------------
|
|
125
|
+
validIdentifiers: ['email', 'username'],
|
|
126
|
+
|
|
112
127
|
// -- Database ---------------------------------------------------------------
|
|
113
128
|
dialect: new PostgresDialect({
|
|
114
129
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -122,6 +137,9 @@ export const sentriAuth = createAuthHono<Role>({
|
|
|
122
137
|
saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
|
|
123
138
|
// apiKey: process.env.API_KEY,
|
|
124
139
|
|
|
140
|
+
// -- Rate Limiting (optional) -----------------------------------------------
|
|
141
|
+
// rateLimit: { maxLoginAttempts: 5, maxRegisterAttempts: 5 },
|
|
142
|
+
|
|
125
143
|
// -- Redis (optional) -------------------------------------------------------
|
|
126
144
|
// redisUrl: process.env.REDIS_URL,
|
|
127
145
|
|
|
@@ -157,6 +175,9 @@ export const sentriAuth = createAuthElysia<Role>({
|
|
|
157
175
|
// -- Roles ------------------------------------------------------------------
|
|
158
176
|
validRoles: ['admin', 'user'],
|
|
159
177
|
|
|
178
|
+
// -- Identifiers ------------------------------------------------------------
|
|
179
|
+
validIdentifiers: ['email', 'username'],
|
|
180
|
+
|
|
160
181
|
// -- Database ---------------------------------------------------------------
|
|
161
182
|
dialect: new PostgresDialect({
|
|
162
183
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -183,6 +204,9 @@ export const sentriAuth = createAuthKoa<Role>({
|
|
|
183
204
|
// -- Roles ------------------------------------------------------------------
|
|
184
205
|
validRoles: ['admin', 'user'],
|
|
185
206
|
|
|
207
|
+
// -- Identifiers ------------------------------------------------------------
|
|
208
|
+
validIdentifiers: ['email', 'username'],
|
|
209
|
+
|
|
186
210
|
// -- Database ---------------------------------------------------------------
|
|
187
211
|
dialect: new PostgresDialect({
|
|
188
212
|
pool: new Pool({ connectionString: process.env.DATABASE_URL! })
|
|
@@ -511,4 +535,4 @@ Examples:
|
|
|
511
535
|
npx sentri init client hono \u2192 client mode, hono adapter
|
|
512
536
|
`);}s(c,"help");async function l(e,o,t){if(existsSync(e)){console.log(` skip ${t} (already exists)`);return}await writeFile(e,o,"utf8"),console.log(` create ${t}`);}s(l,"writeIfNotExists");async function S(e,o){let t=["server","client"],i=["express","fastify","hono","elysia","koa"];t.includes(e)||(console.error(`Unknown mode: "${e}". Valid modes: ${t.join(", ")}`),process.exit(1)),i.includes(o)||(console.error(`Unknown adapter: "${o}". Valid adapters: ${i.join(", ")}`),process.exit(1));let a=process.cwd(),p=join(a,"src","lib");await mkdir(p,{recursive:true});let u=g[e][o],d=e==="server"?A:R,m=E[e][o];console.log(`
|
|
513
537
|
Generating sentri ${e} mode files (${o})...
|
|
514
|
-
`),await l(join(p,"sentri.ts"),u,"src/lib/sentri.ts"),await l(join(a,".env.example"),d,".env.example"),console.log(m);}s(S,"init");var x=process.argv.slice(2),[r,k
|
|
538
|
+
`),await l(join(p,"sentri.ts"),u,"src/lib/sentri.ts"),await l(join(a,".env.example"),d,".env.example"),console.log(m);}s(S,"init");var x=process.argv.slice(2),[r,I,k]=x;(!r||r==="--help"||r==="-h")&&(c(),process.exit(0));r==="init"?S(I??"server",k??"express").catch(t=>{console.error(t),process.exit(1);}):(console.error(`Unknown command: ${r}`),c(),process.exit(1));
|
package/dist/core/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var t=Object.defineProperty;var
|
|
1
|
+
'use strict';var t=Object.defineProperty;var T=(I,E)=>t(I,"name",{value:E,configurable:true});var _=Object.assign(Object.create(null),{UNAUTHORIZED:401,TOKEN_EXPIRED:401,TOKEN_INVALID:401,INVALID_CREDENTIALS:401,FORBIDDEN:403,USER_NOT_FOUND:404,IDENTIFIER_NOT_FOUND:404,USER_ALREADY_EXISTS:409,IDENTIFIER_ALREADY_EXISTS:409,INVALID_ROLE:400,VALIDATION_ERROR:400,CONFIGURATION_ERROR:500,TOKEN_REUSE:401,RATE_LIMIT_EXCEEDED:429}),R=class extends Error{static{T(this,"SentriError");}code;statusCode;constructor(E,N,O){super(N),this.name="SentriError",this.code=E,this.statusCode=O??_[E]??500;}};exports.SENTRI_ERROR_STATUS=_;exports.SentriError=R;
|
package/dist/core/index.d.cts
CHANGED
|
@@ -1,340 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Discriminant codes for built-in {@link SentriError} instances.
|
|
5
|
-
*
|
|
6
|
-
* - `INVALID_CREDENTIALS` — identifier or password did not match (intentionally vague to prevent user enumeration)
|
|
7
|
-
* - `USER_NOT_FOUND` — an operation required a user that does not exist
|
|
8
|
-
* - `USER_ALREADY_EXISTS` — registration was attempted with an identifier already in the database
|
|
9
|
-
* - `IDENTIFIER_NOT_FOUND` — a referenced identifier ID does not exist or does not belong to the user
|
|
10
|
-
* - `IDENTIFIER_ALREADY_EXISTS` — the identifier value is already taken by another user
|
|
11
|
-
* - `TOKEN_EXPIRED` — the JWT was valid but its `exp` claim is in the past
|
|
12
|
-
* - `TOKEN_INVALID` — the JWT could not be verified (bad signature, malformed, wrong type)
|
|
13
|
-
* - `FORBIDDEN` — the user is authenticated but lacks the required role
|
|
14
|
-
* - `UNAUTHORIZED` — no valid access token was present on the request, or the session was revoked
|
|
15
|
-
* - `INVALID_ROLE` — a role name was used that is not in `validRoles`
|
|
16
|
-
* - `VALIDATION_ERROR` — a required field was missing or had an invalid value
|
|
17
|
-
* - `CONFIGURATION_ERROR` — `createAuth` was called with an invalid configuration
|
|
18
|
-
*
|
|
19
|
-
* When you extend {@link SentriError} for your own error types you can use any
|
|
20
|
-
* string as `code` — it does not need to be one of these built-in values.
|
|
21
|
-
*/
|
|
22
|
-
type SentriErrorCode = 'INVALID_CREDENTIALS' | 'USER_NOT_FOUND' | 'USER_ALREADY_EXISTS' | 'IDENTIFIER_NOT_FOUND' | 'IDENTIFIER_ALREADY_EXISTS' | 'TOKEN_EXPIRED' | 'TOKEN_INVALID' | 'FORBIDDEN' | 'UNAUTHORIZED' | 'INVALID_ROLE' | 'VALIDATION_ERROR' | 'CONFIGURATION_ERROR' | 'TOKEN_REUSE';
|
|
23
|
-
/**
|
|
24
|
-
* Default HTTP status codes for built-in error codes.
|
|
25
|
-
* Custom codes not in this map default to 500.
|
|
26
|
-
*
|
|
27
|
-
* @internal
|
|
28
|
-
*/
|
|
29
|
-
declare const SENTRI_ERROR_STATUS: Record<string, number>;
|
|
30
|
-
/**
|
|
31
|
-
* Base error class for all authentication and authorization failures in sentri.
|
|
32
|
-
*
|
|
33
|
-
* Every error thrown by sentri is an instance of `SentriError`. The `code`
|
|
34
|
-
* property is a machine-readable string that lets you distinguish error
|
|
35
|
-
* types without string-matching on the message. Built-in codes are listed
|
|
36
|
-
* in {@link SentriErrorCode}; custom subclasses may use any string.
|
|
37
|
-
*
|
|
38
|
-
* The `statusCode` property holds the HTTP status that the built-in router
|
|
39
|
-
* and `auth.errorHandler()` will use in the response. For built-in codes
|
|
40
|
-
* it is derived automatically. Pass it explicitly when subclassing with a
|
|
41
|
-
* custom code.
|
|
42
|
-
*
|
|
43
|
-
* ---
|
|
44
|
-
*
|
|
45
|
-
* **Extending SentriError**
|
|
46
|
-
*
|
|
47
|
-
* You can create application-specific error classes by extending `SentriError`.
|
|
48
|
-
* Any subclass will be caught automatically by `auth.errorHandler()` because
|
|
49
|
-
* `instanceof SentriError` is `true` for all subclasses.
|
|
50
|
-
*
|
|
51
|
-
* ```typescript
|
|
52
|
-
* import { SentriError } from 'sentri';
|
|
53
|
-
*
|
|
54
|
-
* export class PaymentError extends SentriError {
|
|
55
|
-
* constructor(message: string) {
|
|
56
|
-
* super('PAYMENT_FAILED', message, 402);
|
|
57
|
-
* }
|
|
58
|
-
* }
|
|
59
|
-
*
|
|
60
|
-
* router.post('/checkout', auth.protect(), async (req, res) => {
|
|
61
|
-
* const ok = await chargeCard(req.body.cardToken);
|
|
62
|
-
* if (!ok) throw new PaymentError('Card declined');
|
|
63
|
-
* res.json({ success: true });
|
|
64
|
-
* });
|
|
65
|
-
* ```
|
|
66
|
-
*
|
|
67
|
-
* ---
|
|
68
|
-
*
|
|
69
|
-
* **Error handling in custom routes**
|
|
70
|
-
*
|
|
71
|
-
* ```typescript
|
|
72
|
-
* app.use('/auth', auth.router());
|
|
73
|
-
* app.use('/api', apiRouter);
|
|
74
|
-
*
|
|
75
|
-
* // Mount after all routes — catches SentriError from sentri AND your subclasses
|
|
76
|
-
* app.use(auth.errorHandler());
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
declare class SentriError extends Error {
|
|
80
|
-
/**
|
|
81
|
-
* Machine-readable error code.
|
|
82
|
-
* Built-in codes are defined by {@link SentriErrorCode}.
|
|
83
|
-
* Custom subclasses may use any string.
|
|
84
|
-
*/
|
|
85
|
-
readonly code: string;
|
|
86
|
-
/**
|
|
87
|
-
* HTTP status code associated with this error.
|
|
88
|
-
* Derived automatically for built-in codes; pass it explicitly when
|
|
89
|
-
* subclassing with a custom `code`.
|
|
90
|
-
*/
|
|
91
|
-
readonly statusCode: number;
|
|
92
|
-
constructor(code: SentriErrorCode | (string & {}), message: string, statusCode?: number);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Minimal structured logger interface accepted by Sentri.
|
|
97
|
-
*
|
|
98
|
-
* Compatible out-of-the-box with **pino**, **winston**, and **console** — all
|
|
99
|
-
* three expose `info`, `warn`, and `error` methods that accept an object argument.
|
|
100
|
-
*
|
|
101
|
-
* Pass an instance via `logger` in `ServerAuthConfig` or `ClientAuthConfig`.
|
|
102
|
-
* When omitted, Sentri produces no log output (no-op default).
|
|
103
|
-
*
|
|
104
|
-
* Each call receives a plain `Record<string, unknown>` containing structured
|
|
105
|
-
* fields — never a pre-formatted string — so your logger controls serialisation,
|
|
106
|
-
* output destination, and timestamp format.
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* // pino
|
|
110
|
-
* import pino from 'pino';
|
|
111
|
-
* const auth = createAuth({ ..., logger: pino() });
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* // winston
|
|
115
|
-
* import winston from 'winston';
|
|
116
|
-
* const auth = createAuth({ ..., logger: winston.createLogger({ ... }) });
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* // console (zero setup, useful for development)
|
|
120
|
-
* const auth = createAuth({ ..., logger: console });
|
|
121
|
-
*/
|
|
122
|
-
interface SentriLogger {
|
|
123
|
-
info(data: Record<string, unknown>): void;
|
|
124
|
-
warn(data: Record<string, unknown>): void;
|
|
125
|
-
error(data: Record<string, unknown>): void;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
interface ApiResponse<T = null> {
|
|
129
|
-
error: boolean;
|
|
130
|
-
statusCode: number;
|
|
131
|
-
message: string;
|
|
132
|
-
data: T | null;
|
|
133
|
-
}
|
|
134
|
-
/** A single identifier entry belonging to a user. */
|
|
135
|
-
interface IdentifierRecord {
|
|
136
|
-
id: string;
|
|
137
|
-
type: string;
|
|
138
|
-
value: string;
|
|
139
|
-
}
|
|
140
|
-
/** The authenticated user shape embedded in JWT payloads and middleware context. */
|
|
141
|
-
interface AuthUser<TRole extends string = string> {
|
|
142
|
-
id: string;
|
|
143
|
-
roles: TRole[];
|
|
144
|
-
/** All identifiers for this user. Only present in full user responses, not in JWT. */
|
|
145
|
-
identifiers?: IdentifierRecord[];
|
|
146
|
-
}
|
|
147
|
-
/** Input for a single identifier entry. */
|
|
148
|
-
interface IdentifierInput {
|
|
149
|
-
/** Arbitrary label such as 'email', 'username', or 'phone'. */
|
|
150
|
-
type: string;
|
|
151
|
-
/** The globally unique identifier value. */
|
|
152
|
-
value: string;
|
|
153
|
-
}
|
|
154
|
-
type RegisterResult<TRole extends string = string> = {
|
|
155
|
-
success: true;
|
|
156
|
-
user: AuthUser<TRole>;
|
|
157
|
-
} | {
|
|
158
|
-
success: false;
|
|
159
|
-
error: SentriError;
|
|
160
|
-
};
|
|
161
|
-
type AuthResult<TRole extends string = string> = {
|
|
162
|
-
success: true;
|
|
163
|
-
accessToken: string;
|
|
164
|
-
refreshToken: string;
|
|
165
|
-
user: AuthUser<TRole>;
|
|
166
|
-
} | {
|
|
167
|
-
success: false;
|
|
168
|
-
error: SentriError;
|
|
169
|
-
};
|
|
170
|
-
type AssignRolesResult<TRole extends string = string> = {
|
|
171
|
-
success: true;
|
|
172
|
-
user: AuthUser<TRole>;
|
|
173
|
-
} | {
|
|
174
|
-
success: false;
|
|
175
|
-
error: SentriError;
|
|
176
|
-
};
|
|
177
|
-
type GetUserResult<TRole extends string = string> = {
|
|
178
|
-
success: true;
|
|
179
|
-
user: AuthUser<TRole>;
|
|
180
|
-
} | {
|
|
181
|
-
success: false;
|
|
182
|
-
error: SentriError;
|
|
183
|
-
};
|
|
184
|
-
type BulkIdentifiersResult = {
|
|
185
|
-
success: true;
|
|
186
|
-
identifiers: IdentifierRecord[];
|
|
187
|
-
} | {
|
|
188
|
-
success: false;
|
|
189
|
-
error: SentriError;
|
|
190
|
-
};
|
|
191
|
-
type ChangePasswordResult = {
|
|
192
|
-
success: true;
|
|
193
|
-
} | {
|
|
194
|
-
success: false;
|
|
195
|
-
error: SentriError;
|
|
196
|
-
};
|
|
197
|
-
type RefreshResult<TRole extends string = string> = {
|
|
198
|
-
success: true;
|
|
199
|
-
accessToken: string;
|
|
200
|
-
refreshToken: string;
|
|
201
|
-
user: AuthUser<TRole>;
|
|
202
|
-
} | {
|
|
203
|
-
success: false;
|
|
204
|
-
error: SentriError;
|
|
205
|
-
};
|
|
206
|
-
interface RegisterInput<TRole extends string = string> {
|
|
207
|
-
/** One or more identifiers for the new user. All values must be globally unique. */
|
|
208
|
-
identifiers: IdentifierInput[];
|
|
209
|
-
password: string;
|
|
210
|
-
roles?: TRole[];
|
|
211
|
-
}
|
|
212
|
-
interface LoginInput {
|
|
213
|
-
/** Any of the user's identifier values — Sentri searches all types. */
|
|
214
|
-
identifier: string;
|
|
215
|
-
password: string;
|
|
216
|
-
}
|
|
217
|
-
interface CookieConfig {
|
|
218
|
-
name?: string;
|
|
219
|
-
httpOnly?: boolean;
|
|
220
|
-
secure?: boolean;
|
|
221
|
-
sameSite?: 'strict' | 'lax' | 'none';
|
|
222
|
-
path?: string;
|
|
223
|
-
}
|
|
224
|
-
interface AccessCookieConfig {
|
|
225
|
-
name?: string;
|
|
226
|
-
secure?: boolean;
|
|
227
|
-
sameSite?: 'strict' | 'lax' | 'none';
|
|
228
|
-
path?: string;
|
|
229
|
-
}
|
|
230
|
-
interface AuthHooks {
|
|
231
|
-
onRegister?: (user: AuthUser) => void | Promise<void>;
|
|
232
|
-
onLoginSuccess?: (user: AuthUser, meta: {
|
|
233
|
-
ip: string;
|
|
234
|
-
userAgent: string;
|
|
235
|
-
}) => void | Promise<void>;
|
|
236
|
-
onLoginFailed?: (identifier: string, error: SentriError, meta: {
|
|
237
|
-
ip: string;
|
|
238
|
-
}) => void | Promise<void>;
|
|
239
|
-
onPasswordChanged?: (userId: string) => void | Promise<void>;
|
|
240
|
-
onLogout?: (userId: string) => void | Promise<void>;
|
|
241
|
-
}
|
|
242
|
-
interface RateLimitOptions {
|
|
243
|
-
maxLoginAttempts?: number;
|
|
244
|
-
maxRegisterAttempts?: number;
|
|
245
|
-
}
|
|
246
|
-
interface RouterHandlers {
|
|
247
|
-
register?: (input: RegisterInput, meta: {
|
|
248
|
-
ip: string;
|
|
249
|
-
userAgent: string;
|
|
250
|
-
}) => Promise<RegisterResult>;
|
|
251
|
-
login?: (input: LoginInput, meta: {
|
|
252
|
-
ip: string;
|
|
253
|
-
userAgent: string;
|
|
254
|
-
}) => Promise<AuthResult>;
|
|
255
|
-
refresh?: (refreshToken: string, meta: {
|
|
256
|
-
ip: string;
|
|
257
|
-
userAgent: string;
|
|
258
|
-
}) => Promise<RefreshResult>;
|
|
259
|
-
logout?: (refreshToken: string | undefined) => Promise<void>;
|
|
260
|
-
logoutAll?: (userId: string) => Promise<void>;
|
|
261
|
-
getUser?: (userId: string) => Promise<GetUserResult>;
|
|
262
|
-
assignRoles?: (userId: string, roles: string[]) => Promise<AssignRolesResult>;
|
|
263
|
-
bulkCreateIdentifiers?: (userId: string, identifiers: IdentifierInput[]) => Promise<BulkIdentifiersResult>;
|
|
264
|
-
bulkUpdateIdentifiers?: (userId: string, updates: Array<{
|
|
265
|
-
id: string;
|
|
266
|
-
type: string;
|
|
267
|
-
value: string;
|
|
268
|
-
}>) => Promise<BulkIdentifiersResult>;
|
|
269
|
-
bulkDeleteIdentifiers?: (userId: string, ids: string[]) => Promise<BulkIdentifiersResult>;
|
|
270
|
-
changePassword?: (userId: string, currentPassword: string, newPassword: string) => Promise<ChangePasswordResult>;
|
|
271
|
-
getSessions?: (userId: string) => Promise<any>;
|
|
272
|
-
revokeSession?: (userId: string, sessionId: string) => Promise<void>;
|
|
273
|
-
}
|
|
274
|
-
interface ServerAuthConfig<TRole extends string = string> {
|
|
275
|
-
mode: 'server';
|
|
276
|
-
/** Kysely Dialect (e.g. PostgresDialect, MysqlDialect, SqliteDialect). */
|
|
277
|
-
dialect: Dialect;
|
|
278
|
-
/**
|
|
279
|
-
* JWT signing secret.
|
|
280
|
-
* - HS256/HS384/HS512: plain string, minimum 32 characters.
|
|
281
|
-
* - RS256/RS384/RS512: RSA private key in PEM format.
|
|
282
|
-
*/
|
|
283
|
-
secret: string;
|
|
284
|
-
/**
|
|
285
|
-
* JWT signing algorithm.
|
|
286
|
-
* Use RS256/RS384/RS512 to enable the GET /keys endpoint for SSO.
|
|
287
|
-
* @default 'HS256'
|
|
288
|
-
*/
|
|
289
|
-
algorithm?: 'HS256' | 'HS384' | 'HS512' | 'RS256' | 'RS384' | 'RS512';
|
|
290
|
-
validRoles: readonly TRole[];
|
|
291
|
-
/** @default '15m' */
|
|
292
|
-
accessExpiresIn?: string | number;
|
|
293
|
-
/** @default '7d' */
|
|
294
|
-
refreshExpiresIn?: string | number;
|
|
295
|
-
/** @default 12 */
|
|
296
|
-
saltRounds?: number;
|
|
297
|
-
apiKey?: string;
|
|
298
|
-
cookie?: CookieConfig;
|
|
299
|
-
accessCookie?: AccessCookieConfig;
|
|
300
|
-
hooks?: AuthHooks;
|
|
301
|
-
router?: RouterHandlers;
|
|
302
|
-
isTokenRevoked?: (sessionId: string) => boolean | Promise<boolean>;
|
|
303
|
-
rateLimit?: RateLimitOptions | boolean;
|
|
304
|
-
/**
|
|
305
|
-
* Redis connection URL (e.g. `redis://localhost:6379`).
|
|
306
|
-
* When set, `auth.idempotencyMiddleware()` uses Redis as the cache backend
|
|
307
|
-
* instead of an in-memory Map — required for multi-process deployments.
|
|
308
|
-
*/
|
|
309
|
-
redisUrl?: string;
|
|
310
|
-
/**
|
|
311
|
-
* Structured logger instance. Compatible with pino, winston, or console.
|
|
312
|
-
* When omitted, Sentri produces no log output.
|
|
313
|
-
*/
|
|
314
|
-
logger?: SentriLogger;
|
|
315
|
-
/**
|
|
316
|
-
* Service name embedded in every log entry.
|
|
317
|
-
* @default 'sentri'
|
|
318
|
-
*/
|
|
319
|
-
loggerService?: string;
|
|
320
|
-
}
|
|
321
|
-
interface ClientAuthConfig<TRole extends string = string> {
|
|
322
|
-
mode: 'client';
|
|
323
|
-
/** URL of the auth server's public key endpoint (e.g. https://auth.myapp.com/auth/keys). */
|
|
324
|
-
keyUri: string;
|
|
325
|
-
/** Optional — only needed for TypeScript type safety on authorize(). */
|
|
326
|
-
validRoles?: readonly TRole[];
|
|
327
|
-
/**
|
|
328
|
-
* Structured logger instance. Compatible with pino, winston, or console.
|
|
329
|
-
* When omitted, Sentri produces no log output.
|
|
330
|
-
*/
|
|
331
|
-
logger?: SentriLogger;
|
|
332
|
-
/**
|
|
333
|
-
* Service name embedded in every log entry.
|
|
334
|
-
* @default 'sentri'
|
|
335
|
-
*/
|
|
336
|
-
loggerService?: string;
|
|
337
|
-
}
|
|
338
|
-
type AuthConfig<TRole extends string = string> = ServerAuthConfig<TRole> | ClientAuthConfig<TRole>;
|
|
339
|
-
|
|
340
|
-
export { type AccessCookieConfig, type ApiResponse, type AssignRolesResult, type AuthConfig, type AuthHooks, type AuthResult, type AuthUser, type BulkIdentifiersResult, type ChangePasswordResult, type ClientAuthConfig, type CookieConfig, type GetUserResult, type IdentifierInput, type IdentifierRecord, type LoginInput, type RefreshResult, type RegisterInput, type RegisterResult, type RouterHandlers, SENTRI_ERROR_STATUS, SentriError, type SentriErrorCode, type SentriLogger, type ServerAuthConfig };
|
|
1
|
+
export { c as AccessCookieConfig, n as ApiResponse, k as AssignRolesResult, a as AuthConfig, d as AuthHooks, h as AuthResult, A as AuthUser, B as BulkIdentifiersResult, j as ChangePasswordResult, o as ClientAuthConfig, C as CookieConfig, G as GetUserResult, I as IdentifierInput, p as IdentifierRecord, L as LoginInput, i as RefreshResult, f as RegisterInput, g as RegisterResult, R as RouterHandlers, l as SENTRI_ERROR_STATUS, m as SentriError, q as SentriErrorCode, S as SentriLogger, b as ServerAuthConfig } from '../index-CVb3-EnK.cjs';
|
|
2
|
+
import 'kysely';
|