sentri 4.1.1 → 5.0.1

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/dist/cli.js CHANGED
@@ -1,14 +1,25 @@
1
1
  #!/usr/bin/env node
2
- import {mkdir,writeFile}from'fs/promises';import {existsSync}from'fs';import {join}from'path';var u=`import { createAuthServer } from 'sentri';
2
+ import {mkdir,writeFile}from'fs/promises';import {existsSync}from'fs';import {join}from'path';var y=Object.defineProperty;var s=(e,o)=>y(e,"name",{value:o,configurable:true});var g={server:{express:`import { createAuthExpress } from 'sentri/express';
3
+ import { PostgresDialect } from 'kysely';
4
+ import pg from 'pg';
5
+
6
+ const { Pool } = pg;
3
7
 
4
8
  type Role = 'admin' | 'user';
5
9
 
6
- export const sentriAuth = createAuthServer<Role>({
10
+ export const sentriAuth = createAuthExpress<Role>({
11
+ mode: 'server',
12
+
7
13
  // -- Roles ------------------------------------------------------------------
8
14
  validRoles: ['admin', 'user'],
9
15
 
16
+ // -- Identifiers ------------------------------------------------------------
17
+ validIdentifiers: ['email', 'username'],
18
+
10
19
  // -- Database ---------------------------------------------------------------
11
- db: { connectionString: process.env.DATABASE_URL! },
20
+ dialect: new PostgresDialect({
21
+ pool: new Pool({ connectionString: process.env.DATABASE_URL! })
22
+ }),
12
23
 
13
24
  // -- Token ------------------------------------------------------------------
14
25
  accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
@@ -19,16 +30,16 @@ export const sentriAuth = createAuthServer<Role>({
19
30
  // apiKey: process.env.API_KEY, // uncomment to restrict POST /register
20
31
 
21
32
  // -- Redis (optional) -------------------------------------------------------
22
- // redisUrl: process.env.REDIS_URL, // uncomment to enable distributed idempotency cache
33
+ // redisUrl: process.env.REDIS_URL,
23
34
 
24
35
  // -- Cookie (optional) ------------------------------------------------------
25
- // cookie: { secure: true, sameSite: 'strict' }, // refresh token cookie
26
- // accessCookie: { secure: true, sameSite: 'strict' }, // access token cookie (SPA)
36
+ // cookie: { secure: true, sameSite: 'strict' },
37
+ // accessCookie: { secure: true, sameSite: 'strict' },
27
38
 
28
39
  // -- Hooks (optional) -------------------------------------------------------
29
40
  // hooks: {
30
- // onLogin: (user) => console.log(\`[\${new Date().toISOString()}] login: \${user.identifier}\`),
31
- // onFailedLogin: (identifier) => console.warn(\`failed login attempt: \${identifier}\`),
41
+ // onLogin: (user) => console.log(\`login: \${user.identifier}\`),
42
+ // onFailedLogin: (identifier) => console.warn(\`failed login: \${identifier}\`),
32
43
  // onLogout: (userId) => console.log(\`logout: \${userId}\`),
33
44
  // },
34
45
 
@@ -36,37 +47,179 @@ export const sentriAuth = createAuthServer<Role>({
36
47
  // isTokenRevoked: async (sessionId) => false,
37
48
 
38
49
  // -- Logger (optional) ------------------------------------------------------
39
- // Accepts any logger compatible with pino, winston, or console.
40
- // When omitted, sentri produces no log output.
41
50
  // logger: console,
42
- // loggerService: 'sentri', // default: 'sentri'
51
+ // loggerService: 'sentri',
43
52
  });
44
- `,d=`# -- Server -------------------------------------------------------------------
45
- PORT=3000
53
+ `,fastify:`import { createAuthFastify } from 'sentri/fastify';
54
+ import { PostgresDialect } from 'kysely';
55
+ import pg from 'pg';
46
56
 
47
- # -- Database -----------------------------------------------------------------
48
- DATABASE_URL=postgresql://user:password@localhost:5432/mydb
57
+ const { Pool } = pg;
49
58
 
50
- # -- Token --------------------------------------------------------------------
51
- JWT_ACCESS_EXPIRES_IN=15m
52
- JWT_REFRESH_EXPIRES_IN=7d
59
+ type Role = 'admin' | 'user';
53
60
 
54
- # -- Security -----------------------------------------------------------------
55
- SALT_ROUNDS=12
56
- # API_KEY=your-register-api-key
61
+ export const sentriAuth = createAuthFastify<Role>({
62
+ mode: 'server',
57
63
 
58
- # -- Redis (optional) ---------------------------------------------------------
59
- # REDIS_URL=redis://localhost:6379
60
- `,m=`import { createAuth } from 'sentri';
64
+ // -- Roles ------------------------------------------------------------------
65
+ validRoles: ['admin', 'user'],
66
+
67
+ // -- Identifiers ------------------------------------------------------------
68
+ validIdentifiers: ['email', 'username'],
69
+
70
+ // -- Database ---------------------------------------------------------------
71
+ dialect: new PostgresDialect({
72
+ pool: new Pool({ connectionString: process.env.DATABASE_URL! })
73
+ }),
74
+
75
+ // -- Token ------------------------------------------------------------------
76
+ accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
77
+ refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? '7d',
78
+
79
+ // -- Security ---------------------------------------------------------------
80
+ saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
81
+ // apiKey: process.env.API_KEY,
82
+
83
+ // -- Redis (optional) -------------------------------------------------------
84
+ // redisUrl: process.env.REDIS_URL,
85
+
86
+ // -- Cookie (optional) ------------------------------------------------------
87
+ // cookie: { secure: true, sameSite: 'strict' },
88
+ // accessCookie: { secure: true, sameSite: 'strict' },
89
+
90
+ // -- Hooks (optional) -------------------------------------------------------
91
+ // hooks: {
92
+ // onLogin: (user) => console.log(\`login: \${user.identifier}\`),
93
+ // onFailedLogin: (identifier) => console.warn(\`failed login: \${identifier}\`),
94
+ // onLogout: (userId) => console.log(\`logout: \${userId}\`),
95
+ // },
96
+
97
+ // -- Token revocation (optional) --------------------------------------------
98
+ // isTokenRevoked: async (sessionId) => false,
99
+
100
+ // -- Logger (optional) ------------------------------------------------------
101
+ // logger: console,
102
+ // loggerService: 'sentri',
103
+ });
104
+ `,hono:`import { createAuthHono } from 'sentri/hono';
105
+ import { PostgresDialect } from 'kysely';
106
+ import pg from 'pg';
107
+
108
+ const { Pool } = pg;
109
+
110
+ type Role = 'admin' | 'user';
111
+
112
+ export const sentriAuth = createAuthHono<Role>({
113
+ mode: 'server',
114
+
115
+ // -- Roles ------------------------------------------------------------------
116
+ validRoles: ['admin', 'user'],
117
+
118
+ // -- Identifiers ------------------------------------------------------------
119
+ validIdentifiers: ['email', 'username'],
120
+
121
+ // -- Database ---------------------------------------------------------------
122
+ dialect: new PostgresDialect({
123
+ pool: new Pool({ connectionString: process.env.DATABASE_URL! })
124
+ }),
125
+
126
+ // -- Token ------------------------------------------------------------------
127
+ accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
128
+ refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? '7d',
129
+
130
+ // -- Security ---------------------------------------------------------------
131
+ saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
132
+ // apiKey: process.env.API_KEY,
133
+
134
+ // -- Redis (optional) -------------------------------------------------------
135
+ // redisUrl: process.env.REDIS_URL,
136
+
137
+ // -- Cookie (optional) ------------------------------------------------------
138
+ // cookie: { secure: true, sameSite: 'strict' },
139
+ // accessCookie: { secure: true, sameSite: 'strict' },
140
+
141
+ // -- Hooks (optional) -------------------------------------------------------
142
+ // hooks: {
143
+ // onLogin: (user) => console.log(\`login: \${user.identifier}\`),
144
+ // onFailedLogin: (identifier) => console.warn(\`failed login: \${identifier}\`),
145
+ // onLogout: (userId) => console.log(\`logout: \${userId}\`),
146
+ // },
147
+
148
+ // -- Token revocation (optional) --------------------------------------------
149
+ // isTokenRevoked: async (sessionId) => false,
150
+
151
+ // -- Logger (optional) ------------------------------------------------------
152
+ // logger: console,
153
+ // loggerService: 'sentri',
154
+ });
155
+ `,elysia:`import { createAuthElysia } from 'sentri/elysia';
156
+ import { PostgresDialect } from 'kysely';
157
+ import pg from 'pg';
158
+
159
+ const { Pool } = pg;
160
+
161
+ type Role = 'admin' | 'user';
162
+
163
+ export const sentriAuth = createAuthElysia<Role>({
164
+ mode: 'server',
165
+
166
+ // -- Roles ------------------------------------------------------------------
167
+ validRoles: ['admin', 'user'],
168
+
169
+ // -- Identifiers ------------------------------------------------------------
170
+ validIdentifiers: ['email', 'username'],
171
+
172
+ // -- Database ---------------------------------------------------------------
173
+ dialect: new PostgresDialect({
174
+ pool: new Pool({ connectionString: process.env.DATABASE_URL! })
175
+ }),
176
+
177
+ // -- Token ------------------------------------------------------------------
178
+ accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
179
+ refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? '7d',
180
+
181
+ // -- Security ---------------------------------------------------------------
182
+ saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
183
+ });
184
+ `,koa:`import { createAuthKoa } from 'sentri/koa';
185
+ import { PostgresDialect } from 'kysely';
186
+ import pg from 'pg';
187
+
188
+ const { Pool } = pg;
61
189
 
62
190
  type Role = 'admin' | 'user';
63
191
 
64
- export const sentriAuth = createAuth<Role>({
192
+ export const sentriAuth = createAuthKoa<Role>({
193
+ mode: 'server',
194
+
195
+ // -- Roles ------------------------------------------------------------------
196
+ validRoles: ['admin', 'user'],
197
+
198
+ // -- Identifiers ------------------------------------------------------------
199
+ validIdentifiers: ['email', 'username'],
200
+
201
+ // -- Database ---------------------------------------------------------------
202
+ dialect: new PostgresDialect({
203
+ pool: new Pool({ connectionString: process.env.DATABASE_URL! })
204
+ }),
205
+
206
+ // -- Token ------------------------------------------------------------------
207
+ accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
208
+ refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? '7d',
209
+
210
+ // -- Security ---------------------------------------------------------------
211
+ saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
212
+ });
213
+ `},client:{express:`import { createAuthExpress } from 'sentri/express';
214
+
215
+ type Role = 'admin' | 'user';
216
+
217
+ export const sentriAuth = createAuthExpress<Role>({
65
218
  mode: 'client',
66
219
 
67
220
  // -- Auth server ------------------------------------------------------------
68
221
  // URL of the auth server's GET /auth/keys endpoint (JWKS).
69
- // The server must use RS256/RS384/RS512 to expose this endpoint.
222
+ // The server must use RS256 to expose this endpoint.
70
223
  keyUri: process.env.AUTH_KEY_URI!,
71
224
 
72
225
  // -- Roles (optional) -------------------------------------------------------
@@ -74,40 +227,118 @@ export const sentriAuth = createAuth<Role>({
74
227
  validRoles: ['admin', 'user'],
75
228
 
76
229
  // -- Logger (optional) ------------------------------------------------------
77
- // Accepts any logger compatible with pino, winston, or console.
78
- // When omitted, sentri produces no log output.
79
230
  // logger: console,
80
- // loggerService: 'auth-service', // default: 'sentri'
231
+ // loggerService: 'auth-service',
81
232
  });
82
- `,g=`# -- Server -------------------------------------------------------------------
233
+ `,fastify:`import { createAuthFastify } from 'sentri/fastify';
234
+
235
+ type Role = 'admin' | 'user';
236
+
237
+ export const sentriAuth = createAuthFastify<Role>({
238
+ mode: 'client',
239
+
240
+ // -- Auth server ------------------------------------------------------------
241
+ // URL of the auth server's GET /auth/keys endpoint (JWKS).
242
+ keyUri: process.env.AUTH_KEY_URI!,
243
+
244
+ // -- Roles (optional) -------------------------------------------------------
245
+ validRoles: ['admin', 'user'],
246
+
247
+ // -- Logger (optional) ------------------------------------------------------
248
+ // logger: console,
249
+ // loggerService: 'auth-service',
250
+ });
251
+ `,hono:`import { createAuthHono } from 'sentri/hono';
252
+
253
+ type Role = 'admin' | 'user';
254
+
255
+ export const sentriAuth = createAuthHono<Role>({
256
+ mode: 'client',
257
+
258
+ // -- Auth server ------------------------------------------------------------
259
+ // URL of the auth server's GET /auth/keys endpoint (JWKS).
260
+ keyUri: process.env.AUTH_KEY_URI!,
261
+
262
+ // -- Roles (optional) -------------------------------------------------------
263
+ validRoles: ['admin', 'user'],
264
+
265
+ // -- Logger (optional) ------------------------------------------------------
266
+ // logger: console,
267
+ // loggerService: 'auth-service',
268
+ });
269
+ `,elysia:`import { createAuthElysia } from 'sentri/elysia';
270
+
271
+ type Role = 'admin' | 'user';
272
+
273
+ export const sentriAuth = createAuthElysia<Role>({
274
+ mode: 'client',
275
+
276
+ // -- Auth server ------------------------------------------------------------
277
+ // URL of the auth server's GET /auth/keys endpoint (JWKS).
278
+ // The server must use RS256 to expose this endpoint.
279
+ keyUri: process.env.AUTH_KEY_URI!,
280
+
281
+ // -- Roles (optional) -------------------------------------------------------
282
+ // Only used for TypeScript type safety on authorize() \u2014 not validated at runtime.
283
+ validRoles: ['admin', 'user'],
284
+
285
+ // -- Logger (optional) ------------------------------------------------------
286
+ // logger: console,
287
+ // loggerService: 'auth-service',
288
+ });
289
+ `,koa:`import { createAuthKoa } from 'sentri/koa';
290
+
291
+ type Role = 'admin' | 'user';
292
+
293
+ export const sentriAuth = createAuthKoa<Role>({
294
+ mode: 'client',
295
+
296
+ // -- Auth server ------------------------------------------------------------
297
+ // URL of the auth server's GET /auth/keys endpoint (JWKS).
298
+ // The server must use RS256 to expose this endpoint.
299
+ keyUri: process.env.AUTH_KEY_URI!,
300
+
301
+ // -- Roles (optional) -------------------------------------------------------
302
+ // Only used for TypeScript type safety on authorize() \u2014 not validated at runtime.
303
+ validRoles: ['admin', 'user'],
304
+
305
+ // -- Logger (optional) ------------------------------------------------------
306
+ // logger: console,
307
+ // loggerService: 'auth-service',
308
+ });
309
+ `}},A=`# -- Server -------------------------------------------------------------------
83
310
  PORT=3000
84
311
 
85
- # -- Auth Server --------------------------------------------------------------
86
- # URL of the auth server's GET /auth/keys endpoint (JWKS).
87
- AUTH_KEY_URI=http://localhost:3000/auth/keys
88
- `;function a(){console.log(`
89
- sentri \u2014 auth/authorization library for Express
312
+ # -- Database -----------------------------------------------------------------
313
+ DATABASE_URL=postgresql://user:password@localhost:5432/mydb
90
314
 
91
- Usage:
92
- npx sentri <command>
315
+ # -- Token --------------------------------------------------------------------
316
+ JWT_ACCESS_EXPIRES_IN=15m
317
+ JWT_REFRESH_EXPIRES_IN=7d
93
318
 
94
- Commands:
95
- init server Generate src/lib/sentri.ts for server mode (PostgreSQL + JWT signing)
96
- init client Generate src/lib/sentri.ts for client mode (JWT verification via JWKS)
319
+ # -- Security -----------------------------------------------------------------
320
+ SALT_ROUNDS=12
321
+ # API_KEY=your-register-api-key
97
322
 
98
- Examples:
99
- npx sentri init server
100
- npx sentri init client
101
- `);}async function s(e,o,n){if(existsSync(e)){console.log(` skip ${n} (already exists)`);return}await writeFile(e,o,"utf8"),console.log(` create ${n}`);}async function v(){let e=process.cwd(),o=join(e,"src","lib");await mkdir(o,{recursive:true}),console.log(`
102
- Generating sentri server mode files...
103
- `),await s(join(o,"sentri.ts"),u,"src/lib/sentri.ts"),await s(join(e,".env.example"),d,".env.example"),console.log(`
323
+ # -- Redis (optional) ---------------------------------------------------------
324
+ # REDIS_URL=redis://localhost:6379
325
+ `,R=`# -- Server -------------------------------------------------------------------
326
+ PORT=3000
327
+
328
+ # -- Auth Server --------------------------------------------------------------
329
+ # URL of the auth server's GET /auth/keys endpoint (JWKS).
330
+ AUTH_KEY_URI=http://localhost:3000/auth/keys
331
+ `,E={server:{express:`
104
332
  Done. Next steps:
105
333
 
106
334
  1. Copy .env.example to .env and fill in your values
107
335
  2. Add to your app entry point:
108
336
 
337
+ import express from 'express';
109
338
  import { sentriAuth } from './lib/sentri.js';
110
339
 
340
+ const app = express();
341
+ app.use(express.json());
111
342
  await sentriAuth.migrate();
112
343
  app.use('/auth', sentriAuth.router());
113
344
  app.use(sentriAuth.errorHandler());
@@ -115,16 +346,184 @@ Done. Next steps:
115
346
  3. Protect routes:
116
347
 
117
348
  app.get('/me', sentriAuth.protect(), (req, res) => res.json(req.user));
118
- `);}async function h(){let e=process.cwd(),o=join(e,"src","lib");await mkdir(o,{recursive:true}),console.log(`
119
- Generating sentri client mode files...
120
- `),await s(join(o,"sentri.ts"),m,"src/lib/sentri.ts"),await s(join(e,".env.example"),g,".env.example"),console.log(`
349
+ `,fastify:`
350
+ Done. Next steps:
351
+
352
+ 1. Copy .env.example to .env and fill in your values
353
+ 2. Install peer deps: npm install fastify @fastify/cookie
354
+ 3. Add to your app entry point:
355
+
356
+ import Fastify from 'fastify';
357
+ import cookie from '@fastify/cookie';
358
+ import { sentriAuth } from './lib/sentri.js';
359
+
360
+ const app = Fastify();
361
+ await app.register(cookie);
362
+ await sentriAuth.migrate();
363
+ await app.register(sentriAuth.plugin(), { prefix: '/auth' });
364
+ app.setErrorHandler(sentriAuth.errorHandler());
365
+
366
+ 4. Protect routes:
367
+
368
+ app.get('/me', { preHandler: sentriAuth.protect() }, async (req) => req.user);
369
+ `,hono:`
370
+ Done. Next steps:
371
+
372
+ 1. Copy .env.example to .env and fill in your values
373
+ 2. Install peer deps: npm install hono
374
+ 3. Add to your app entry point:
375
+
376
+ import { Hono } from 'hono';
377
+ import { sentriAuth } from './lib/sentri.js';
378
+ import type { SentriHonoEnv } from 'sentri/hono';
379
+
380
+ const app = new Hono<SentriHonoEnv>();
381
+ await sentriAuth.migrate();
382
+ app.route('/auth', sentriAuth.router());
383
+ app.onError(sentriAuth.errorHandler());
384
+
385
+ 4. Protect routes:
386
+
387
+ app.get('/me', sentriAuth.protect(), (c) => c.json(c.get('user')));
388
+ `,elysia:`
389
+ Done. Next steps:
390
+
391
+ 1. Copy .env.example to .env and fill in your values
392
+ 2. Install peer deps: npm install elysia
393
+ 3. Add to your app entry point:
394
+
395
+ import { Elysia } from 'elysia';
396
+ import { sentriAuth } from './lib/sentri.js';
397
+
398
+ const app = new Elysia()
399
+ .onError(sentriAuth.errorHandler())
400
+ .group('/auth', app => app.use(sentriAuth.router()))
401
+ .use(sentriAuth.protect())
402
+ .get('/me', ({ user }) => user);
403
+
404
+ 4. Protect routes:
405
+
406
+ app.use(sentriAuth.protect())
407
+ .get('/me', ({ user }) => user);
408
+ `,koa:`
409
+ Done. Next steps:
410
+
411
+ 1. Copy .env.example to .env and fill in your values
412
+ 2. Install peer deps: npm install koa @koa/router koa-bodyparser
413
+ 3. Add to your app entry point:
414
+
415
+ import Koa from 'koa';
416
+ import Router from '@koa/router';
417
+ import bodyParser from 'koa-bodyparser';
418
+ import { sentriAuth } from './lib/sentri.js';
419
+
420
+ const app = new Koa();
421
+ app.use(bodyParser());
422
+ app.use(sentriAuth.errorHandler());
423
+ await sentriAuth.migrate();
424
+
425
+ const rootRouter = new Router();
426
+ rootRouter.use('/auth', sentriAuth.router().routes());
427
+ app.use(rootRouter.routes());
428
+
429
+ 4. Protect routes:
430
+
431
+ rootRouter.get('/me', sentriAuth.protect(), (ctx) => {
432
+ ctx.body = ctx.state.user;
433
+ });
434
+ `},client:{express:`
121
435
  Done. Next steps:
122
436
 
123
437
  1. Copy .env.example to .env and set AUTH_KEY_URI to your auth server's /auth/keys endpoint
124
438
  2. Add to your app entry point:
125
439
 
440
+ import express from 'express';
126
441
  import { sentriAuth } from './lib/sentri.js';
127
442
 
443
+ const app = express();
128
444
  app.get('/protected', sentriAuth.protect(), (req, res) => res.json(req.user));
129
445
  app.use(sentriAuth.errorHandler());
130
- `);}var E=process.argv.slice(2),[r,i]=E;(!r||r==="--help"||r==="-h")&&(a(),process.exit(0));r==="init"?i==="server"?v().catch(e=>{console.error(e),process.exit(1);}):i==="client"?h().catch(e=>{console.error(e),process.exit(1);}):(console.error("Usage: npx sentri init <server|client>"),process.exit(1)):(console.error(`Unknown command: ${r}`),a(),process.exit(1));
446
+ `,fastify:`
447
+ Done. Next steps:
448
+
449
+ 1. Copy .env.example to .env and set AUTH_KEY_URI to your auth server's /auth/keys endpoint
450
+ 2. Install peer deps: npm install fastify
451
+ 3. Add to your app entry point:
452
+
453
+ import Fastify from 'fastify';
454
+ import { sentriAuth } from './lib/sentri.js';
455
+
456
+ const app = Fastify();
457
+ app.get('/protected', { preHandler: sentriAuth.protect() }, async (req) => req.user);
458
+ app.setErrorHandler(sentriAuth.errorHandler());
459
+ `,hono:`
460
+ Done. Next steps:
461
+
462
+ 1. Copy .env.example to .env and set AUTH_KEY_URI to your auth server's /auth/keys endpoint
463
+ 2. Install peer deps: npm install hono
464
+ 3. Add to your app entry point:
465
+
466
+ import { Hono } from 'hono';
467
+ import { sentriAuth } from './lib/sentri.js';
468
+ import type { SentriHonoEnv } from 'sentri/hono';
469
+
470
+ const app = new Hono<SentriHonoEnv>();
471
+ app.get('/protected', sentriAuth.protect(), (c) => c.json(c.get('user')));
472
+ app.onError(sentriAuth.errorHandler());
473
+ `,elysia:`
474
+ Done. Next steps:
475
+
476
+ 1. Copy .env.example to .env and set AUTH_KEY_URI to your auth server's /auth/keys endpoint
477
+ 2. Install peer deps: npm install elysia
478
+ 3. Add to your app entry point:
479
+
480
+ import { Elysia } from 'elysia';
481
+ import { sentriAuth } from './lib/sentri.js';
482
+
483
+ const app = new Elysia()
484
+ .onError(sentriAuth.errorHandler())
485
+ .use(sentriAuth.protect())
486
+ .get('/protected', ({ user }) => user);
487
+ `,koa:`
488
+ Done. Next steps:
489
+
490
+ 1. Copy .env.example to .env and set AUTH_KEY_URI to your auth server's /auth/keys endpoint
491
+ 2. Install peer deps: npm install koa @koa/router
492
+ 3. Add to your app entry point:
493
+
494
+ import Koa from 'koa';
495
+ import Router from '@koa/router';
496
+ import { sentriAuth } from './lib/sentri.js';
497
+
498
+ const app = new Koa();
499
+ app.use(sentriAuth.errorHandler());
500
+
501
+ const rootRouter = new Router();
502
+ rootRouter.get('/protected', sentriAuth.protect(), (ctx) => {
503
+ ctx.body = ctx.state.user;
504
+ });
505
+ app.use(rootRouter.routes());
506
+ `}};function c(){console.log(`
507
+ sentri \u2014 auth/authorization library for Express, Fastify, Hono, Elysia, and Koa
508
+
509
+ Usage:
510
+ npx sentri <command>
511
+
512
+ Commands:
513
+ init [mode] [adapter] Generate src/lib/sentri.ts
514
+
515
+ mode: server (default) | client
516
+ adapter: express (default) | fastify | hono | elysia | koa
517
+
518
+ Examples:
519
+ npx sentri init \u2192 server mode, express adapter
520
+ npx sentri init server \u2192 server mode, express adapter
521
+ npx sentri init server hono \u2192 server mode, hono adapter
522
+ npx sentri init server elysia \u2192 server mode, elysia adapter
523
+ npx sentri init server koa \u2192 server mode, koa adapter
524
+ npx sentri init client \u2192 client mode, express adapter
525
+ npx sentri init client fastify \u2192 client mode, fastify adapter
526
+ npx sentri init client hono \u2192 client mode, hono adapter
527
+ `);}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(`
528
+ Generating sentri ${e} mode files (${o})...
529
+ `),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));
@@ -0,0 +1 @@
1
+ 'use strict';var t=Object.defineProperty;var N=(I,E)=>t(I,"name",{value:E,configurable:true});var O=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}),R=class extends Error{static{N(this,"SentriError");}code;statusCode;constructor(E,T,_){super(T),this.name="SentriError",this.code=E,this.statusCode=_??O[E]??500;}};exports.SENTRI_ERROR_STATUS=O;exports.SentriError=R;