@dax-crafta/auth 2.1.6 → 2.1.8
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/.mocharc.cjs +6 -0
- package/README.md +167 -274
- package/image.png +0 -0
- package/package.json +6 -2
- package/src/index.d.ts +213 -107
- package/src/index.js +669 -442
- package/src/middlewares/auth.middleware.js +64 -19
- package/src/middlewares/cors.middleware.js +73 -0
- package/src/middlewares/validation.middleware.js +2 -1
- package/src/models/user.js +12 -12
- package/src/services/audit.service.js +66 -0
- package/src/services/auth.service.js +71 -42
- package/src/services/passwordless.service.js +66 -0
- package/src/services/role.service.js +5 -0
- package/src/services/session.service.js +141 -0
- package/src/services/webhook.service.js +134 -0
- package/src/utils/api-error.js +165 -8
- package/src/utils/email.js +57 -11
- package/src/utils/mfa.js +27 -18
- package/src/utils/password-policy.js +6 -1
- package/src/utils/password-strength.js +68 -0
- package/test/01-register-login.test.js +134 -0
- package/test/02-password-reset.test.js +50 -0
- package/test/03-2fa.test.js +54 -0
- package/test/04-rbac.test.js +51 -0
- package/test/05-audit-webhook.test.js +78 -0
- package/test/06-sessions.test.js +36 -0
- package/test/07-error-normalization.test.js +64 -0
- package/test/08-cors-health.test.js +45 -0
- package/test/09-passwordless.test.js +40 -0
- package/test/10-webhook-signing.test.js +37 -0
- package/test/helpers.js +130 -0
- package/test/run-tests.js +94 -0
- package/test/tiny-test.js +68 -0
package/.mocharc.cjs
ADDED
package/README.md
CHANGED
|
@@ -1,274 +1,167 @@
|
|
|
1
|
-
# @dax-crafta/auth
|
|
2
|
-
|
|
3
|
-
Production-ready
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@dax-crafta/auth)
|
|
6
|
-
[](https://github.com/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
auditLogs: true,
|
|
169
|
-
twoFactor: true,
|
|
170
|
-
csrf: false
|
|
171
|
-
}
|
|
172
|
-
})(app);
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Notes:
|
|
176
|
-
- If SMTP is missing, emailVerification/loginAlerts are auto-disabled with warning.
|
|
177
|
-
- If `securityAttempts: false`, lockout attempt handling is disabled.
|
|
178
|
-
|
|
179
|
-
## 6. Email setup (optional)
|
|
180
|
-
|
|
181
|
-
Enable this only when SMTP is ready:
|
|
182
|
-
|
|
183
|
-
```js
|
|
184
|
-
auth({
|
|
185
|
-
features: {
|
|
186
|
-
emailVerification: true,
|
|
187
|
-
loginAlerts: true
|
|
188
|
-
},
|
|
189
|
-
smtp: {
|
|
190
|
-
host: process.env.SMTP_HOST,
|
|
191
|
-
port: Number(process.env.SMTP_PORT || 587),
|
|
192
|
-
auth: {
|
|
193
|
-
user: process.env.SMTP_USER,
|
|
194
|
-
pass: process.env.SMTP_PASS
|
|
195
|
-
},
|
|
196
|
-
from: process.env.SMTP_FROM
|
|
197
|
-
},
|
|
198
|
-
baseUrl: process.env.BASE_URL || 'http://localhost:3000'
|
|
199
|
-
})(app);
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## 7. Google OAuth setup (optional)
|
|
203
|
-
|
|
204
|
-
```js
|
|
205
|
-
auth({
|
|
206
|
-
social: {
|
|
207
|
-
google: {
|
|
208
|
-
clientID: process.env.GOOGLE_CLIENT_ID,
|
|
209
|
-
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
210
|
-
callbackURL: 'http://localhost:3000/auth/google/callback'
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
})(app);
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Routes:
|
|
217
|
-
- `GET /auth/google`
|
|
218
|
-
- `GET /auth/google/callback`
|
|
219
|
-
|
|
220
|
-
## 8. RBAC quick use
|
|
221
|
-
|
|
222
|
-
```js
|
|
223
|
-
const role = await app.roleService.createRole({
|
|
224
|
-
name: 'admin',
|
|
225
|
-
permissions: [
|
|
226
|
-
{ resource: 'users', actions: ['create', 'read', 'update', 'delete'] }
|
|
227
|
-
]
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
const allowed = await app.roleService.checkPermission('admin', 'users', 'delete');
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## 9. Environment variables
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
JWT_SECRET=my-super-secret
|
|
237
|
-
MONGO_URL=mongodb://127.0.0.1:27017/crafta-auth-demo
|
|
238
|
-
SMTP_HOST=smtp.example.com
|
|
239
|
-
SMTP_PORT=587
|
|
240
|
-
SMTP_USER=you@example.com
|
|
241
|
-
SMTP_PASS=your-password
|
|
242
|
-
SMTP_FROM=noreply@example.com
|
|
243
|
-
BASE_URL=http://localhost:3000
|
|
244
|
-
GOOGLE_CLIENT_ID=...
|
|
245
|
-
GOOGLE_CLIENT_SECRET=...
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## 10. Troubleshooting
|
|
249
|
-
|
|
250
|
-
- 401 on protected route
|
|
251
|
-
- Token missing or expired.
|
|
252
|
-
- Send `Authorization: Bearer <accessToken>`.
|
|
253
|
-
|
|
254
|
-
- Register fails on password policy
|
|
255
|
-
- Use uppercase + lowercase + number + special char.
|
|
256
|
-
|
|
257
|
-
- Email not sending
|
|
258
|
-
- Check SMTP credentials and port.
|
|
259
|
-
- If SMTP absent, email features auto-disable by design.
|
|
260
|
-
|
|
261
|
-
- Refresh token invalid
|
|
262
|
-
- Refresh token is rotated; use latest token returned by API.
|
|
263
|
-
|
|
264
|
-
## 11. Release confidence
|
|
265
|
-
|
|
266
|
-
- Built-in smoke suite is available:
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
npm test
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## License
|
|
273
|
-
|
|
274
|
-
MIT © Dax Crafta
|
|
1
|
+
# @dax-crafta/auth
|
|
2
|
+
|
|
3
|
+
Production-ready authentication library for Crafta apps, featuring plug-and-play defaults, robust security, and clean JSON-based customization.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@dax-crafta/auth)
|
|
6
|
+
[](https://github.com/NPM-crafta/crafta-auth/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
1. **JWT Authentication**: Secure sessions with automatic refresh token rotation.
|
|
10
|
+
2. **Standard Routes**: Built-in register, login, verify email, forgot/reset password, and refresh routes.
|
|
11
|
+
3. **Multi-Factor Authentication (MFA)**: Optional TOTP-based 2FA with backup codes support.
|
|
12
|
+
4. **RBAC**: Role-Based Access Control service to manage permissions and roles.
|
|
13
|
+
5. **Rate Limiting**: Route-level protection for sensitive endpoints (login, register, 2FA).
|
|
14
|
+
6. **Password Policy**: Strict policy enforcement with password history checks and strength validation.
|
|
15
|
+
7. **Google OAuth**: Optional social login integration.
|
|
16
|
+
8. **Audit Logs**: Comprehensive logging to MongoDB and local files.
|
|
17
|
+
9. **Session Management**: Full session control with per-user session limits and global logout.
|
|
18
|
+
10. **Webhooks**: Real-time event notifications for auth lifecycle events (registered, login, logout, password change).
|
|
19
|
+
11. **Passwordless Login**: Magic link authentication.
|
|
20
|
+
12. **Standardized Error Handling**: Unified error format with 19 distinct `AUTH_*` codes.
|
|
21
|
+
13. **CORS Middleware**: Explicit origin whitelisting for secure cross-origin requests.
|
|
22
|
+
14. **Customizable Fields**: Flexible user model customization.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
```bash
|
|
26
|
+
npm install @dax-crafta/auth
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Minimal Setup
|
|
30
|
+
```javascript
|
|
31
|
+
const { crafta } = require('crafta');
|
|
32
|
+
const { auth } = require('@dax-crafta/auth');
|
|
33
|
+
|
|
34
|
+
const app = crafta();
|
|
35
|
+
|
|
36
|
+
auth({
|
|
37
|
+
env: {
|
|
38
|
+
JWT_SECRET: process.env.JWT_SECRET || 'dev-secret-123'
|
|
39
|
+
},
|
|
40
|
+
mongoUrl: process.env.MONGO_URL || 'mongodb://127.0.0.1:27017/crafta-auth-demo'
|
|
41
|
+
})(app);
|
|
42
|
+
|
|
43
|
+
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Configuration Options
|
|
47
|
+
The library is configured via a single object passed to the `auth()` function:
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
auth({
|
|
51
|
+
strategy: 'jwt', // Currently defaults to 'jwt'
|
|
52
|
+
fields: ['name', 'email', 'password'],
|
|
53
|
+
routes: { /* Custom route paths */ },
|
|
54
|
+
passwordPolicy: {
|
|
55
|
+
minLength: 8,
|
|
56
|
+
requireUppercase: true,
|
|
57
|
+
requireNumbers: true,
|
|
58
|
+
requireSpecialChars: true,
|
|
59
|
+
expiryDays: 90
|
|
60
|
+
},
|
|
61
|
+
limits: {
|
|
62
|
+
loginMax: 10,
|
|
63
|
+
registerMax: 20
|
|
64
|
+
}
|
|
65
|
+
})(app);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Feature Toggles
|
|
69
|
+
Enable or disable features via the `features` object:
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
auth({
|
|
73
|
+
features: {
|
|
74
|
+
emailVerification: true,
|
|
75
|
+
twoFactor: true,
|
|
76
|
+
passwordless: false,
|
|
77
|
+
auditLogs: true,
|
|
78
|
+
webhooks: false,
|
|
79
|
+
rateLimit: true,
|
|
80
|
+
csrf: false
|
|
81
|
+
}
|
|
82
|
+
})(app);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Email Setup
|
|
86
|
+
Configure SMTP to enable email-based features (Verification, Forgot Password, Magic Links, Login Alerts):
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
auth({
|
|
90
|
+
smtp: {
|
|
91
|
+
host: process.env.SMTP_HOST,
|
|
92
|
+
port: 587,
|
|
93
|
+
auth: {
|
|
94
|
+
user: process.env.SMTP_USER,
|
|
95
|
+
pass: process.env.SMTP_PASS
|
|
96
|
+
},
|
|
97
|
+
from: process.env.SMTP_FROM
|
|
98
|
+
},
|
|
99
|
+
baseUrl: 'http://localhost:3000'
|
|
100
|
+
})(app);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Google OAuth Setup
|
|
104
|
+
```javascript
|
|
105
|
+
auth({
|
|
106
|
+
social: {
|
|
107
|
+
google: {
|
|
108
|
+
clientID: process.env.GOOGLE_CLIENT_ID,
|
|
109
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
110
|
+
callbackURL: 'http://localhost:3000/auth/google/callback'
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
})(app);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## RBAC Quick Use
|
|
117
|
+
Access the role service directly from your app instance:
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
// Check permission
|
|
121
|
+
const allowed = await app.roleService.checkPermission('admin', 'users', 'delete');
|
|
122
|
+
|
|
123
|
+
// Create role
|
|
124
|
+
await app.roleService.createRole({
|
|
125
|
+
name: 'editor',
|
|
126
|
+
permissions: [{ resource: 'posts', actions: ['create', 'update'] }]
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Environment Variables
|
|
131
|
+
- `JWT_SECRET`: Secret key for signing tokens.
|
|
132
|
+
- `MONGO_URL`: MongoDB connection string.
|
|
133
|
+
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS`, `SMTP_FROM`: SMTP configuration.
|
|
134
|
+
- `BASE_URL`: Base URL for email links.
|
|
135
|
+
- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`: Google OAuth credentials.
|
|
136
|
+
|
|
137
|
+
## Troubleshooting
|
|
138
|
+
- **401 Unauthorized**: Check if `Authorization: Bearer <accessToken>` header is present and valid.
|
|
139
|
+
- **Password policy errors**: Ensure passwords meet length, uppercase, number, and special character requirements.
|
|
140
|
+
- **Email issues**: Verify SMTP configuration; features relying on email will automatically disable if SMTP is misconfigured.
|
|
141
|
+
|
|
142
|
+
## Error Codes
|
|
143
|
+
| Code | Description | HTTP Status |
|
|
144
|
+
| :--- | :--- | :--- |
|
|
145
|
+
| `AUTH_BAD_REQUEST` | Generic bad request error | 400 |
|
|
146
|
+
| `AUTH_VALIDATION` | Invalid request data | 400 |
|
|
147
|
+
| `AUTH_PASSWORD_POLICY` | Password policy violation | 400 |
|
|
148
|
+
| `AUTH_PASSWORD_REUSE` | Cannot reuse previous passwords | 400 |
|
|
149
|
+
| `AUTH_SOCIAL_FAILED` | Social login failure | 400 |
|
|
150
|
+
| `AUTH_INVALID_ID` | Invalid resource identifier | 400 |
|
|
151
|
+
| `AUTH_UNAUTHORIZED` | Authentication required | 401 |
|
|
152
|
+
| `AUTH_INVALID_CREDENTIALS` | Invalid email or password | 401 |
|
|
153
|
+
| `AUTH_INVALID_TOKEN` | Token invalid or missing | 401 |
|
|
154
|
+
| `AUTH_EXPIRED_TOKEN` | Token expired | 401 |
|
|
155
|
+
| `AUTH_2FA_FAILED` | Invalid 2FA code | 401 |
|
|
156
|
+
| `AUTH_FORBIDDEN` | Insufficient permissions | 403 |
|
|
157
|
+
| `AUTH_ACCOUNT_LOCKED` | Account locked due to failed attempts | 403 |
|
|
158
|
+
| `AUTH_EMAIL_NOT_VERIFIED` | Email verification required | 403 |
|
|
159
|
+
| `AUTH_2FA_REQUIRED` | 2FA code input required | 403 |
|
|
160
|
+
| `AUTH_NOT_FOUND` | Resource not found | 404 |
|
|
161
|
+
| `AUTH_CONFLICT` | Resource already exists | 409 |
|
|
162
|
+
| `AUTH_RATE_LIMITED` | Too many requests | 429 |
|
|
163
|
+
| `AUTH_SMTP_DISABLED` | Email delivery service disabled | 503 |
|
|
164
|
+
| `AUTH_INTERNAL` | Unexpected internal error | 500 |
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
MIT © Dax Crafta
|
package/image.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dax-crafta/auth",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "A powerful, flexible, and secure authentication plugin for the Crafta framework. Supports JWT, social login, 2FA, RBAC, audit logging, and enterprise-grade security features.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -61,5 +61,9 @@
|
|
|
61
61
|
},
|
|
62
62
|
"homepage": "https://github.com/daxp472/crafta#readme",
|
|
63
63
|
"license": "MIT",
|
|
64
|
-
"author": "Dax Patel"
|
|
64
|
+
"author": "Dax Patel",
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/mocha": "^10.0.10",
|
|
67
|
+
"mocha": "^10.8.2"
|
|
68
|
+
}
|
|
65
69
|
}
|