sentri 1.1.2 → 2.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.
Files changed (64) hide show
  1. package/README.md +268 -448
  2. package/dist/cli.d.ts +0 -2
  3. package/dist/cli.js +113 -107
  4. package/dist/index.d.ts +545 -11
  5. package/dist/index.js +1 -5
  6. package/package.json +9 -7
  7. package/dist/cli.d.ts.map +0 -1
  8. package/dist/cli.js.map +0 -1
  9. package/dist/client.d.ts +0 -160
  10. package/dist/client.d.ts.map +0 -1
  11. package/dist/client.js +0 -45
  12. package/dist/client.js.map +0 -1
  13. package/dist/errors/AuthError.d.ts +0 -99
  14. package/dist/errors/AuthError.d.ts.map +0 -1
  15. package/dist/errors/AuthError.js +0 -97
  16. package/dist/errors/AuthError.js.map +0 -1
  17. package/dist/index.d.ts.map +0 -1
  18. package/dist/index.js.map +0 -1
  19. package/dist/libs/config.d.ts +0 -62
  20. package/dist/libs/config.d.ts.map +0 -1
  21. package/dist/libs/config.js +0 -97
  22. package/dist/libs/config.js.map +0 -1
  23. package/dist/libs/hash.d.ts +0 -17
  24. package/dist/libs/hash.d.ts.map +0 -1
  25. package/dist/libs/hash.js +0 -22
  26. package/dist/libs/hash.js.map +0 -1
  27. package/dist/libs/token.d.ts +0 -46
  28. package/dist/libs/token.d.ts.map +0 -1
  29. package/dist/libs/token.js +0 -118
  30. package/dist/libs/token.js.map +0 -1
  31. package/dist/middleware/authorize.d.ts +0 -18
  32. package/dist/middleware/authorize.d.ts.map +0 -1
  33. package/dist/middleware/authorize.js +0 -30
  34. package/dist/middleware/authorize.js.map +0 -1
  35. package/dist/middleware/errorHandler.d.ts +0 -71
  36. package/dist/middleware/errorHandler.d.ts.map +0 -1
  37. package/dist/middleware/errorHandler.js +0 -74
  38. package/dist/middleware/errorHandler.js.map +0 -1
  39. package/dist/middleware/permit.d.ts +0 -62
  40. package/dist/middleware/permit.d.ts.map +0 -1
  41. package/dist/middleware/permit.js +0 -61
  42. package/dist/middleware/permit.js.map +0 -1
  43. package/dist/middleware/protect.d.ts +0 -31
  44. package/dist/middleware/protect.d.ts.map +0 -1
  45. package/dist/middleware/protect.js +0 -54
  46. package/dist/middleware/protect.js.map +0 -1
  47. package/dist/middleware/router.d.ts +0 -34
  48. package/dist/middleware/router.d.ts.map +0 -1
  49. package/dist/middleware/router.js +0 -264
  50. package/dist/middleware/router.js.map +0 -1
  51. package/dist/services/auth.d.ts +0 -85
  52. package/dist/services/auth.d.ts.map +0 -1
  53. package/dist/services/auth.js +0 -173
  54. package/dist/services/auth.js.map +0 -1
  55. package/dist/types/auth.d.ts +0 -450
  56. package/dist/types/auth.d.ts.map +0 -1
  57. package/dist/types/auth.js +0 -21
  58. package/dist/types/auth.js.map +0 -1
  59. package/templates/drizzle/adapter.ts +0 -154
  60. package/templates/drizzle/auth.ts +0 -82
  61. package/templates/drizzle/schema.ts +0 -47
  62. package/templates/prisma/adapter.ts +0 -122
  63. package/templates/prisma/auth.ts +0 -85
  64. package/templates/prisma/schema.prisma +0 -56
package/dist/cli.d.ts CHANGED
@@ -1,3 +1 @@
1
1
  #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js CHANGED
@@ -1,112 +1,118 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, copyFileSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
- import { join, dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
- const __dirname = dirname(fileURLToPath(import.meta.url));
6
- const COMMANDS = ['generate'];
7
- const ORMS = ['prisma', 'drizzle'];
8
- function help() {
9
- console.log(`
10
- sentri auth/authorization library for Express
2
+ import {mkdir,writeFile}from'fs/promises';import {existsSync}from'fs';import {join}from'path';var u=`import { createAuthServer } from 'sentri';
3
+
4
+ type Role = 'admin' | 'user';
5
+
6
+ export const sentriAuth = createAuthServer<Role>({
7
+ // -- Roles ------------------------------------------------------------------
8
+ validRoles: ['admin', 'user'],
9
+
10
+ // -- Database ---------------------------------------------------------------
11
+ db: { connectionString: process.env.DATABASE_URL! },
12
+
13
+ // -- Token ------------------------------------------------------------------
14
+ accessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN ?? '15m',
15
+ refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN ?? '7d',
16
+
17
+ // -- Security ---------------------------------------------------------------
18
+ saltRounds: parseInt(process.env.SALT_ROUNDS ?? '12', 10),
19
+ // apiKey: process.env.API_KEY, // uncomment to restrict POST /register
20
+
21
+ // -- Redis (optional) -------------------------------------------------------
22
+ // redisUrl: process.env.REDIS_URL, // uncomment to enable distributed idempotency cache
23
+
24
+ // -- Cookie (optional) ------------------------------------------------------
25
+ // cookie: { secure: true, sameSite: 'strict' }, // refresh token cookie
26
+ // accessCookie: { secure: true, sameSite: 'strict' }, // access token cookie (SPA)
27
+
28
+ // -- Hooks (optional) -------------------------------------------------------
29
+ // hooks: {
30
+ // onLogin: (user) => console.log(\`[\${new Date().toISOString()}] login: \${user.identifier}\`),
31
+ // onFailedLogin: (identifier) => console.warn(\`failed login attempt: \${identifier}\`),
32
+ // onLogout: (userId) => console.log(\`logout: \${userId}\`),
33
+ // },
34
+
35
+ // -- Token revocation (optional) --------------------------------------------
36
+ // isTokenRevoked: async (sessionId) => false,
37
+ });
38
+ `,d=`# -- Server -------------------------------------------------------------------
39
+ PORT=3000
40
+
41
+ # -- Database -----------------------------------------------------------------
42
+ DATABASE_URL=postgresql://user:password@localhost:5432/mydb
43
+
44
+ # -- Token --------------------------------------------------------------------
45
+ JWT_ACCESS_EXPIRES_IN=15m
46
+ JWT_REFRESH_EXPIRES_IN=7d
47
+
48
+ # -- Security -----------------------------------------------------------------
49
+ SALT_ROUNDS=12
50
+ # API_KEY=your-register-api-key
51
+
52
+ # -- Redis (optional) ---------------------------------------------------------
53
+ # REDIS_URL=redis://localhost:6379
54
+ `,m=`import { createAuth } from 'sentri';
55
+
56
+ type Role = 'admin' | 'user';
57
+
58
+ export const sentriAuth = createAuth<Role>({
59
+ mode: 'client',
60
+
61
+ // -- Auth server ------------------------------------------------------------
62
+ // URL of the auth server's GET /auth/keys endpoint (JWKS).
63
+ // The server must use RS256/RS384/RS512 to expose this endpoint.
64
+ keyUri: process.env.AUTH_KEY_URI!,
65
+
66
+ // -- Roles (optional) -------------------------------------------------------
67
+ // Only used for TypeScript type safety on authorize() \u2014 not validated at runtime.
68
+ validRoles: ['admin', 'user'],
69
+ });
70
+ `,v=`# -- Server -------------------------------------------------------------------
71
+ PORT=3000
72
+
73
+ # -- Auth Server --------------------------------------------------------------
74
+ # URL of the auth server's GET /auth/keys endpoint (JWKS).
75
+ AUTH_KEY_URI=http://localhost:3000/auth/keys
76
+ `;function c(){console.log(`
77
+ sentri \u2014 auth/authorization library for Express
11
78
 
12
79
  Usage:
13
- npx sentri <command> [options]
80
+ npx sentri <command>
14
81
 
15
82
  Commands:
16
- generate <prisma|drizzle>
17
- Generate adapter, auth config, and schema templates
18
- in src/lib/sentri/ and create a barrel at src/lib/index.ts
19
- `);
20
- }
21
- function generateSchemaFile(templatePath, destination, firstLinePrefix, label) {
22
- if (!existsSync(templatePath))
23
- return;
24
- mkdirSync(dirname(destination), { recursive: true });
25
- if (!existsSync(destination)) {
26
- copyFileSync(templatePath, destination);
27
- console.log(`Created ${label}`);
28
- }
29
- else {
30
- const templateContent = readFileSync(templatePath, 'utf-8');
31
- const lines = templateContent.split('\n');
32
- const firstLine = lines.findIndex((line) => line.startsWith(firstLinePrefix));
33
- if (firstLine !== -1) {
34
- const block = lines.slice(firstLine).join('\n').trimEnd();
35
- const existing = readFileSync(destination, 'utf-8');
36
- writeFileSync(destination, existing.trimEnd() + '\n\n' + block + '\n');
37
- console.log(`Updated ${label} (tables appended)`);
38
- }
39
- }
40
- }
41
- function generate(orm) {
42
- if (!orm || !ORMS.includes(orm)) {
43
- console.error(`Error: specify an ORM — usage: sentri generate <${ORMS.join('|')}>`);
44
- process.exit(1);
45
- }
46
- const templateDirectory = join(__dirname, '..', 'templates', orm);
47
- const destinationDirectory = join(process.cwd(), 'src', 'lib', 'sentri');
48
- const adapterDestination = join(destinationDirectory, 'adapter.ts');
49
- const authDestination = join(destinationDirectory, 'auth.ts');
50
- const barrelDestination = join(process.cwd(), 'src', 'lib', 'index.ts');
51
- if (!existsSync(templateDirectory)) {
52
- console.error(`Error: templates for "${orm}" not found. Try reinstalling sentri.`);
53
- process.exit(1);
54
- }
55
- if (existsSync(adapterDestination) || existsSync(authDestination)) {
56
- console.error('Error: files already exist in src/lib/sentri/. Remove them first if you want to regenerate.');
57
- process.exit(1);
58
- }
59
- mkdirSync(destinationDirectory, { recursive: true });
60
- copyFileSync(join(templateDirectory, 'adapter.ts'), adapterDestination);
61
- copyFileSync(join(templateDirectory, 'auth.ts'), authDestination);
62
- console.log('Created src/lib/sentri/adapter.ts');
63
- console.log('Created src/lib/sentri/auth.ts');
64
- if (orm === 'prisma') {
65
- generateSchemaFile(join(__dirname, '..', 'templates', 'prisma', 'schema.prisma'), join(process.cwd(), 'prisma', 'schema.prisma'), 'model ', 'prisma/schema.prisma');
66
- }
67
- else {
68
- generateSchemaFile(join(templateDirectory, 'schema.ts'), join(destinationDirectory, 'schema.ts'), 'export ', 'src/lib/sentri/schema.ts');
69
- }
70
- if (!existsSync(barrelDestination)) {
71
- mkdirSync(dirname(barrelDestination), { recursive: true });
72
- writeFileSync(barrelDestination, "export { createAdapter } from './sentri/adapter.js';\nexport { auth } from './sentri/auth.js';\n");
73
- console.log('Created src/lib/index.ts');
74
- }
75
- else {
76
- console.log('Skipped src/lib/index.ts (already exists)');
77
- }
78
- console.log('');
79
- console.log('Next steps:');
80
- if (orm === 'prisma') {
81
- console.log(' 1. Edit prisma/schema.prisma — change @map("email") to match your column name');
82
- console.log(' 2. Set DATABASE_URL and JWT_SECRET in your .env file');
83
- console.log(' 3. Run: npx prisma migrate dev && npx prisma generate');
84
- console.log(' 4. Edit src/lib/sentri/auth.ts — update validRoles to match your app');
85
- }
86
- else {
87
- console.log(' 1. Edit src/lib/sentri/schema.ts — change text(\'email\') to match your column name');
88
- console.log(' 2. Edit src/lib/sentri/auth.ts — update validRoles to match your app');
89
- console.log(' 3. Set JWT_SECRET in your .env file');
90
- }
91
- console.log(' Mount the router in your Express app:');
92
- console.log(" import { auth } from './lib/sentri/auth.js';");
93
- console.log(" app.use('/auth', auth.router());");
94
- console.log('');
95
- }
96
- const [, , command, ...args] = process.argv;
97
- if (!command || command === '--help' || command === '-h') {
98
- help();
99
- process.exit(0);
100
- }
101
- if (!COMMANDS.includes(command)) {
102
- console.error(`Unknown command: ${command}`);
103
- help();
104
- process.exit(1);
105
- }
106
- if (args.includes('--help') || args.includes('-h')) {
107
- help();
108
- process.exit(0);
109
- }
110
- if (command === 'generate')
111
- generate(args[0]);
112
- //# sourceMappingURL=cli.js.map
83
+ init server Generate src/lib/sentri.ts for server mode (PostgreSQL + JWT signing)
84
+ init client Generate src/lib/sentri.ts for client mode (JWT verification via JWKS)
85
+
86
+ Examples:
87
+ npx sentri init server
88
+ npx sentri init client
89
+ `);}async function o(e,t,n){if(existsSync(e)){console.log(` skip ${n} (already exists)`);return}await writeFile(e,t,"utf8"),console.log(` create ${n}`);}async function E(){let e=process.cwd(),t=join(e,"src","lib");await mkdir(t,{recursive:true}),console.log(`
90
+ Generating sentri server mode files...
91
+ `),await o(join(t,"sentri.ts"),u,"src/lib/sentri.ts"),await o(join(e,".env.example"),d,".env.example"),console.log(`
92
+ Done. Next steps:
93
+
94
+ 1. Copy .env.example to .env and fill in your values
95
+ 2. Add to your app entry point:
96
+
97
+ import { sentriAuth } from './lib/sentri.js';
98
+
99
+ await sentriAuth.migrate();
100
+ app.use('/auth', sentriAuth.router());
101
+ app.use(sentriAuth.errorHandler());
102
+
103
+ 3. Protect routes:
104
+
105
+ app.get('/me', sentriAuth.protect(), (req, res) => res.json(req.user));
106
+ `);}async function S(){let e=process.cwd(),t=join(e,"src","lib");await mkdir(t,{recursive:true}),console.log(`
107
+ Generating sentri client mode files...
108
+ `),await o(join(t,"sentri.ts"),m,"src/lib/sentri.ts"),await o(join(e,".env.example"),v,".env.example"),console.log(`
109
+ Done. Next steps:
110
+
111
+ 1. Copy .env.example to .env and set AUTH_KEY_URI to your auth server's /auth/keys endpoint
112
+ 2. Add to your app entry point:
113
+
114
+ import { sentriAuth } from './lib/sentri.js';
115
+
116
+ app.get('/protected', sentriAuth.protect(), (req, res) => res.json(req.user));
117
+ app.use(sentriAuth.errorHandler());
118
+ `);}var h=process.argv.slice(2),[s,i]=h;(!s||s==="--help"||s==="-h")&&(c(),process.exit(0));s==="init"?i==="server"?E().catch(e=>{console.error(e),process.exit(1);}):i==="client"?S().catch(e=>{console.error(e),process.exit(1);}):(console.error("Usage: npx sentri init <server|client>"),process.exit(1)):(console.error(`Unknown command: ${s}`),c(),process.exit(1));