@dax-crafta/auth 1.3.3 → 1.3.4

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +94 -52
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.4",
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
  };