@dax-crafta/auth 2.0.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.
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@dax-crafta/auth",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
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
+ "types": "src/index.d.ts",
6
7
  "private": false,
7
8
  "dependencies": {
8
9
  "bcryptjs": "^2.4.3",
package/src/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export function register(email: string, password: string): Promise<any>;
2
+ export function login(email: string, password: string): Promise<any>;
3
+ export function verifyToken(token: string): boolean;
4
+
5
+ export interface User {
6
+ email: string;
7
+ password?: string;
8
+ role?: string;
9
+ }
10
+
11
+ export function getUser(id: string): Promise<User>;
12
+ export function logout(): Promise<void>;
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ const passport = require('passport');
3
3
  const cookieParser = require('cookie-parser');
4
4
  const csrf = require('csurf');
5
5
  const helmet = require("helmet");
6
+ const mongoose = require("mongoose"); // <<< FIX ADDED
6
7
 
7
8
  const GoogleStrategy = require('passport-google-oauth20').Strategy;
8
9
  const AuthService = require('./services/auth.service');
@@ -73,6 +74,21 @@ function auth(config = {}) {
73
74
  throw new Error('SMTP configuration is required for email verification');
74
75
  }
75
76
 
77
+ // ------------------------------------------
78
+ // ✅ FIX — Proper MongoDB Connection
79
+ // ------------------------------------------
80
+ if (mongoose.connection.readyState === 0) {
81
+ mongoose.connect(finalConfig.mongoUrl, {
82
+ useNewUrlParser: true,
83
+ useUnifiedTopology: true
84
+ })
85
+ .then(() => console.log("📦 Auth Library MongoDB Connected"))
86
+ .catch(err => console.error("❌ Auth Library MongoDB Error:", err));
87
+ } else {
88
+ console.log("📦 Using existing mongoose connection");
89
+ }
90
+ // ------------------------------------------
91
+
76
92
  const authService = new AuthService(finalConfig);
77
93
  const roleService = new RoleService();
78
94
  const auditService = new AuditService();
@@ -80,7 +96,6 @@ function auth(config = {}) {
80
96
  const passwordPolicy = new PasswordPolicy(finalConfig.passwordPolicy);
81
97
  const { rateLimiter, limiterFor, verifyToken, checkRole, checkOwnershipOrAdmin } = createAuthMiddleware(finalConfig);
82
98
 
83
- // setup passport strategies as earlier if provided...
84
99
  if (finalConfig.social && finalConfig.social.google) {
85
100
  passport.use(new GoogleStrategy(finalConfig.social.google,
86
101
  async (accessToken, refreshToken, profile, done) => {
@@ -96,13 +111,11 @@ function auth(config = {}) {
96
111
 
97
112
  return function (app) {
98
113
  app.use(cookieParser());
99
- // CSRF: enable only if config.enableCSRF === true
114
+
100
115
  if (finalConfig.enableCSRF) {
101
- // use cookie-based CSRF token and expect header 'x-csrf-token' or cookie
102
116
  const csrfProtection = csrf({ cookie: true });
103
117
  app.use(csrfProtection);
104
118
 
105
- // expose token endpoint to clients (they must fetch this and send it back on state-changing requests)
106
119
  app.get('/csrf-token', (req, res) => {
107
120
  res.json({ csrfToken: req.csrfToken() });
108
121
  });
@@ -111,19 +124,17 @@ function auth(config = {}) {
111
124
  app.use(passport.initialize());
112
125
  app.use(rateLimiter);
113
126
  app.use(helmet({
114
- contentSecurityPolicy: false, // optional to ease frontend dev
127
+ contentSecurityPolicy: false,
115
128
  crossOriginEmbedderPolicy: false,
116
129
  }));
117
130
 
118
-
119
- // attach services
120
131
  app.authService = authService;
121
132
  app.roleService = roleService;
122
133
  app.auditService = auditService;
123
134
  app.mfaService = mfaService;
124
135
  app.passwordPolicy = passwordPolicy;
125
136
 
126
- // register
137
+ // REGISTER
127
138
  app.post(
128
139
  finalConfig.routes.register,
129
140
  limiterFor('register'),
@@ -156,7 +167,7 @@ function auth(config = {}) {
156
167
  }
157
168
  );
158
169
 
159
- // login
170
+ // LOGIN
160
171
  app.post(
161
172
  finalConfig.routes.login,
162
173
  limiterFor('login'),
@@ -189,7 +200,7 @@ function auth(config = {}) {
189
200
  }
190
201
  );
191
202
 
192
- // 2FA verification (rate-limited)
203
+ // 2FA
193
204
  app.post(
194
205
  finalConfig.routes.twoFactor,
195
206
  limiterFor('2fa'),
@@ -206,7 +217,7 @@ function auth(config = {}) {
206
217
  }
207
218
  );
208
219
 
209
- // forgot password (rate-limited)
220
+ // FORGOT PASSWORD
210
221
  app.post(
211
222
  finalConfig.routes.forgotPassword,
212
223
  limiterFor('forgotPassword'),
@@ -222,7 +233,7 @@ function auth(config = {}) {
222
233
  }
223
234
  );
224
235
 
225
- // reset password
236
+ // RESET PASSWORD
226
237
  app.post(
227
238
  finalConfig.routes.resetPassword,
228
239
  validators.resetPasswordValidator,
@@ -238,7 +249,7 @@ function auth(config = {}) {
238
249
  }
239
250
  );
240
251
 
241
- // refresh token
252
+ // REFRESH TOKEN
242
253
  app.post(
243
254
  finalConfig.routes.refreshToken,
244
255
  validators.refreshTokenValidator,
@@ -253,11 +264,11 @@ function auth(config = {}) {
253
264
  }
254
265
  );
255
266
 
256
- // update profile (prevent IDOR: only owner or admin)
267
+ // UPDATE PROFILE
257
268
  app.put(
258
269
  finalConfig.routes.profile,
259
270
  verifyToken,
260
- checkOwnershipOrAdmin((req) => req.user.id), // target is the calling user; if you allow admin to pass an id param, adapt accordingly
271
+ checkOwnershipOrAdmin((req) => req.user.id),
261
272
  validators.profileUpdateValidator,
262
273
  validators.handleValidation,
263
274
  async (req, res, next) => {
@@ -271,7 +282,7 @@ function auth(config = {}) {
271
282
  }
272
283
  );
273
284
 
274
- // roles (admin only)
285
+ // CREATE ROLE (ADMIN)
275
286
  app.post('/roles', verifyToken, checkRole(['admin']), async (req, res, next) => {
276
287
  try {
277
288
  const role = await roleService.createRole(req.body);
@@ -281,7 +292,7 @@ function auth(config = {}) {
281
292
  }
282
293
  });
283
294
 
284
- // social google callback example (kept same)
295
+ // GOOGLE OAUTH
285
296
  if (finalConfig.social && finalConfig.social.google) {
286
297
  app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
287
298
 
@@ -303,17 +314,18 @@ function auth(config = {}) {
303
314
  });
304
315
  }
305
316
 
306
- // centralized error handler (friendly for clients)
317
+ // ERROR HANDLER
307
318
  app.use((err, req, res, next) => {
308
319
  console.error(err && err.stack ? err.stack : err);
309
320
  const status = err.status || (err.name === 'ValidationError' ? 400 : 500);
310
321
 
311
- // If client error (4xx) show helpful message, else generic in production
312
322
  let message;
313
323
  if (status >= 400 && status < 500) {
314
324
  message = err.message || 'Bad request';
315
325
  } else {
316
- message = process.env.NODE_ENV === 'development' ? (err.message || 'Internal Server Error') : 'Internal Server Error';
326
+ message = process.env.NODE_ENV === 'development'
327
+ ? (err.message || 'Internal Server Error')
328
+ : 'Internal Server Error';
317
329
  }
318
330
 
319
331
  res.status(status).json({ success: false, error: message });