@metaadri/secureauth 1.2.0 → 1.2.2

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
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.2.0",
6
+ "version": "1.2.2",
7
7
  "description": "SecureAuth CLI - Add enterprise authentication to any Express app in one command",
8
8
  "bin": {
9
9
  "secureauth": "bin/cli.js"
package/src/scaffolder.js CHANGED
@@ -30,6 +30,7 @@ const LOCKOUT_CHECK_CODE = `
30
30
 
31
31
  const LOCKOUT_INCREMENT_CODE = `
32
32
  const failedAttempts = await userModel.incrementFailedAttempts(user.id);
33
+ const remaining = MAX_FAILED_ATTEMPTS - failedAttempts;
33
34
  `;
34
35
 
35
36
  const LOCKOUT_TRIGGER_CODE = `
@@ -116,9 +117,61 @@ function scaffold(targetDir, answers) {
116
117
  fileCount++;
117
118
  }
118
119
 
120
+ postProcess(targetDir);
119
121
  return fileCount;
120
122
  }
121
123
 
124
+ function postProcess(targetDir) {
125
+ const files = {
126
+ 'controllers/authController.js': [
127
+ {
128
+ search: /(const failedAttempts = await userModel\.incrementFailedAttempts\(user\.id\);)(?!\s+const remaining)/,
129
+ replace: '$1\n const remaining = MAX_FAILED_ATTEMPTS - failedAttempts;'
130
+ }
131
+ ],
132
+ 'server.js': [
133
+ {
134
+ search: /require\('dotenv'\)\.config\(\);/,
135
+ replace: "const path = require('path');\nrequire('dotenv').config({ path: path.join(__dirname, '.env') });"
136
+ },
137
+ {
138
+ search: /initDatabase\(\)\s*\.then\(async\s*\(\)\s*=>\s*\{[\s\S]*?await seedAdminUser\(\);[\s\S]*?await seedDemoUser\(\);[\s\S]*?dbReady\s*=\s*true;[\s\S]*?console\.log\('Database initialized and seeded'\);\s*\}\)[\s\S]*?\.catch\(err\s*=>\s*\{[\s\S]*?console\.error\('Database initialization failed:',\s*err\.message\);\s*\}\);/,
139
+ replace: "try {\n initDatabase();\n seedAdminUser();\n seedDemoUser();\n dbReady = true;\n console.log('Database initialized and seeded');\n} catch (err) {\n console.error('Database initialization failed:', err.message);\n}"
140
+ }
141
+ ],
142
+ 'database/db.sqlite.js': [
143
+ {
144
+ search: /query:\s*\(text,\s*params\)\s*=>\s*\{[^}]*const stmt\s*=\s*db\.prepare\(text\);[^}]*const rows\s*=\s*params\s*\?\s*stmt\.all\(\.\.\.params\)\s*:\s*stmt\.all\(\);[^}]*return\s*\{\s*rows\s*\};[^}]*\}/,
145
+ replace: "query: (text, params) => {\n const stmt = db.prepare(text);\n const sql = text.trim().toUpperCase();\n if (sql.startsWith('SELECT')) {\n const rows = params ? stmt.all(...params) : stmt.all();\n return { rows };\n }\n const info = params ? stmt.run(...params) : stmt.run();\n return { rows: [], changes: info.changes };\n }"
146
+ }
147
+ ],
148
+ 'routes/authRoutes.js': [
149
+ {
150
+ search: /router\.post\('\/demo\/login', authController\.demoLogin\);\s*/,
151
+ replace: ''
152
+ }
153
+ ]
154
+ };
155
+
156
+ for (const [relative, rules] of Object.entries(files)) {
157
+ const filePath = path.join(targetDir, relative);
158
+ if (!fs.existsSync(filePath)) continue;
159
+ try {
160
+ let content = fs.readFileSync(filePath, 'utf-8');
161
+ const before = content;
162
+ for (const rule of rules) {
163
+ content = content.replace(rule.search, rule.replace);
164
+ }
165
+ if (content !== before) {
166
+ fs.writeFileSync(filePath, content, 'utf-8');
167
+ logger.info(`Patched ${relative}`);
168
+ }
169
+ } catch {
170
+ // skip unreadable files
171
+ }
172
+ }
173
+ }
174
+
122
175
  function collectFiles(dir) {
123
176
  const results = [];
124
177
  for (const entry of fs.readdirSync(dir)) {
@@ -111,8 +111,13 @@ module.exports = {
111
111
  db: {
112
112
  query: (text, params) => {
113
113
  const stmt = db.prepare(text);
114
- const rows = params ? stmt.all(...params) : stmt.all();
115
- return { rows };
114
+ const sql = text.trim().toUpperCase();
115
+ if (sql.startsWith('SELECT')) {
116
+ const rows = params ? stmt.all(...params) : stmt.all();
117
+ return { rows };
118
+ }
119
+ const info = params ? stmt.run(...params) : stmt.run();
120
+ return { rows: [], changes: info.changes };
116
121
  }
117
122
  }
118
123
  };
@@ -8,7 +8,6 @@ const loginLimiter = createRateLimiter(5, 15);
8
8
 
9
9
  router.post('/register', authController.register);
10
10
  router.post('/login', loginLimiter, authController.loginStep1);
11
- router.post('/demo/login', authController.demoLogin);
12
11
  router.post('/verify-2fa', loginLimiter, authController.verifyTOTP);
13
12
  router.get('/dashboard', checkAndRefreshToken, authController.getDashboard);
14
13
  router.get('/login-history', checkAndRefreshToken, authController.getLoginHistory);
@@ -1,7 +1,7 @@
1
- require('dotenv').config();
1
+ const path = require('path');
2
+ require('dotenv').config({ path: path.join(__dirname, '.env') });
2
3
  const express = require('express');
3
4
  const cors = require('cors');
4
- const path = require('path');
5
5
  const helmet = require('helmet');
6
6
 
7
7
  const authRoutes = require('./routes/authRoutes');
@@ -62,16 +62,15 @@ app.get('/', (req, res) => {
62
62
 
63
63
  let dbReady = false;
64
64
 
65
- initDatabase()
66
- .then(async () => {
67
- await seedAdminUser();
68
- await seedDemoUser();
69
- dbReady = true;
70
- console.log('Database initialized and seeded');
71
- })
72
- .catch(err => {
73
- console.error('Database initialization failed:', err.message);
74
- });
65
+ try {
66
+ initDatabase();
67
+ seedAdminUser();
68
+ seedDemoUser();
69
+ dbReady = true;
70
+ console.log('Database initialized and seeded');
71
+ } catch (err) {
72
+ console.error('Database initialization failed:', err.message);
73
+ }
75
74
 
76
75
  app.use((req, res, next) => {
77
76
  if (dbReady) return next();