security fixes
This commit is contained in:
parent
d3f2a921bf
commit
8cab248959
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "bill-tracker",
|
||||
"version": "0.28.1",
|
||||
"version": "0.28.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bill-tracker",
|
||||
"version": "0.28.1",
|
||||
"version": "0.28.3",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-alert-dialog": "^1.1.2",
|
||||
|
|
@ -32,8 +32,8 @@
|
|||
"express": "^4.18.2",
|
||||
"express-rate-limit": "^8.4.1",
|
||||
"lucide-react": "^0.456.0",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.14",
|
||||
"node-cron": "^4.2.1",
|
||||
"nodemailer": "^8.0.9",
|
||||
"openid-client": "^5.7.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
@ -2770,21 +2770,6 @@
|
|||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/body-parser/node_modules/qs": {
|
||||
"version": "6.15.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
|
||||
"integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
|
|
@ -3571,14 +3556,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
|
||||
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
|
||||
"version": "4.22.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz",
|
||||
"integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "~1.20.3",
|
||||
"body-parser": "~1.20.5",
|
||||
"content-disposition": "~0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "~0.7.1",
|
||||
|
|
@ -3597,7 +3582,7 @@
|
|||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "~0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "~6.14.0",
|
||||
"qs": "~6.15.1",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "~0.19.0",
|
||||
|
|
@ -5364,13 +5349,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/node-cron": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz",
|
||||
"integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.2.1.tgz",
|
||||
"integrity": "sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"uuid": "8.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
|
|
@ -5383,9 +5365,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz",
|
||||
"integrity": "sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==",
|
||||
"version": "8.0.9",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.9.tgz",
|
||||
"integrity": "sha512-5ofa7BUN8+C+Hckh5V2GjeeOGRQBx0CJQA6KxrvuZfC8iU4/q7sLn8XrtEEhJkjV6HdyIiQs7Bba6bTao8JhkA==",
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
|
|
@ -5792,9 +5774,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.14.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
|
||||
"integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
|
||||
"version": "6.15.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
|
||||
"integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
|
|
@ -7107,16 +7089,6 @@
|
|||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@
|
|||
"express": "^4.18.2",
|
||||
"express-rate-limit": "^8.4.1",
|
||||
"lucide-react": "^0.456.0",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.14",
|
||||
"node-cron": "^4.2.1",
|
||||
"nodemailer": "^8.0.9",
|
||||
"openid-client": "^5.7.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ router.post('/check-updates', requireAuth, requireAdmin, async (req, res) => {
|
|||
const result = await checkForUpdates(true);
|
||||
res.json(result);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message || 'Update check failed' });
|
||||
res.status(500).json({ error: 'Update check failed' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const express = require('express');
|
|||
const router = express.Router();
|
||||
const { getDb, rollbackMigration } = require('../db/database');
|
||||
const { hashPassword } = require('../services/authService');
|
||||
const { logAudit } = require('../services/auditService');
|
||||
const {
|
||||
createBackup,
|
||||
deleteBackup,
|
||||
|
|
@ -162,10 +163,18 @@ router.post('/users', async (req, res) => {
|
|||
"INSERT INTO users (username, password_hash, role, first_login) VALUES (?, ?, 'user', 1)"
|
||||
).run(username, hash);
|
||||
|
||||
res.status(201).json(
|
||||
db.prepare('SELECT id, username, role, active, is_default_admin, must_change_password, first_login, created_at FROM users WHERE id = ?')
|
||||
.get(result.lastInsertRowid)
|
||||
);
|
||||
const created = db.prepare(
|
||||
'SELECT id, username, role, active, is_default_admin, must_change_password, first_login, created_at FROM users WHERE id = ?'
|
||||
).get(result.lastInsertRowid);
|
||||
|
||||
logAudit({
|
||||
user_id: req.user.id, action: 'admin.user.create',
|
||||
entity_type: 'user', entity_id: created.id,
|
||||
details: { created_username: username },
|
||||
ip_address: req.ip, user_agent: req.get('user-agent'),
|
||||
});
|
||||
|
||||
res.status(201).json(created);
|
||||
});
|
||||
|
||||
// PUT /api/admin/users/:id/password
|
||||
|
|
@ -182,11 +191,16 @@ router.put('/users/:id/password', async (req, res) => {
|
|||
db.prepare("UPDATE users SET password_hash=?, must_change_password=1, updated_at=datetime('now') WHERE id=?")
|
||||
.run(hash, req.params.id);
|
||||
db.prepare('DELETE FROM sessions WHERE user_id = ?').run(req.params.id);
|
||||
res.json({ success: true });
|
||||
|
||||
logAudit({
|
||||
user_id: req.user.id, action: 'admin.password.reset',
|
||||
entity_type: 'user', entity_id: Number(req.params.id),
|
||||
details: { target_username: user.username },
|
||||
ip_address: req.ip, user_agent: req.get('user-agent'),
|
||||
});
|
||||
|
||||
// Import audit service
|
||||
const { logAudit } = require('../services/auditService');
|
||||
res.json({ success: true });
|
||||
});
|
||||
|
||||
// PUT /api/admin/users/:id/role
|
||||
// Promote/demote an existing user. Prevents removing the last admin or
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ router.get('/history', (req, res) => {
|
|||
updated_at: updatedAt,
|
||||
});
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message || 'Failed to read release history' });
|
||||
res.status(500).json({ error: 'Failed to read release history' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ router.get('/update-status', async (req, res) => {
|
|||
try {
|
||||
res.json(await checkForUpdates(false));
|
||||
} catch (err) {
|
||||
res.json({ current_version: pkg.version, latest_version: null, up_to_date: null, has_update: false, error: err.message });
|
||||
res.json({ current_version: pkg.version, latest_version: null, up_to_date: null, has_update: false, error: 'Update check unavailable' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue