@awesome-lang-auth/node 1.10.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/LICENSE +21 -0
- package/README.detailed.md +4059 -0
- package/README.md +248 -0
- package/dist/abstract/base-auth-strategy.abstract.d.ts +7 -0
- package/dist/abstract/base-auth-strategy.abstract.d.ts.map +1 -0
- package/dist/abstract/base-auth-strategy.abstract.js +7 -0
- package/dist/abstract/base-auth-strategy.abstract.js.map +1 -0
- package/dist/abstract/base-oauth-strategy.abstract.d.ts +27 -0
- package/dist/abstract/base-oauth-strategy.abstract.d.ts.map +1 -0
- package/dist/abstract/base-oauth-strategy.abstract.js +11 -0
- package/dist/abstract/base-oauth-strategy.abstract.js.map +1 -0
- package/dist/adapters/express.d.ts +45 -0
- package/dist/adapters/express.d.ts.map +1 -0
- package/dist/adapters/express.js +49 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/fastify.d.ts +72 -0
- package/dist/adapters/fastify.d.ts.map +1 -0
- package/dist/adapters/fastify.js +63 -0
- package/dist/adapters/fastify.js.map +1 -0
- package/dist/auth-configurator.d.ts +65 -0
- package/dist/auth-configurator.d.ts.map +1 -0
- package/dist/auth-configurator.js +127 -0
- package/dist/auth-configurator.js.map +1 -0
- package/dist/events/auth-event-bus.d.ts +68 -0
- package/dist/events/auth-event-bus.d.ts.map +1 -0
- package/dist/events/auth-event-bus.js +60 -0
- package/dist/events/auth-event-bus.js.map +1 -0
- package/dist/events/auth-event-names.d.ts +34 -0
- package/dist/events/auth-event-names.d.ts.map +1 -0
- package/dist/events/auth-event-names.js +41 -0
- package/dist/events/auth-event-names.js.map +1 -0
- package/dist/http-types.d.ts +135 -0
- package/dist/http-types.d.ts.map +1 -0
- package/dist/http-types.js +18 -0
- package/dist/http-types.js.map +1 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/api-key-store.interface.d.ts +94 -0
- package/dist/interfaces/api-key-store.interface.d.ts.map +1 -0
- package/dist/interfaces/api-key-store.interface.js +3 -0
- package/dist/interfaces/api-key-store.interface.js.map +1 -0
- package/dist/interfaces/auth-strategy.interface.d.ts +6 -0
- package/dist/interfaces/auth-strategy.interface.d.ts.map +1 -0
- package/dist/interfaces/auth-strategy.interface.js +3 -0
- package/dist/interfaces/auth-strategy.interface.js.map +1 -0
- package/dist/interfaces/linked-accounts-store.interface.d.ts +74 -0
- package/dist/interfaces/linked-accounts-store.interface.d.ts.map +1 -0
- package/dist/interfaces/linked-accounts-store.interface.js +3 -0
- package/dist/interfaces/linked-accounts-store.interface.js.map +1 -0
- package/dist/interfaces/pending-link-store.interface.d.ts +77 -0
- package/dist/interfaces/pending-link-store.interface.d.ts.map +1 -0
- package/dist/interfaces/pending-link-store.interface.js +3 -0
- package/dist/interfaces/pending-link-store.interface.js.map +1 -0
- package/dist/interfaces/roles-permissions-store.interface.d.ts +129 -0
- package/dist/interfaces/roles-permissions-store.interface.d.ts.map +1 -0
- package/dist/interfaces/roles-permissions-store.interface.js +3 -0
- package/dist/interfaces/roles-permissions-store.interface.js.map +1 -0
- package/dist/interfaces/session-store.interface.d.ts +92 -0
- package/dist/interfaces/session-store.interface.d.ts.map +1 -0
- package/dist/interfaces/session-store.interface.js +3 -0
- package/dist/interfaces/session-store.interface.js.map +1 -0
- package/dist/interfaces/settings-store.interface.d.ts +91 -0
- package/dist/interfaces/settings-store.interface.d.ts.map +1 -0
- package/dist/interfaces/settings-store.interface.js +3 -0
- package/dist/interfaces/settings-store.interface.js.map +1 -0
- package/dist/interfaces/sse-distributor.interface.d.ts +25 -0
- package/dist/interfaces/sse-distributor.interface.d.ts.map +1 -0
- package/dist/interfaces/sse-distributor.interface.js +3 -0
- package/dist/interfaces/sse-distributor.interface.js.map +1 -0
- package/dist/interfaces/telemetry-store.interface.d.ts +72 -0
- package/dist/interfaces/telemetry-store.interface.d.ts.map +1 -0
- package/dist/interfaces/telemetry-store.interface.js +3 -0
- package/dist/interfaces/telemetry-store.interface.js.map +1 -0
- package/dist/interfaces/template-store.interface.d.ts +37 -0
- package/dist/interfaces/template-store.interface.d.ts.map +1 -0
- package/dist/interfaces/template-store.interface.js +3 -0
- package/dist/interfaces/template-store.interface.js.map +1 -0
- package/dist/interfaces/tenant-store.interface.d.ts +97 -0
- package/dist/interfaces/tenant-store.interface.d.ts.map +1 -0
- package/dist/interfaces/tenant-store.interface.js +3 -0
- package/dist/interfaces/tenant-store.interface.js.map +1 -0
- package/dist/interfaces/token-store.interface.d.ts +10 -0
- package/dist/interfaces/token-store.interface.d.ts.map +1 -0
- package/dist/interfaces/token-store.interface.js +3 -0
- package/dist/interfaces/token-store.interface.js.map +1 -0
- package/dist/interfaces/user-metadata-store.interface.d.ts +50 -0
- package/dist/interfaces/user-metadata-store.interface.d.ts.map +1 -0
- package/dist/interfaces/user-metadata-store.interface.js +3 -0
- package/dist/interfaces/user-metadata-store.interface.js.map +1 -0
- package/dist/interfaces/user-store.interface.d.ts +113 -0
- package/dist/interfaces/user-store.interface.d.ts.map +1 -0
- package/dist/interfaces/user-store.interface.js +3 -0
- package/dist/interfaces/user-store.interface.js.map +1 -0
- package/dist/interfaces/webhook-store.interface.d.ts +139 -0
- package/dist/interfaces/webhook-store.interface.d.ts.map +1 -0
- package/dist/interfaces/webhook-store.interface.js +3 -0
- package/dist/interfaces/webhook-store.interface.js.map +1 -0
- package/dist/middleware/api-key.middleware.d.ts +35 -0
- package/dist/middleware/api-key.middleware.d.ts.map +1 -0
- package/dist/middleware/api-key.middleware.js +45 -0
- package/dist/middleware/api-key.middleware.js.map +1 -0
- package/dist/middleware/auth.middleware.d.ts +13 -0
- package/dist/middleware/auth.middleware.d.ts.map +1 -0
- package/dist/middleware/auth.middleware.js +55 -0
- package/dist/middleware/auth.middleware.js.map +1 -0
- package/dist/middleware/jwks-auth.middleware.d.ts +18 -0
- package/dist/middleware/jwks-auth.middleware.d.ts.map +1 -0
- package/dist/middleware/jwks-auth.middleware.js +77 -0
- package/dist/middleware/jwks-auth.middleware.js.map +1 -0
- package/dist/models/api-key.model.d.ts +66 -0
- package/dist/models/api-key.model.d.ts.map +1 -0
- package/dist/models/api-key.model.js +3 -0
- package/dist/models/api-key.model.js.map +1 -0
- package/dist/models/auth-config.model.d.ts +387 -0
- package/dist/models/auth-config.model.d.ts.map +1 -0
- package/dist/models/auth-config.model.js +3 -0
- package/dist/models/auth-config.model.js.map +1 -0
- package/dist/models/errors.d.ts +7 -0
- package/dist/models/errors.d.ts.map +1 -0
- package/dist/models/errors.js +14 -0
- package/dist/models/errors.js.map +1 -0
- package/dist/models/session.model.d.ts +28 -0
- package/dist/models/session.model.d.ts.map +1 -0
- package/dist/models/session.model.js +3 -0
- package/dist/models/session.model.js.map +1 -0
- package/dist/models/tenant.model.d.ts +20 -0
- package/dist/models/tenant.model.d.ts.map +1 -0
- package/dist/models/tenant.model.js +3 -0
- package/dist/models/tenant.model.js.map +1 -0
- package/dist/models/token.model.d.ts +21 -0
- package/dist/models/token.model.d.ts.map +1 -0
- package/dist/models/token.model.js +3 -0
- package/dist/models/token.model.js.map +1 -0
- package/dist/models/user.model.d.ts +92 -0
- package/dist/models/user.model.d.ts.map +1 -0
- package/dist/models/user.model.js +3 -0
- package/dist/models/user.model.js.map +1 -0
- package/dist/router/admin.router.d.ts +188 -0
- package/dist/router/admin.router.d.ts.map +1 -0
- package/dist/router/admin.router.js +1507 -0
- package/dist/router/admin.router.js.map +1 -0
- package/dist/router/auth.router.d.ts +199 -0
- package/dist/router/auth.router.d.ts.map +1 -0
- package/dist/router/auth.router.js +1636 -0
- package/dist/router/auth.router.js.map +1 -0
- package/dist/router/openapi.d.ts +98 -0
- package/dist/router/openapi.d.ts.map +1 -0
- package/dist/router/openapi.js +1518 -0
- package/dist/router/openapi.js.map +1 -0
- package/dist/router/router-events.d.ts +38 -0
- package/dist/router/router-events.d.ts.map +1 -0
- package/dist/router/router-events.js +74 -0
- package/dist/router/router-events.js.map +1 -0
- package/dist/router/tools.router.d.ts +104 -0
- package/dist/router/tools.router.d.ts.map +1 -0
- package/dist/router/tools.router.js +227 -0
- package/dist/router/tools.router.js.map +1 -0
- package/dist/router/ui.router.d.ts +49 -0
- package/dist/router/ui.router.d.ts.map +1 -0
- package/dist/router/ui.router.js +272 -0
- package/dist/router/ui.router.js.map +1 -0
- package/dist/services/api-key.service.d.ts +53 -0
- package/dist/services/api-key.service.d.ts.map +1 -0
- package/dist/services/api-key.service.js +66 -0
- package/dist/services/api-key.service.js.map +1 -0
- package/dist/services/jwks.service.d.ts +73 -0
- package/dist/services/jwks.service.d.ts.map +1 -0
- package/dist/services/jwks.service.js +174 -0
- package/dist/services/jwks.service.js.map +1 -0
- package/dist/services/mailer.service.d.ts +30 -0
- package/dist/services/mailer.service.d.ts.map +1 -0
- package/dist/services/mailer.service.js +248 -0
- package/dist/services/mailer.service.js.map +1 -0
- package/dist/services/notification.service.d.ts +110 -0
- package/dist/services/notification.service.d.ts.map +1 -0
- package/dist/services/notification.service.js +79 -0
- package/dist/services/notification.service.js.map +1 -0
- package/dist/services/password.service.d.ts +5 -0
- package/dist/services/password.service.d.ts.map +1 -0
- package/dist/services/password.service.js +17 -0
- package/dist/services/password.service.js.map +1 -0
- package/dist/services/sms.service.d.ts +14 -0
- package/dist/services/sms.service.d.ts.map +1 -0
- package/dist/services/sms.service.js +51 -0
- package/dist/services/sms.service.js.map +1 -0
- package/dist/services/token.service.d.ts +62 -0
- package/dist/services/token.service.d.ts.map +1 -0
- package/dist/services/token.service.js +354 -0
- package/dist/services/token.service.js.map +1 -0
- package/dist/stores/memory-template.store.d.ts +12 -0
- package/dist/stores/memory-template.store.d.ts.map +1 -0
- package/dist/stores/memory-template.store.js +35 -0
- package/dist/stores/memory-template.store.js.map +1 -0
- package/dist/strategies/api-key/api-key.strategy.d.ts +72 -0
- package/dist/strategies/api-key/api-key.strategy.d.ts.map +1 -0
- package/dist/strategies/api-key/api-key.strategy.js +182 -0
- package/dist/strategies/api-key/api-key.strategy.js.map +1 -0
- package/dist/strategies/local/local.strategy.d.ts +19 -0
- package/dist/strategies/local/local.strategy.d.ts.map +1 -0
- package/dist/strategies/local/local.strategy.js +45 -0
- package/dist/strategies/local/local.strategy.js.map +1 -0
- package/dist/strategies/magic-link/magic-link.strategy.d.ts +8 -0
- package/dist/strategies/magic-link/magic-link.strategy.d.ts.map +1 -0
- package/dist/strategies/magic-link/magic-link.strategy.js +53 -0
- package/dist/strategies/magic-link/magic-link.strategy.js.map +1 -0
- package/dist/strategies/oauth/generic-oauth.strategy.d.ts +120 -0
- package/dist/strategies/oauth/generic-oauth.strategy.d.ts.map +1 -0
- package/dist/strategies/oauth/generic-oauth.strategy.js +88 -0
- package/dist/strategies/oauth/generic-oauth.strategy.js.map +1 -0
- package/dist/strategies/oauth/github.strategy.d.ts +31 -0
- package/dist/strategies/oauth/github.strategy.d.ts.map +1 -0
- package/dist/strategies/oauth/github.strategy.js +72 -0
- package/dist/strategies/oauth/github.strategy.js.map +1 -0
- package/dist/strategies/oauth/google.strategy.d.ts +31 -0
- package/dist/strategies/oauth/google.strategy.d.ts.map +1 -0
- package/dist/strategies/oauth/google.strategy.js +61 -0
- package/dist/strategies/oauth/google.strategy.js.map +1 -0
- package/dist/strategies/sms/sms.strategy.d.ts +7 -0
- package/dist/strategies/sms/sms.strategy.d.ts.map +1 -0
- package/dist/strategies/sms/sms.strategy.js +39 -0
- package/dist/strategies/sms/sms.strategy.js.map +1 -0
- package/dist/strategies/two-factor/totp.strategy.d.ts +12 -0
- package/dist/strategies/two-factor/totp.strategy.d.ts.map +1 -0
- package/dist/strategies/two-factor/totp.strategy.js +32 -0
- package/dist/strategies/two-factor/totp.strategy.js.map +1 -0
- package/dist/tools/auth-tools.d.ts +200 -0
- package/dist/tools/auth-tools.d.ts.map +1 -0
- package/dist/tools/auth-tools.js +232 -0
- package/dist/tools/auth-tools.js.map +1 -0
- package/dist/tools/sse-manager.d.ts +118 -0
- package/dist/tools/sse-manager.d.ts.map +1 -0
- package/dist/tools/sse-manager.js +163 -0
- package/dist/tools/sse-manager.js.map +1 -0
- package/dist/tools/sse-notify.decorator.d.ts +74 -0
- package/dist/tools/sse-notify.decorator.d.ts.map +1 -0
- package/dist/tools/sse-notify.decorator.js +78 -0
- package/dist/tools/sse-notify.decorator.js.map +1 -0
- package/dist/tools/webhook-action.d.ts +130 -0
- package/dist/tools/webhook-action.d.ts.map +1 -0
- package/dist/tools/webhook-action.js +144 -0
- package/dist/tools/webhook-action.js.map +1 -0
- package/dist/tools/webhook-sender.d.ts +31 -0
- package/dist/tools/webhook-sender.d.ts.map +1 -0
- package/dist/tools/webhook-sender.js +80 -0
- package/dist/tools/webhook-sender.js.map +1 -0
- package/dist/ui-assets/2fa.html +115 -0
- package/dist/ui-assets/account-conflict.html +108 -0
- package/dist/ui-assets/admin.css +263 -0
- package/dist/ui-assets/admin.js +1927 -0
- package/dist/ui-assets/auth.js +725 -0
- package/dist/ui-assets/base.css +219 -0
- package/dist/ui-assets/forgot-password.html +93 -0
- package/dist/ui-assets/link-verify.html +74 -0
- package/dist/ui-assets/login.html +135 -0
- package/dist/ui-assets/magic-link.html +112 -0
- package/dist/ui-assets/register.html +122 -0
- package/dist/ui-assets/reset-password.html +103 -0
- package/dist/ui-assets/ui-i18n-keys.json +78 -0
- package/dist/ui-assets/verify-email.html +66 -0
- package/package.json +89 -0
package/README.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# awesome-node-auth
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
[](https://github.com/sponsors/nik2208)
|
|
7
|
+
|
|
8
|
+
[](https://nodei.co/npm/@awesome-lang-auth/node/)
|
|
9
|
+
|
|
10
|
+
A production-ready, **database-agnostic** JWT authentication library for Node.js written in TypeScript. Drop-in auth for Express, NestJS, Next.js, Fastify and any other Node.js framework — connect to any database through a single interface.
|
|
11
|
+
|
|
12
|
+
> **The self-hosted alternative to Supertokens and Supabase Auth.** Same enterprise-grade features, zero vendor lock-in.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @awesome-lang-auth/node
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> Up to 1.10.0 the package was published as `awesome-node-auth`. To migrate, replace the dependency with `@awesome-lang-auth/node` and change your imports from `'awesome-node-auth'` to `'@awesome-lang-auth/node'`; the API is the same.
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import express from 'express';
|
|
28
|
+
import { AuthConfigurator, AuthEventBus } from '@awesome-lang-auth/node';
|
|
29
|
+
import { myUserStore } from './my-user-store'; // your IUserStore impl
|
|
30
|
+
|
|
31
|
+
const app = express();
|
|
32
|
+
app.use(express.json());
|
|
33
|
+
|
|
34
|
+
const eventBus = new AuthEventBus();
|
|
35
|
+
|
|
36
|
+
const auth = new AuthConfigurator(
|
|
37
|
+
{
|
|
38
|
+
accessTokenSecret: process.env.ACCESS_TOKEN_SECRET!,
|
|
39
|
+
refreshTokenSecret: process.env.REFRESH_TOKEN_SECRET!,
|
|
40
|
+
accessTokenExpiresIn: '15m',
|
|
41
|
+
refreshTokenExpiresIn: '7d',
|
|
42
|
+
},
|
|
43
|
+
myUserStore,
|
|
44
|
+
{ eventBus },
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
app.use(auth.buildAllRouters({
|
|
48
|
+
admin: {
|
|
49
|
+
accessPolicy: 'is-admin-flag', // admin panel for users with isAdmin: true
|
|
50
|
+
},
|
|
51
|
+
})); // mounts /auth/* and /auth/admin/*
|
|
52
|
+
|
|
53
|
+
// Grant the admin panel from a seed script or CLI task (sets isAdmin; needs IUserStore.update):
|
|
54
|
+
// await auth.promoteToAdmin(userId, { method: 'flag' });
|
|
55
|
+
|
|
56
|
+
app.get('/protected', auth.middleware(), (req, res) => {
|
|
57
|
+
res.json({ user: req.user });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
app.listen(3000);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Implement `IUserStore` once for your database and you're done.
|
|
64
|
+
Full DB examples (MongoDB, PostgreSQL, MySQL, in-memory) → [README.detailed.md](./README.detailed.md).
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Features
|
|
69
|
+
|
|
70
|
+
| Area | Highlights |
|
|
71
|
+
|---|---|
|
|
72
|
+
| **Auth strategies** | Email/password · OAuth 2.0 (Google, GitHub, custom) · Magic links · SMS OTP · TOTP 2FA |
|
|
73
|
+
| **Token management** | HttpOnly-cookie or Bearer mode · automatic access/refresh rotation · `__Host-`/`__Secure-` cookie prefixes |
|
|
74
|
+
| **Identity Provider (IdP) mode** *(v1.9)* | RS256-signed JWTs · public JWKS endpoint (`/.well-known/jwks.json`) · Resource Server middleware · zero new dependencies |
|
|
75
|
+
| **Stateful sessions** *(v1.5)* | `ISessionStore` + real-time revocation (`checkOn: allcalls\|refresh\|none`) · works behind your own L1/L2 cache layers |
|
|
76
|
+
| **Dynamic email templates** *(v1.6)* | `ITemplateStore` — per-language mail templates + UI i18n with safe hardcoded fallback · built-in `MemoryTemplateStore` |
|
|
77
|
+
| **CSRF protection** | Double-submit cookie pattern · `__Host-` prefix hardening against cookie-tossing |
|
|
78
|
+
| **Account management** | Registration · change email/password · account deletion · email verification (none/lazy/strict) |
|
|
79
|
+
| **Account linking** | Link multiple OAuth providers · conflict resolution via `IPendingLinkStore` |
|
|
80
|
+
| **RBAC** | `IRolesPermissionsStore` with tenant awareness |
|
|
81
|
+
| **Multi-tenancy** | `ITenantStore` for isolated tenant apps |
|
|
82
|
+
| **Admin panel** | Full-featured admin UI: user management, sessions, roles, tenants, metadata, API keys, webhooks |
|
|
83
|
+
| **Built-in UI** | Zero-dependency HTML/CSS/JS login UI served at `<apiPrefix>/ui/` · **headless mode** for SPAs |
|
|
84
|
+
| **Client libraries** | Angular · Flutter · React · served `auth.js` — see [Ecosystem](#ecosystem) |
|
|
85
|
+
| **Event-driven** | `AuthEventBus` · SSE push · inbound/outbound webhooks · telemetry |
|
|
86
|
+
| **API keys** | M2M bcrypt-hashed keys with scopes, expiry, IP allowlist and audit log |
|
|
87
|
+
| **OpenAPI / Swagger** | Auto-generated specs for auth, admin and tools routers |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Identity Provider (IdP) Mode *(v1.9)*
|
|
92
|
+
|
|
93
|
+
Turn any Provisioner into a central IdP that issues RS256-signed JWTs. Downstream Resource Servers validate tokens via the public JWKS endpoint — no shared secrets.
|
|
94
|
+
|
|
95
|
+
**Generate the RSA private key for your `.env`** (uses Node.js built-in `crypto` — no install needed):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
node -e "
|
|
99
|
+
const { generateKeyPairSync } = require('crypto');
|
|
100
|
+
const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
|
|
101
|
+
const pem = privateKey.export({ type: 'pkcs8', format: 'pem' });
|
|
102
|
+
console.log('IDP_PRIVATE_KEY=' + Buffer.from(pem).toString('base64'));
|
|
103
|
+
"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Then in your config:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Provisioner (IdP)
|
|
110
|
+
const auth = new AuthConfigurator({
|
|
111
|
+
accessTokenSecret: '...',
|
|
112
|
+
refreshTokenSecret: '...',
|
|
113
|
+
idProvider: {
|
|
114
|
+
enabled: true,
|
|
115
|
+
issuer: 'https://auth.myplatform.com',
|
|
116
|
+
privateKey: Buffer.from(process.env.IDP_PRIVATE_KEY!, 'base64').toString('utf8'),
|
|
117
|
+
},
|
|
118
|
+
}, userStore);
|
|
119
|
+
|
|
120
|
+
// Resource Server (downstream)
|
|
121
|
+
import { createJwksAuthMiddleware } from '@awesome-lang-auth/node';
|
|
122
|
+
|
|
123
|
+
app.use('/api', createJwksAuthMiddleware({
|
|
124
|
+
jwksUrl: 'https://auth.myplatform.com/.well-known/jwks.json',
|
|
125
|
+
issuer: 'https://auth.myplatform.com',
|
|
126
|
+
}), myApiRouter);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
> In **development**, if you omit `privateKey` an ephemeral keypair is auto-generated at startup.
|
|
130
|
+
|
|
131
|
+
→ Full guide: [awesomenodeauth.com/docs/advanced/idp-mode](https://awesomenodeauth.com/docs/advanced/idp-mode)
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Key Endpoints
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
POST /auth/login POST /auth/refresh GET /auth/me
|
|
139
|
+
POST /auth/register POST /auth/logout GET /auth/sessions ← device list
|
|
140
|
+
POST /auth/forgot-password POST /auth/change-password DELETE /auth/sessions/:h ← revoke device
|
|
141
|
+
POST /auth/magic-link/send POST /auth/2fa/verify DELETE /auth/account
|
|
142
|
+
GET /auth/oauth/:provider GET /auth/oauth/:provider/callback
|
|
143
|
+
POST /auth/sessions/cleanup POST /auth/add-phone PATCH /auth/profile
|
|
144
|
+
GET /.well-known/jwks.json ← IdP mode only
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Optional Stores Snapshot
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
const auth = new AuthConfigurator(
|
|
153
|
+
{ ...config, templateStore }, // ITemplateStore — dynamic email templates + UI i18n (v1.6), part of AuthConfig
|
|
154
|
+
userStore,
|
|
155
|
+
{ eventBus }, // optional; the third argument only accepts { eventBus }
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
app.use('/auth', auth.router({
|
|
159
|
+
sessionStore, // ISessionStore — stateful sessions + device management
|
|
160
|
+
metadataStore, // IUserMetadataStore — arbitrary per-user key/value pairs
|
|
161
|
+
rbacStore, // IRolesPermissionsStore
|
|
162
|
+
tenantStore, // ITenantStore
|
|
163
|
+
linkedAccountsStore, // ILinkedAccountsStore — several OAuth providers per user
|
|
164
|
+
pendingLinkStore, // IPendingLinkStore — OAuth account-linking conflicts (with linkedAccountsStore)
|
|
165
|
+
}));
|
|
166
|
+
|
|
167
|
+
app.get('/protected', auth.middleware(), handler); // uses the sessionStore passed to router() above (call router() first)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
With `buildAllRouters()`, pass the same stores as `auth: { … }`; the admin panel takes its own in `admin: { … }` (see [Admin UI](#admin-ui)).
|
|
171
|
+
|
|
172
|
+
Full configuration reference → [README.detailed.md § Configuration](./README.detailed.md#configuration)
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Admin UI
|
|
177
|
+
|
|
178
|
+
Use `auth.buildAllRouters({ admin: ... })` to mount both the main auth router and the admin router together. The admin router lives at `/auth/admin/*`, and `jwtSecret` is auto-filled from `AuthConfig.accessTokenSecret`. Set `accessPolicy` (or a non-empty legacy `adminSecret`): without either, the admin routes are mounted **unprotected** and a `WARNING` is written to `stderr`. Without `accessPolicy`, an `adminSecret` that is present but empty (an unset environment variable, for example) throws a configuration error at startup.
|
|
179
|
+
|
|
180
|
+
| `admin` option (`AdminOptions`) | Unlocks |
|
|
181
|
+
|---|---|
|
|
182
|
+
| `sessionStore` | Sessions tab |
|
|
183
|
+
| `rbacStore` | Roles & Permissions tab |
|
|
184
|
+
| `tenantStore` | Tenants tab |
|
|
185
|
+
| `userMetadataStore` | Metadata section in user detail |
|
|
186
|
+
| `settingsStore` | ⚙️ Control tab |
|
|
187
|
+
| `linkedAccountsStore` | Linked Accounts column |
|
|
188
|
+
| `apiKeyStore` | 🔑 API Keys tab |
|
|
189
|
+
| `webhookStore` | 🔗 Webhooks tab |
|
|
190
|
+
| `templateStore` | Email & UI tab |
|
|
191
|
+
| `uploadDir` (optionally `uploadBaseUrl`) | Logo upload in branding |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Two login endpoints, two audiences
|
|
196
|
+
|
|
197
|
+
- `/auth/ui/login` — end-user login for your application (built-in UI, `ui: { enabled: true }`)
|
|
198
|
+
- `/auth/admin/` — admin panel for operators (its sign-in form posts to `/auth/admin/login`)
|
|
199
|
+
|
|
200
|
+
They are intentionally different flows. If you mount the admin UI for operators, keep linking end users to `/auth/ui/login`.
|
|
201
|
+
|
|
202
|
+
The admin sign-in form checks the password only, with no second factor, and its session opens the admin console and nothing else. To send operators through the application login and its 2FA flow, set `admin.loginPath: '/auth/ui/login'` (after signing in they land on `/`; reopen `/auth/admin/`). `POST /auth/admin/login` stays mounted and still accepts the password alone, so block it at your proxy if operators must always pass 2FA.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Ecosystem
|
|
207
|
+
|
|
208
|
+
`awesome-node-auth` is the reference server of a family of libraries that port its HTTP API to other runtimes, plus client libraries for that API.
|
|
209
|
+
|
|
210
|
+
**Servers**
|
|
211
|
+
|
|
212
|
+
| Runtime | Repository | Status |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| Node.js | [`awesome-node-auth`](https://github.com/nik2208/awesome-node-auth) (this repo) | npm `@awesome-lang-auth/node` |
|
|
215
|
+
| Go | [`awesome-go-auth`](https://github.com/awesome-lang-auth/awesome-go-auth) | Go module, 0.11.x · 1.0 in progress |
|
|
216
|
+
| AWS Lambda | [`awesome-lambda-auth`](https://github.com/awesome-lang-auth/awesome-lambda-auth) | Preview |
|
|
217
|
+
| Python | [`awesome-python-auth`](https://github.com/awesome-lang-auth/awesome-python-auth) | PyPI `awesome-python-auth` 1.1.0 |
|
|
218
|
+
| Rust | [`awesome-rust-auth`](https://github.com/awesome-lang-auth/awesome-rust-auth) | Git only (not on crates.io) |
|
|
219
|
+
| Dart | [`awesome-dart-auth`](https://github.com/awesome-lang-auth/awesome-dart-auth) | Git only (not on pub.dev) |
|
|
220
|
+
|
|
221
|
+
**Clients**
|
|
222
|
+
|
|
223
|
+
| Client | Package | Status |
|
|
224
|
+
|---|---|---|
|
|
225
|
+
| Angular | [`ng-awesome-node-auth`](https://github.com/awesome-lang-auth/awesome-angular-auth) | npm · to be renamed `@awesome-lang-auth/angular` |
|
|
226
|
+
| Flutter | [`awesome_node_auth_flutter`](https://github.com/awesome-lang-auth/awesome-flutter-auth) | pub.dev · to be renamed `awesome_flutter_auth` |
|
|
227
|
+
| React | [`@awesome-lang-auth/react`](https://github.com/awesome-lang-auth/awesome-react-auth) | npm 0.1.0 |
|
|
228
|
+
| Browser | `auth.js` | Served by this library at `<apiPrefix>/ui/auth.js` when `ui.enabled` is set — see [Including `auth.js`](./README.detailed.md#including-authjs) |
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Documentation
|
|
233
|
+
|
|
234
|
+
| Resource | Link |
|
|
235
|
+
|---|---|
|
|
236
|
+
| **Full reference** | [README.detailed.md](./README.detailed.md) |
|
|
237
|
+
| **Wiki / Guides** | [awesomenodeauth.com](https://awesomenodeauth.com) |
|
|
238
|
+
| **Changelog** | [CHANGELOG.md](./CHANGELOG.md) |
|
|
239
|
+
| **Demo apps** | [demo/](./demo) |
|
|
240
|
+
| **Framework examples** | [examples/](./examples) |
|
|
241
|
+
|
|
242
|
+
> The companion MCP server (`awesome-node-auth-mcp-server`) has been retired and is no longer available.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
[MIT](./LICENSE) · © 2026 nik2208 · [Sponsor ❤](https://github.com/sponsors/nik2208)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AuthConfig } from '../models/auth-config.model';
|
|
2
|
+
import { BaseUser } from '../models/user.model';
|
|
3
|
+
export declare abstract class BaseAuthStrategy<TInput = unknown, TUser = BaseUser> {
|
|
4
|
+
abstract name: string;
|
|
5
|
+
abstract authenticate(input: TInput, config: AuthConfig): Promise<TUser>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=base-auth-strategy.abstract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-auth-strategy.abstract.d.ts","sourceRoot":"","sources":["../../src/abstract/base-auth-strategy.abstract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,8BAAsB,gBAAgB,CAAC,MAAM,GAAG,OAAO,EAAE,KAAK,GAAG,QAAQ;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;CACzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-auth-strategy.abstract.js","sourceRoot":"","sources":["../../src/abstract/base-auth-strategy.abstract.ts"],"names":[],"mappings":";;;AAGA,MAAsB,gBAAgB;CAGrC;AAHD,4CAGC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AuthConfig } from '../models/auth-config.model';
|
|
2
|
+
import { BaseUser } from '../models/user.model';
|
|
3
|
+
import { BaseAuthStrategy } from './base-auth-strategy.abstract';
|
|
4
|
+
export declare abstract class BaseOAuthStrategy<TUser extends BaseUser = BaseUser> extends BaseAuthStrategy<{
|
|
5
|
+
code: string;
|
|
6
|
+
state?: string;
|
|
7
|
+
}, TUser> {
|
|
8
|
+
abstract name: string;
|
|
9
|
+
abstract getAuthorizationUrl(state?: string): string;
|
|
10
|
+
abstract handleCallback(code: string, state?: string): Promise<TUser>;
|
|
11
|
+
protected abstract exchangeCodeForTokens(code: string): Promise<{
|
|
12
|
+
accessToken: string;
|
|
13
|
+
idToken?: string;
|
|
14
|
+
}>;
|
|
15
|
+
protected abstract getUserProfile(accessToken: string): Promise<{
|
|
16
|
+
id: string;
|
|
17
|
+
email: string;
|
|
18
|
+
emailVerified?: boolean;
|
|
19
|
+
name?: string;
|
|
20
|
+
picture?: string;
|
|
21
|
+
}>;
|
|
22
|
+
authenticate(input: {
|
|
23
|
+
code: string;
|
|
24
|
+
state?: string;
|
|
25
|
+
}, _config: AuthConfig): Promise<TUser>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=base-oauth-strategy.abstract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-oauth-strategy.abstract.d.ts","sourceRoot":"","sources":["../../src/abstract/base-oauth-strategy.abstract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,8BAAsB,iBAAiB,CAAC,KAAK,SAAS,QAAQ,GAAG,QAAQ,CAAE,SAAQ,gBAAgB,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,CAAC;IAC1I,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IACpD,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IACrE,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1G,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAElJ,YAAY,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;CAGjG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseOAuthStrategy = void 0;
|
|
4
|
+
const base_auth_strategy_abstract_1 = require("./base-auth-strategy.abstract");
|
|
5
|
+
class BaseOAuthStrategy extends base_auth_strategy_abstract_1.BaseAuthStrategy {
|
|
6
|
+
async authenticate(input, _config) {
|
|
7
|
+
return this.handleCallback(input.code, input.state);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.BaseOAuthStrategy = BaseOAuthStrategy;
|
|
11
|
+
//# sourceMappingURL=base-oauth-strategy.abstract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-oauth-strategy.abstract.js","sourceRoot":"","sources":["../../src/abstract/base-oauth-strategy.abstract.ts"],"names":[],"mappings":";;;AAEA,+EAAiE;AAEjE,MAAsB,iBAAqD,SAAQ,8CAAyD;IAQ1I,KAAK,CAAC,YAAY,CAAC,KAAuC,EAAE,OAAmB;QAC7E,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;CACF;AAXD,8CAWC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Express adapter for awesome-node-auth.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the Express `Router` and `RequestHandler` types so that Express
|
|
5
|
+
* applications can import them from a single, well-known path within the
|
|
6
|
+
* library.
|
|
7
|
+
*
|
|
8
|
+
* The `expressAdapter` helper is a zero-overhead cast: it accepts an
|
|
9
|
+
* `AuthRequestHandler` written against the framework-neutral types and returns
|
|
10
|
+
* the same function typed as an Express `RequestHandler`, bridging the two
|
|
11
|
+
* type systems without any runtime cost.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { expressAdapter } from '@awesome-lang-auth/node';
|
|
16
|
+
* import type { AuthRequestHandler } from '@awesome-lang-auth/node';
|
|
17
|
+
*
|
|
18
|
+
* const myMiddleware: AuthRequestHandler = (req, res, next) => {
|
|
19
|
+
* // logic here
|
|
20
|
+
* next();
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* // Mount on an Express app with proper Express types:
|
|
24
|
+
* app.use(expressAdapter(myMiddleware));
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @since 1.7.0
|
|
28
|
+
*/
|
|
29
|
+
import { Router, RequestHandler, Request, Response, NextFunction } from 'express';
|
|
30
|
+
import type { AuthRequestHandler } from '../http-types';
|
|
31
|
+
export { Router, RequestHandler };
|
|
32
|
+
export type { Request, Response, NextFunction };
|
|
33
|
+
/**
|
|
34
|
+
* Cast an `AuthRequestHandler` (framework-neutral) to an Express
|
|
35
|
+
* `RequestHandler`.
|
|
36
|
+
*
|
|
37
|
+
* There is no runtime overhead — the original function reference is returned
|
|
38
|
+
* unchanged; only the TypeScript type is adjusted. Use this when you write
|
|
39
|
+
* middleware against the neutral `AuthRequestHandler` interface and need to
|
|
40
|
+
* pass it to `app.use()` / `router.use()` with correct Express typing.
|
|
41
|
+
*
|
|
42
|
+
* @since 1.7.0
|
|
43
|
+
*/
|
|
44
|
+
export declare function expressAdapter(handler: AuthRequestHandler): RequestHandler;
|
|
45
|
+
//# sourceMappingURL=express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;AAClC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAE1E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Express adapter for awesome-node-auth.
|
|
4
|
+
*
|
|
5
|
+
* Re-exports the Express `Router` and `RequestHandler` types so that Express
|
|
6
|
+
* applications can import them from a single, well-known path within the
|
|
7
|
+
* library.
|
|
8
|
+
*
|
|
9
|
+
* The `expressAdapter` helper is a zero-overhead cast: it accepts an
|
|
10
|
+
* `AuthRequestHandler` written against the framework-neutral types and returns
|
|
11
|
+
* the same function typed as an Express `RequestHandler`, bridging the two
|
|
12
|
+
* type systems without any runtime cost.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { expressAdapter } from '@awesome-lang-auth/node';
|
|
17
|
+
* import type { AuthRequestHandler } from '@awesome-lang-auth/node';
|
|
18
|
+
*
|
|
19
|
+
* const myMiddleware: AuthRequestHandler = (req, res, next) => {
|
|
20
|
+
* // logic here
|
|
21
|
+
* next();
|
|
22
|
+
* };
|
|
23
|
+
*
|
|
24
|
+
* // Mount on an Express app with proper Express types:
|
|
25
|
+
* app.use(expressAdapter(myMiddleware));
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @since 1.7.0
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.Router = void 0;
|
|
32
|
+
exports.expressAdapter = expressAdapter;
|
|
33
|
+
const express_1 = require("express");
|
|
34
|
+
Object.defineProperty(exports, "Router", { enumerable: true, get: function () { return express_1.Router; } });
|
|
35
|
+
/**
|
|
36
|
+
* Cast an `AuthRequestHandler` (framework-neutral) to an Express
|
|
37
|
+
* `RequestHandler`.
|
|
38
|
+
*
|
|
39
|
+
* There is no runtime overhead — the original function reference is returned
|
|
40
|
+
* unchanged; only the TypeScript type is adjusted. Use this when you write
|
|
41
|
+
* middleware against the neutral `AuthRequestHandler` interface and need to
|
|
42
|
+
* pass it to `app.use()` / `router.use()` with correct Express typing.
|
|
43
|
+
*
|
|
44
|
+
* @since 1.7.0
|
|
45
|
+
*/
|
|
46
|
+
function expressAdapter(handler) {
|
|
47
|
+
return handler;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;AAmBH,wCAEC;AAnBD,qCAAkF;AAGzE,uFAHA,gBAAM,OAGA;AAGf;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,OAA2B;IACxD,OAAO,OAAoC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fastify adapter for awesome-node-auth.
|
|
3
|
+
*
|
|
4
|
+
* Bridges an `AuthRequestHandler` to Fastify's `preHandler` hook by
|
|
5
|
+
* delegating to `req.raw` / `reply.raw` — the underlying Node.js
|
|
6
|
+
* `IncomingMessage` / `ServerResponse` objects that Fastify exposes on
|
|
7
|
+
* every request and reply.
|
|
8
|
+
*
|
|
9
|
+
* **No extra dependencies required.** This adapter works with any Fastify
|
|
10
|
+
* version that exposes `.raw` on its request and reply objects (v3+).
|
|
11
|
+
*
|
|
12
|
+
* For mounting the full auth **router** (not just middleware) you still need
|
|
13
|
+
* `@fastify/express`, because `auth.router()` returns an Express `Router`
|
|
14
|
+
* that relies on Express-specific request decoration.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import Fastify from 'fastify';
|
|
19
|
+
* import { fastifyAdapter } from '@awesome-lang-auth/node';
|
|
20
|
+
* import { createAuthMiddleware } from '@awesome-lang-auth/node';
|
|
21
|
+
*
|
|
22
|
+
* const fastify = Fastify();
|
|
23
|
+
* const authMiddleware = createAuthMiddleware(authConfig, userStore);
|
|
24
|
+
*
|
|
25
|
+
* // Protect all routes — verify the JWT on every request.
|
|
26
|
+
* fastify.addHook('preHandler', fastifyAdapter(authMiddleware));
|
|
27
|
+
*
|
|
28
|
+
* fastify.get('/profile', async (request) => {
|
|
29
|
+
* return request.raw.user; // populated by awesome-node-auth middleware
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @since 1.7.0
|
|
34
|
+
*/
|
|
35
|
+
import type { AuthRequestHandler } from '../http-types';
|
|
36
|
+
/**
|
|
37
|
+
* Minimal duck-typed surface we use from a Fastify request.
|
|
38
|
+
* Avoids a hard dependency on the `fastify` package.
|
|
39
|
+
*/
|
|
40
|
+
interface FastifyLikeRequest {
|
|
41
|
+
raw: any;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Minimal duck-typed surface we use from a Fastify reply.
|
|
45
|
+
* Avoids a hard dependency on the `fastify` package.
|
|
46
|
+
*/
|
|
47
|
+
interface FastifyLikeReply {
|
|
48
|
+
raw: any;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wrap an `AuthRequestHandler` as a Fastify `preHandler` hook.
|
|
52
|
+
*
|
|
53
|
+
* The adapter forwards `req.raw` and `reply.raw` (the underlying Node.js
|
|
54
|
+
* `IncomingMessage` and `ServerResponse`) to the handler, so that
|
|
55
|
+
* awesome-node-auth middleware operates on the same objects it would receive
|
|
56
|
+
* from Express.
|
|
57
|
+
*
|
|
58
|
+
* There is no runtime overhead beyond the extra function call; the original
|
|
59
|
+
* handler is invoked directly.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { fastifyAdapter } from '@awesome-lang-auth/node';
|
|
64
|
+
*
|
|
65
|
+
* fastify.addHook('preHandler', fastifyAdapter(authMiddleware));
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @since 1.7.0
|
|
69
|
+
*/
|
|
70
|
+
export declare function fastifyAdapter(handler: AuthRequestHandler): (req: FastifyLikeRequest, reply: FastifyLikeReply, done: (err?: Error) => void) => void;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=fastify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../src/adapters/fastify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD;;;GAGG;AACH,UAAU,kBAAkB;IAE1B,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;GAGG;AACH,UAAU,gBAAgB;IAExB,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,kBAAkB,GAC1B,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,CAIzF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fastify adapter for awesome-node-auth.
|
|
4
|
+
*
|
|
5
|
+
* Bridges an `AuthRequestHandler` to Fastify's `preHandler` hook by
|
|
6
|
+
* delegating to `req.raw` / `reply.raw` — the underlying Node.js
|
|
7
|
+
* `IncomingMessage` / `ServerResponse` objects that Fastify exposes on
|
|
8
|
+
* every request and reply.
|
|
9
|
+
*
|
|
10
|
+
* **No extra dependencies required.** This adapter works with any Fastify
|
|
11
|
+
* version that exposes `.raw` on its request and reply objects (v3+).
|
|
12
|
+
*
|
|
13
|
+
* For mounting the full auth **router** (not just middleware) you still need
|
|
14
|
+
* `@fastify/express`, because `auth.router()` returns an Express `Router`
|
|
15
|
+
* that relies on Express-specific request decoration.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import Fastify from 'fastify';
|
|
20
|
+
* import { fastifyAdapter } from '@awesome-lang-auth/node';
|
|
21
|
+
* import { createAuthMiddleware } from '@awesome-lang-auth/node';
|
|
22
|
+
*
|
|
23
|
+
* const fastify = Fastify();
|
|
24
|
+
* const authMiddleware = createAuthMiddleware(authConfig, userStore);
|
|
25
|
+
*
|
|
26
|
+
* // Protect all routes — verify the JWT on every request.
|
|
27
|
+
* fastify.addHook('preHandler', fastifyAdapter(authMiddleware));
|
|
28
|
+
*
|
|
29
|
+
* fastify.get('/profile', async (request) => {
|
|
30
|
+
* return request.raw.user; // populated by awesome-node-auth middleware
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @since 1.7.0
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.fastifyAdapter = fastifyAdapter;
|
|
38
|
+
/**
|
|
39
|
+
* Wrap an `AuthRequestHandler` as a Fastify `preHandler` hook.
|
|
40
|
+
*
|
|
41
|
+
* The adapter forwards `req.raw` and `reply.raw` (the underlying Node.js
|
|
42
|
+
* `IncomingMessage` and `ServerResponse`) to the handler, so that
|
|
43
|
+
* awesome-node-auth middleware operates on the same objects it would receive
|
|
44
|
+
* from Express.
|
|
45
|
+
*
|
|
46
|
+
* There is no runtime overhead beyond the extra function call; the original
|
|
47
|
+
* handler is invoked directly.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { fastifyAdapter } from '@awesome-lang-auth/node';
|
|
52
|
+
*
|
|
53
|
+
* fastify.addHook('preHandler', fastifyAdapter(authMiddleware));
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @since 1.7.0
|
|
57
|
+
*/
|
|
58
|
+
function fastifyAdapter(handler) {
|
|
59
|
+
return (req, reply, done) => {
|
|
60
|
+
handler(req.raw, reply.raw, done);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=fastify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/adapters/fastify.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;AA0CH,wCAMC;AA1BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,cAAc,CAC5B,OAA2B;IAE3B,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Router, RequestHandler } from 'express';
|
|
2
|
+
import { AuthConfig } from './models/auth-config.model';
|
|
3
|
+
import { IUserStore } from './interfaces/user-store.interface';
|
|
4
|
+
import { TokenService } from './services/token.service';
|
|
5
|
+
import { PasswordService } from './services/password.service';
|
|
6
|
+
import { LocalStrategy } from './strategies/local/local.strategy';
|
|
7
|
+
import { GoogleStrategy } from './strategies/oauth/google.strategy';
|
|
8
|
+
import { GithubStrategy } from './strategies/oauth/github.strategy';
|
|
9
|
+
import { RouterOptions } from './router/auth.router';
|
|
10
|
+
import { ISessionStore } from './interfaces/session-store.interface';
|
|
11
|
+
import { AdminOptions, AdminAccessPolicy } from './router/admin.router';
|
|
12
|
+
import { AuthEventBus } from './events/auth-event-bus';
|
|
13
|
+
import { IRolesPermissionsStore } from './interfaces/roles-permissions-store.interface';
|
|
14
|
+
export interface AuthConfiguratorOptions {
|
|
15
|
+
eventBus?: AuthEventBus;
|
|
16
|
+
}
|
|
17
|
+
type BuildAllRoutersAdminOptions = Omit<AdminOptions, 'jwtSecret' | 'apiPrefix' | 'eventBus'> & {
|
|
18
|
+
jwtSecret?: string;
|
|
19
|
+
apiPrefix?: string;
|
|
20
|
+
eventBus?: AuthEventBus;
|
|
21
|
+
};
|
|
22
|
+
export interface BuildAllRoutersOptions {
|
|
23
|
+
auth?: RouterOptions;
|
|
24
|
+
/**
|
|
25
|
+
* Options for the admin router. `accessPolicy` (or a non-empty legacy
|
|
26
|
+
* `adminSecret`) is required: without either, `createAdminRouter` mounts the
|
|
27
|
+
* admin routes unprotected. The type cannot reject an empty `adminSecret`;
|
|
28
|
+
* `createAdminRouter` throws on it at runtime. Pass `accessPolicy: 'open'`
|
|
29
|
+
* to opt out explicitly.
|
|
30
|
+
*/
|
|
31
|
+
admin: BuildAllRoutersAdminOptions & ({
|
|
32
|
+
accessPolicy: AdminAccessPolicy;
|
|
33
|
+
} | {
|
|
34
|
+
adminSecret: string;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export declare class AuthConfigurator {
|
|
38
|
+
private readonly config;
|
|
39
|
+
private readonly userStore;
|
|
40
|
+
private readonly options;
|
|
41
|
+
private readonly _tokenService;
|
|
42
|
+
private readonly _passwordService;
|
|
43
|
+
private _sessionStore?;
|
|
44
|
+
constructor(config: AuthConfig, userStore: IUserStore, options?: AuthConfiguratorOptions);
|
|
45
|
+
middleware(options?: {
|
|
46
|
+
sessionStore?: ISessionStore;
|
|
47
|
+
}): RequestHandler;
|
|
48
|
+
router(options?: RouterOptions): Router;
|
|
49
|
+
buildAllRouters(options: BuildAllRoutersOptions): Router;
|
|
50
|
+
promoteToAdmin(userId: string, options?: {
|
|
51
|
+
method?: 'flag' | 'role';
|
|
52
|
+
rbacStore?: IRolesPermissionsStore;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
revokeAdmin(userId: string, options?: {
|
|
55
|
+
method?: 'flag' | 'role' | 'both';
|
|
56
|
+
rbacStore?: IRolesPermissionsStore;
|
|
57
|
+
}): Promise<void>;
|
|
58
|
+
get tokenService(): TokenService;
|
|
59
|
+
get passwordService(): PasswordService;
|
|
60
|
+
strategy(name: 'local'): LocalStrategy;
|
|
61
|
+
strategy(name: 'google'): GoogleStrategy;
|
|
62
|
+
strategy(name: 'github'): GithubStrategy;
|
|
63
|
+
}
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=auth-configurator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-configurator.d.ts","sourceRoot":"","sources":["../src/auth-configurator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAsC,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAqB,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AAGxF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,KAAK,2BAA2B,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC,GAAG;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;;;;OAMG;IACH,KAAK,EAAE,2BAA2B,GAAG,CAAC;QAAE,YAAY,EAAE,iBAAiB,CAAA;KAAE,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtG;AAMD,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAGnB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,UAAU,EACrB,OAAO,GAAE,uBAA4B;IAMxD,UAAU,CAAC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,aAAa,CAAA;KAAE,GAAG,cAAc;IAItE,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IAUvC,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM;IAkBlD,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,sBAAsB,CAAA;KAAO,GAC7E,OAAO,CAAC,IAAI,CAAC;IA8BV,WAAW,CACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,sBAAsB,CAAA;KAAO,GACtF,OAAO,CAAC,IAAI,CAAC;IAoChB,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED,IAAI,eAAe,IAAI,eAAe,CAErC;IAED,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa;IACtC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc;IACxC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc;CAazC"}
|