@dax-crafta/auth 1.3.3 → 1.3.5

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 (3) hide show
  1. package/README.md +175 -0
  2. package/package.json +1 -1
  3. package/src/index.js +94 -52
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # @dax-crafta/auth
2
+
3
+ A powerful, flexible, and secure authentication system for Node.js applications. Built with enterprise-grade security features while maintaining developer-friendly simplicity.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@dax-crafta/auth.svg)](https://www.npmjs.com/package/@dax-crafta/auth)
6
+ [![License](https://img.shields.io/npm/l/@dax-crafta/auth.svg)](https://github.com/dax-crafta/auth/blob/main/LICENSE)
7
+
8
+ ## Features
9
+
10
+ - 🔐 **Comprehensive Authentication**
11
+ - Email/Password authentication
12
+ - Social login (Google, Facebook, GitHub)
13
+ - JWT-based session management
14
+ - Refresh token rotation
15
+
16
+ - 👥 **Advanced Role-Based Access Control (RBAC)**
17
+ - Custom role creation
18
+ - Granular permissions
19
+ - Resource-based access control
20
+ - Role hierarchy support
21
+
22
+ - 🔒 **Enterprise Security**
23
+ - Multi-factor authentication (MFA/2FA)
24
+ - Password policies and strength validation
25
+ - Account lockout protection
26
+ - Brute force prevention
27
+
28
+ - 📧 **Email Features**
29
+ - Email verification
30
+ - Password reset
31
+ - Login notifications
32
+ - Custom email templates
33
+
34
+ - 📝 **Audit Logging**
35
+ - Detailed activity tracking
36
+ - Security event logging
37
+ - User session monitoring
38
+
39
+ ## Quick Start
40
+
41
+ ```bash
42
+ npm install @dax-crafta/auth
43
+ ```
44
+
45
+ ```javascript
46
+ const { forge } = require('crafta');
47
+ const { auth } = require('@dax-crafta/auth');
48
+
49
+ const app = forge();
50
+
51
+ // Basic setup
52
+ auth({
53
+ strategy: 'jwt',
54
+ fields: ['email', 'password'],
55
+ emailVerification: true
56
+ })(app);
57
+
58
+ app.listen(3000);
59
+ ```
60
+
61
+ ## Configuration
62
+
63
+ ```javascript
64
+ auth({
65
+ // Authentication Strategy
66
+ strategy: 'jwt',
67
+
68
+ // User Fields
69
+ fields: ['name', 'email', 'password', 'age'],
70
+
71
+ // Routes Configuration
72
+ routes: {
73
+ register: '/register',
74
+ login: '/login',
75
+ verify: '/verify',
76
+ forgotPassword: '/forgot-password',
77
+ resetPassword: '/reset-password',
78
+ refreshToken: '/refresh-token',
79
+ profile: '/profile',
80
+ twoFactor: '/2fa'
81
+ },
82
+
83
+ // Security Settings
84
+ maxLoginAttempts: 5,
85
+ emailVerification: true,
86
+ loginAlerts: true,
87
+
88
+ // Password Policy
89
+ passwordPolicy: {
90
+ minLength: 8,
91
+ requireUppercase: true,
92
+ requireNumbers: true,
93
+ requireSpecialChars: true,
94
+ expiryDays: 90
95
+ },
96
+
97
+ // Email Configuration
98
+ smtp: {
99
+ host: 'smtp.example.com',
100
+ port: 587,
101
+ auth: {
102
+ user: 'your-email@example.com',
103
+ pass: 'your-password'
104
+ },
105
+ from: 'noreply@example.com'
106
+ },
107
+
108
+ // Social Login
109
+ social: {
110
+ google: {
111
+ clientID: 'your-client-id',
112
+ clientSecret: 'your-client-secret',
113
+ callbackURL: 'http://localhost:3000/auth/google/callback'
114
+ }
115
+ }
116
+ })(app);
117
+ ```
118
+
119
+ ## Role-Based Access Control
120
+
121
+ ```javascript
122
+ // Create a custom role
123
+ const adminRole = await roleService.createRole({
124
+ name: 'admin',
125
+ permissions: [{
126
+ resource: 'users',
127
+ actions: ['create', 'read', 'update', 'delete']
128
+ }]
129
+ });
130
+
131
+ // Check permissions
132
+ const canAccess = await roleService.checkPermission('admin', 'users', 'create');
133
+ ```
134
+
135
+ ## Multi-Factor Authentication
136
+
137
+ ```javascript
138
+ // Enable 2FA for a user
139
+ const { secret, qrCode } = await mfaService.generateSecret(
140
+ 'user@example.com',
141
+ 'MyApp'
142
+ );
143
+
144
+ // Verify 2FA token
145
+ const isValid = mfaService.verifyToken(token, secret);
146
+ ```
147
+
148
+ ## Audit Logging
149
+
150
+ ```javascript
151
+ // Log user activity
152
+ await auditService.logActivity({
153
+ userId: user.id,
154
+ action: 'login',
155
+ ipAddress: req.ip,
156
+ userAgent: req.headers['user-agent'],
157
+ status: 'success'
158
+ });
159
+
160
+ // Get user activity history
161
+ const activities = await auditService.getUserActivity(userId);
162
+ ```
163
+
164
+ ## Security Best Practices
165
+
166
+ - Use HTTPS in production
167
+ - Set secure cookie options
168
+ - Configure CORS appropriately
169
+ - Regularly rotate refresh tokens
170
+ - Monitor failed login attempts
171
+ - Implement rate limiting
172
+
173
+ ## License
174
+
175
+ MIT © Dax Crafta
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dax-crafta/auth",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Authentication plugin for crafta framework",
5
5
  "main": "src/index.js",
6
6
  "private": false,
package/src/index.js CHANGED
@@ -3,6 +3,10 @@ const GoogleStrategy = require('passport-google-oauth20').Strategy;
3
3
  const FacebookStrategy = require('passport-facebook').Strategy;
4
4
  const GitHubStrategy = require('passport-github2').Strategy;
5
5
  const AuthService = require('./services/auth.service');
6
+ const RoleService = require('./services/role.service');
7
+ const AuditService = require('./services/audit.service');
8
+ const MFAService = require('./utils/mfa');
9
+ const PasswordPolicy = require('./utils/password-policy');
6
10
  const createAuthMiddleware = require('./middlewares/auth.middleware');
7
11
 
8
12
  const defaultConfig = {
@@ -16,12 +20,21 @@ const defaultConfig = {
16
20
  resetPassword: '/reset-password',
17
21
  refreshToken: '/refresh-token',
18
22
  profile: '/profile',
19
- twoFactor: '/2fa'
23
+ twoFactor: '/2fa',
24
+ roles: '/roles',
25
+ permissions: '/permissions'
20
26
  },
21
27
  mongoUrl: process.env.MONGODB_URI || 'mongodb://localhost:27017/forge-auth',
22
28
  maxLoginAttempts: 5,
23
29
  emailVerification: true,
24
30
  loginAlerts: true,
31
+ passwordPolicy: {
32
+ minLength: 8,
33
+ requireUppercase: true,
34
+ requireNumbers: true,
35
+ requireSpecialChars: true,
36
+ expiryDays: 90
37
+ },
25
38
  smtp: null,
26
39
  social: {
27
40
  google: null,
@@ -41,7 +54,12 @@ function auth(config = {}) {
41
54
  throw new Error('SMTP configuration is required for email verification');
42
55
  }
43
56
 
57
+ // Initialize services
44
58
  const authService = new AuthService(finalConfig);
59
+ const roleService = new RoleService();
60
+ const auditService = new AuditService();
61
+ const mfaService = new MFAService();
62
+ const passwordPolicy = new PasswordPolicy(finalConfig.passwordPolicy);
45
63
  const { rateLimiter, verifyToken, checkRole } = createAuthMiddleware(finalConfig);
46
64
 
47
65
  // Configure social login strategies
@@ -49,7 +67,6 @@ function auth(config = {}) {
49
67
  passport.use(new GoogleStrategy(finalConfig.social.google,
50
68
  async (accessToken, refreshToken, profile, done) => {
51
69
  try {
52
- // Handle Google login
53
70
  const user = await authService.handleSocialLogin('google', profile);
54
71
  done(null, user);
55
72
  } catch (error) {
@@ -63,13 +80,40 @@ function auth(config = {}) {
63
80
  app.use(passport.initialize());
64
81
  app.use(rateLimiter);
65
82
 
66
- // Register route
83
+ // Attach services to app
84
+ app.authService = authService;
85
+ app.roleService = roleService;
86
+ app.auditService = auditService;
87
+ app.mfaService = mfaService;
88
+ app.passwordPolicy = passwordPolicy;
89
+
90
+ // Register route with password policy
67
91
  app.post(finalConfig.routes.register, async (req, res) => {
68
92
  try {
93
+ const { isValid, errors } = passwordPolicy.validate(req.body.password, {
94
+ email: req.body.email,
95
+ name: req.body.name
96
+ });
97
+
98
+ if (!isValid) {
99
+ return res.status(400).json({
100
+ success: false,
101
+ errors
102
+ });
103
+ }
104
+
69
105
  const user = await authService.register(req.body);
106
+ await auditService.logActivity({
107
+ userId: user._id,
108
+ action: 'register',
109
+ ipAddress: req.ip,
110
+ userAgent: req.headers['user-agent'],
111
+ status: 'success'
112
+ });
113
+
70
114
  res.status(201).json({
71
115
  success: true,
72
- message: 'Registration successful. Please verify your email.'
116
+ message: 'Registration successful'
73
117
  });
74
118
  } catch (error) {
75
119
  res.status(400).json({
@@ -79,7 +123,7 @@ function auth(config = {}) {
79
123
  }
80
124
  });
81
125
 
82
- // Login route with device detection
126
+ // Login route with audit logging and MFA support
83
127
  app.post(finalConfig.routes.login, async (req, res) => {
84
128
  try {
85
129
  const deviceInfo = {
@@ -93,11 +137,27 @@ function auth(config = {}) {
93
137
  deviceInfo
94
138
  );
95
139
 
140
+ await auditService.logActivity({
141
+ userId: result.user?._id,
142
+ action: 'login',
143
+ ipAddress: req.ip,
144
+ userAgent: req.headers['user-agent'],
145
+ status: 'success'
146
+ });
147
+
96
148
  res.json({
97
149
  success: true,
98
150
  ...result
99
151
  });
100
152
  } catch (error) {
153
+ await auditService.logActivity({
154
+ action: 'login',
155
+ ipAddress: req.ip,
156
+ userAgent: req.headers['user-agent'],
157
+ status: 'failure',
158
+ details: { error: error.message }
159
+ });
160
+
101
161
  res.status(401).json({
102
162
  success: false,
103
163
  error: error.message
@@ -113,22 +173,12 @@ function auth(config = {}) {
113
173
  req.body.code
114
174
  );
115
175
 
116
- res.json({
117
- success: true,
118
- ...result
176
+ await auditService.logActivity({
177
+ userId: result.user._id,
178
+ action: '2fa_verify',
179
+ status: 'success'
119
180
  });
120
- } catch (error) {
121
- res.status(401).json({
122
- success: false,
123
- error: error.message
124
- });
125
- }
126
- });
127
181
 
128
- // Refresh token
129
- app.post(finalConfig.routes.refreshToken, async (req, res) => {
130
- try {
131
- const result = await authService.refreshToken(req.body.refreshToken);
132
182
  res.json({
133
183
  success: true,
134
184
  ...result
@@ -141,33 +191,11 @@ function auth(config = {}) {
141
191
  }
142
192
  });
143
193
 
144
- // Forgot password
145
- app.post(finalConfig.routes.forgotPassword, async (req, res) => {
146
- try {
147
- await authService.forgotPassword(req.body.email);
148
- res.json({
149
- success: true,
150
- message: 'Password reset instructions sent to your email'
151
- });
152
- } catch (error) {
153
- res.status(400).json({
154
- success: false,
155
- error: error.message
156
- });
157
- }
158
- });
159
-
160
- // Reset password
161
- app.post(finalConfig.routes.resetPassword, async (req, res) => {
194
+ // Role management routes
195
+ app.post('/roles', verifyToken, checkRole(['admin']), async (req, res) => {
162
196
  try {
163
- await authService.resetPassword(
164
- req.body.token,
165
- req.body.newPassword
166
- );
167
- res.json({
168
- success: true,
169
- message: 'Password reset successful'
170
- });
197
+ const role = await roleService.createRole(req.body);
198
+ res.status(201).json({ success: true, role });
171
199
  } catch (error) {
172
200
  res.status(400).json({
173
201
  success: false,
@@ -176,10 +204,16 @@ function auth(config = {}) {
176
204
  }
177
205
  });
178
206
 
179
- // Update profile (protected route)
207
+ // Update profile with audit logging
180
208
  app.put(finalConfig.routes.profile, verifyToken, async (req, res) => {
181
209
  try {
182
210
  const user = await authService.updateProfile(req.user.id, req.body);
211
+ await auditService.logActivity({
212
+ userId: user._id,
213
+ action: 'profile_update',
214
+ status: 'success'
215
+ });
216
+
183
217
  res.json({
184
218
  success: true,
185
219
  user
@@ -200,8 +234,15 @@ function auth(config = {}) {
200
234
 
201
235
  app.get('/auth/google/callback',
202
236
  passport.authenticate('google', { session: false }),
203
- (req, res) => {
237
+ async (req, res) => {
204
238
  const { accessToken, refreshToken } = authService.generateTokens(req.user);
239
+ await auditService.logActivity({
240
+ userId: req.user._id,
241
+ action: 'social_login',
242
+ status: 'success',
243
+ details: { provider: 'google' }
244
+ });
245
+
205
246
  res.json({
206
247
  success: true,
207
248
  accessToken,
@@ -212,11 +253,12 @@ function auth(config = {}) {
212
253
  );
213
254
  }
214
255
 
215
- // Admin-only route example
216
- app.get('/admin', verifyToken, checkRole(['admin']), (req, res) => {
217
- res.json({
218
- success: true,
219
- message: 'Admin access granted'
256
+ // Error handling middleware
257
+ app.use((err, req, res, next) => {
258
+ console.error(err.stack);
259
+ res.status(500).json({
260
+ success: false,
261
+ error: 'Internal Server Error'
220
262
  });
221
263
  });
222
264
  };