mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-05 22:43:23 +00:00
Refactor authentication and routing code to use consistent naming conventions for database fields.
Do NOT update the schema like that again for the love of god.
This commit is contained in:
@@ -28,13 +28,13 @@ router.get('/admin/users', authenticateToken, requireViewUsers, async (req, res)
|
|||||||
username: true,
|
username: true,
|
||||||
email: true,
|
email: true,
|
||||||
role: true,
|
role: true,
|
||||||
isActive: true,
|
is_active: true,
|
||||||
lastLogin: true,
|
last_login: true,
|
||||||
createdAt: true,
|
created_at: true,
|
||||||
updatedAt: true
|
updated_at: true
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: 'desc'
|
created_at: 'desc'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ router.post('/admin/users', authenticateToken, requireManageUsers, [
|
|||||||
data: {
|
data: {
|
||||||
username,
|
username,
|
||||||
email,
|
email,
|
||||||
passwordHash,
|
password_hash: passwordHash,
|
||||||
role
|
role
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
@@ -99,8 +99,8 @@ router.post('/admin/users', authenticateToken, requireManageUsers, [
|
|||||||
username: true,
|
username: true,
|
||||||
email: true,
|
email: true,
|
||||||
role: true,
|
role: true,
|
||||||
isActive: true,
|
is_active: true,
|
||||||
createdAt: true
|
created_at: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ router.put('/admin/users/:userId', authenticateToken, requireManageUsers, [
|
|||||||
if (username) updateData.username = username;
|
if (username) updateData.username = username;
|
||||||
if (email) updateData.email = email;
|
if (email) updateData.email = email;
|
||||||
if (role) updateData.role = role;
|
if (role) updateData.role = role;
|
||||||
if (typeof isActive === 'boolean') updateData.isActive = isActive;
|
if (typeof isActive === 'boolean') updateData.is_active = isActive;
|
||||||
|
|
||||||
// Check if user exists
|
// Check if user exists
|
||||||
const existingUser = await prisma.users.findUnique({
|
const existingUser = await prisma.users.findUnique({
|
||||||
@@ -181,7 +181,7 @@ router.put('/admin/users/:userId', authenticateToken, requireManageUsers, [
|
|||||||
const adminCount = await prisma.users.count({
|
const adminCount = await prisma.users.count({
|
||||||
where: {
|
where: {
|
||||||
role: 'admin',
|
role: 'admin',
|
||||||
isActive: true
|
is_active: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -199,10 +199,10 @@ router.put('/admin/users/:userId', authenticateToken, requireManageUsers, [
|
|||||||
username: true,
|
username: true,
|
||||||
email: true,
|
email: true,
|
||||||
role: true,
|
role: true,
|
||||||
isActive: true,
|
is_active: true,
|
||||||
lastLogin: true,
|
last_login: true,
|
||||||
createdAt: true,
|
created_at: true,
|
||||||
updatedAt: true
|
updated_at: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ router.delete('/admin/users/:userId', authenticateToken, requireManageUsers, asy
|
|||||||
const adminCount = await prisma.users.count({
|
const adminCount = await prisma.users.count({
|
||||||
where: {
|
where: {
|
||||||
role: 'admin',
|
role: 'admin',
|
||||||
isActive: true
|
is_active: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ router.post('/admin/users/:userId/reset-password', authenticateToken, requireMan
|
|||||||
// Update user password
|
// Update user password
|
||||||
await prisma.users.update({
|
await prisma.users.update({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
data: { passwordHash }
|
data: { password_hash: passwordHash }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Log the password reset action (you might want to add an audit log table)
|
// Log the password reset action (you might want to add an audit log table)
|
||||||
@@ -519,7 +519,7 @@ router.post('/verify-tfa', [
|
|||||||
const speakeasy = require('speakeasy');
|
const speakeasy = require('speakeasy');
|
||||||
|
|
||||||
// Check if it's a backup code
|
// Check if it's a backup code
|
||||||
const backupCodes = user.tfaBackupCodes ? JSON.parse(user.tfaBackupCodes) : [];
|
const backupCodes = user.tfa_backup_codes ? JSON.parse(user.tfa_backup_codes) : [];
|
||||||
const isBackupCode = backupCodes.includes(token);
|
const isBackupCode = backupCodes.includes(token);
|
||||||
|
|
||||||
let verified = false;
|
let verified = false;
|
||||||
@@ -527,17 +527,17 @@ router.post('/verify-tfa', [
|
|||||||
if (isBackupCode) {
|
if (isBackupCode) {
|
||||||
// Remove the used backup code
|
// Remove the used backup code
|
||||||
const updatedBackupCodes = backupCodes.filter(code => code !== token);
|
const updatedBackupCodes = backupCodes.filter(code => code !== token);
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
data: {
|
data: {
|
||||||
tfaBackupCodes: JSON.stringify(updatedBackupCodes)
|
tfa_backup_codes: JSON.stringify(updatedBackupCodes)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
verified = true;
|
verified = true;
|
||||||
} else {
|
} else {
|
||||||
// Verify TOTP token
|
// Verify TOTP token
|
||||||
verified = speakeasy.totp.verify({
|
verified = speakeasy.totp.verify({
|
||||||
secret: user.tfaSecret,
|
secret: user.tfa_secret,
|
||||||
encoding: 'base32',
|
encoding: 'base32',
|
||||||
token: token,
|
token: token,
|
||||||
window: 2
|
window: 2
|
||||||
@@ -549,9 +549,9 @@ router.post('/verify-tfa', [
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update last login
|
// Update last login
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
data: { lastLogin: new Date() }
|
data: { last_login: new Date() }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate token
|
// Generate token
|
||||||
@@ -604,7 +604,7 @@ router.put('/profile', authenticateToken, [
|
|||||||
|
|
||||||
// Check if username/email already exists (excluding current user)
|
// Check if username/email already exists (excluding current user)
|
||||||
if (username || email) {
|
if (username || email) {
|
||||||
const existingUser = await prisma.user.findFirst({
|
const existingUser = await prisma.users.findFirst({
|
||||||
where: {
|
where: {
|
||||||
AND: [
|
AND: [
|
||||||
{ id: { not: req.user.id } },
|
{ id: { not: req.user.id } },
|
||||||
@@ -623,7 +623,7 @@ router.put('/profile', authenticateToken, [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedUser = await prisma.user.update({
|
const updatedUser = await prisma.users.update({
|
||||||
where: { id: req.user.id },
|
where: { id: req.user.id },
|
||||||
data: updateData,
|
data: updateData,
|
||||||
select: {
|
select: {
|
||||||
@@ -631,9 +631,9 @@ router.put('/profile', authenticateToken, [
|
|||||||
username: true,
|
username: true,
|
||||||
email: true,
|
email: true,
|
||||||
role: true,
|
role: true,
|
||||||
isActive: true,
|
is_active: true,
|
||||||
lastLogin: true,
|
last_login: true,
|
||||||
updatedAt: true
|
updated_at: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -661,12 +661,12 @@ router.put('/change-password', authenticateToken, [
|
|||||||
const { currentPassword, newPassword } = req.body;
|
const { currentPassword, newPassword } = req.body;
|
||||||
|
|
||||||
// Get user with password hash
|
// Get user with password hash
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { id: req.user.id }
|
where: { id: req.user.id }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify current password
|
// Verify current password
|
||||||
const isValidPassword = await bcrypt.compare(currentPassword, user.passwordHash);
|
const isValidPassword = await bcrypt.compare(currentPassword, user.password_hash);
|
||||||
if (!isValidPassword) {
|
if (!isValidPassword) {
|
||||||
return res.status(401).json({ error: 'Current password is incorrect' });
|
return res.status(401).json({ error: 'Current password is incorrect' });
|
||||||
}
|
}
|
||||||
@@ -675,9 +675,9 @@ router.put('/change-password', authenticateToken, [
|
|||||||
const newPasswordHash = await bcrypt.hash(newPassword, 12);
|
const newPasswordHash = await bcrypt.hash(newPassword, 12);
|
||||||
|
|
||||||
// Update password
|
// Update password
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: req.user.id },
|
where: { id: req.user.id },
|
||||||
data: { passwordHash: newPasswordHash }
|
data: { password_hash: newPasswordHash }
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
|
|||||||
@@ -162,16 +162,16 @@ router.get('/hosts', authenticateToken, requireViewHosts, async (req, res) => {
|
|||||||
// Show all hosts regardless of status
|
// Show all hosts regardless of status
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true,
|
friendly_name: true,
|
||||||
hostname: true,
|
hostname: true,
|
||||||
ip: true,
|
ip: true,
|
||||||
osType: true,
|
os_type: true,
|
||||||
osVersion: true,
|
os_version: true,
|
||||||
lastUpdate: true,
|
last_update: true,
|
||||||
status: true,
|
status: true,
|
||||||
agentVersion: true,
|
agent_version: true,
|
||||||
autoUpdate: true,
|
auto_update: true,
|
||||||
hostGroup: {
|
host_groups: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
@@ -180,15 +180,15 @@ router.get('/hosts', authenticateToken, requireViewHosts, async (req, res) => {
|
|||||||
},
|
},
|
||||||
_count: {
|
_count: {
|
||||||
select: {
|
select: {
|
||||||
hostPackages: {
|
host_packages: {
|
||||||
where: {
|
where: {
|
||||||
needsUpdate: true
|
needs_update: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
orderBy: { lastUpdate: 'desc' }
|
orderBy: { last_update: 'desc' }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get update counts for each host separately
|
// Get update counts for each host separately
|
||||||
@@ -196,15 +196,15 @@ router.get('/hosts', authenticateToken, requireViewHosts, async (req, res) => {
|
|||||||
hosts.map(async (host) => {
|
hosts.map(async (host) => {
|
||||||
const updatesCount = await prisma.host_packages.count({
|
const updatesCount = await prisma.host_packages.count({
|
||||||
where: {
|
where: {
|
||||||
hostId: host.id,
|
host_id: host.id,
|
||||||
needsUpdate: true
|
needs_update: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get total packages count for this host
|
// Get total packages count for this host
|
||||||
const totalPackagesCount = await prisma.host_packages.count({
|
const totalPackagesCount = await prisma.host_packages.count({
|
||||||
where: {
|
where: {
|
||||||
hostId: host.id
|
host_id: host.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -244,9 +244,9 @@ router.get('/packages', authenticateToken, requireViewPackages, async (req, res)
|
|||||||
try {
|
try {
|
||||||
const packages = await prisma.packages.findMany({
|
const packages = await prisma.packages.findMany({
|
||||||
where: {
|
where: {
|
||||||
hostPackages: {
|
host_packages: {
|
||||||
some: {
|
some: {
|
||||||
needsUpdate: true
|
needs_update: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -255,18 +255,18 @@ router.get('/packages', authenticateToken, requireViewPackages, async (req, res)
|
|||||||
name: true,
|
name: true,
|
||||||
description: true,
|
description: true,
|
||||||
category: true,
|
category: true,
|
||||||
latestVersion: true,
|
latest_version: true,
|
||||||
hostPackages: {
|
host_packages: {
|
||||||
where: { needsUpdate: true },
|
where: { needs_update: true },
|
||||||
select: {
|
select: {
|
||||||
currentVersion: true,
|
current_version: true,
|
||||||
availableVersion: true,
|
available_version: true,
|
||||||
isSecurityUpdate: true,
|
is_security_update: true,
|
||||||
host: {
|
hosts: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true,
|
friendly_name: true,
|
||||||
osType: true
|
os_type: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,14 +284,14 @@ router.get('/packages', authenticateToken, requireViewPackages, async (req, res)
|
|||||||
category: pkg.category,
|
category: pkg.category,
|
||||||
latestVersion: pkg.latest_version,
|
latestVersion: pkg.latest_version,
|
||||||
affectedHostsCount: pkg.host_packages.length,
|
affectedHostsCount: pkg.host_packages.length,
|
||||||
isSecurityUpdate: pkg.host_packages.some(hp => hp.isSecurityUpdate),
|
isSecurityUpdate: pkg.host_packages.some(hp => hp.is_security_update),
|
||||||
affectedHosts: pkg.host_packages.map(hp => ({
|
affectedHosts: pkg.host_packages.map(hp => ({
|
||||||
hostId: hp.host.id,
|
hostId: hp.hosts.id,
|
||||||
friendlyName: hp.host.friendlyName,
|
friendlyName: hp.hosts.friendly_name,
|
||||||
osType: hp.host.osType,
|
osType: hp.hosts.os_type,
|
||||||
currentVersion: hp.currentVersion,
|
currentVersion: hp.current_version,
|
||||||
availableVersion: hp.availableVersion,
|
availableVersion: hp.available_version,
|
||||||
isSecurityUpdate: hp.isSecurityUpdate
|
isSecurityUpdate: hp.is_security_update
|
||||||
}))
|
}))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -310,22 +310,22 @@ router.get('/hosts/:hostId', authenticateToken, requireViewHosts, async (req, re
|
|||||||
const host = await prisma.hosts.findUnique({
|
const host = await prisma.hosts.findUnique({
|
||||||
where: { id: hostId },
|
where: { id: hostId },
|
||||||
include: {
|
include: {
|
||||||
hostGroup: {
|
host_groups: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
color: true
|
color: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hostPackages: {
|
host_packages: {
|
||||||
include: {
|
include: {
|
||||||
package: true
|
packages: true
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
needsUpdate: 'desc'
|
needs_update: 'desc'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateHistory: {
|
update_history: {
|
||||||
orderBy: {
|
orderBy: {
|
||||||
timestamp: 'desc'
|
timestamp: 'desc'
|
||||||
},
|
},
|
||||||
@@ -342,8 +342,8 @@ router.get('/hosts/:hostId', authenticateToken, requireViewHosts, async (req, re
|
|||||||
...host,
|
...host,
|
||||||
stats: {
|
stats: {
|
||||||
totalPackages: host.host_packages.length,
|
totalPackages: host.host_packages.length,
|
||||||
outdatedPackages: host.host_packages.filter(hp => hp.needsUpdate).length,
|
outdatedPackages: host.host_packages.filter(hp => hp.needs_update).length,
|
||||||
securityUpdates: host.host_packages.filter(hp => hp.needsUpdate && hp.isSecurityUpdate).length
|
securityUpdates: host.host_packages.filter(hp => hp.needs_update && hp.is_security_update).length
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -936,14 +936,14 @@ router.patch('/agent/versions/:versionId/current', authenticateToken, requireMan
|
|||||||
|
|
||||||
// First, unset all current versions
|
// First, unset all current versions
|
||||||
await prisma.agent_versions.updateMany({
|
await prisma.agent_versions.updateMany({
|
||||||
where: { isCurrent: true },
|
where: { is_current: true },
|
||||||
data: { isCurrent: false }
|
data: { is_current: false, updated_at: new Date() }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the specified version as current
|
// Set the specified version as current
|
||||||
const agentVersion = await prisma.agent_versions.update({
|
const agentVersion = await prisma.agent_versions.update({
|
||||||
where: { id: versionId },
|
where: { id: versionId },
|
||||||
data: { isCurrent: true }
|
data: { is_current: true, updated_at: new Date() }
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json(agentVersion);
|
res.json(agentVersion);
|
||||||
@@ -960,14 +960,14 @@ router.patch('/agent/versions/:versionId/default', authenticateToken, requireMan
|
|||||||
|
|
||||||
// First, unset all default versions
|
// First, unset all default versions
|
||||||
await prisma.agent_versions.updateMany({
|
await prisma.agent_versions.updateMany({
|
||||||
where: { isDefault: true },
|
where: { is_default: true },
|
||||||
data: { isDefault: false }
|
data: { is_default: false, updated_at: new Date() }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the specified version as default
|
// Set the specified version as default
|
||||||
const agentVersion = await prisma.agent_versions.update({
|
const agentVersion = await prisma.agent_versions.update({
|
||||||
where: { id: versionId },
|
where: { id: versionId },
|
||||||
data: { isDefault: true }
|
data: { is_default: true, updated_at: new Date() }
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json(agentVersion);
|
res.json(agentVersion);
|
||||||
@@ -1030,7 +1030,7 @@ router.patch('/:hostId/friendly-name', authenticateToken, requireManageHosts, [
|
|||||||
// Check if friendly name is already taken by another host
|
// Check if friendly name is already taken by another host
|
||||||
const existingHost = await prisma.hosts.findFirst({
|
const existingHost = await prisma.hosts.findFirst({
|
||||||
where: {
|
where: {
|
||||||
friendlyName: friendlyName,
|
friendly_name: friendlyName,
|
||||||
id: { not: hostId }
|
id: { not: hostId }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1042,23 +1042,23 @@ router.patch('/:hostId/friendly-name', authenticateToken, requireManageHosts, [
|
|||||||
// Update the friendly name
|
// Update the friendly name
|
||||||
const updatedHost = await prisma.hosts.update({
|
const updatedHost = await prisma.hosts.update({
|
||||||
where: { id: hostId },
|
where: { id: hostId },
|
||||||
data: { friendlyName },
|
data: { friendly_name: friendlyName },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true,
|
friendly_name: true,
|
||||||
hostname: true,
|
hostname: true,
|
||||||
ip: true,
|
ip: true,
|
||||||
osType: true,
|
os_type: true,
|
||||||
osVersion: true,
|
os_version: true,
|
||||||
architecture: true,
|
architecture: true,
|
||||||
lastUpdate: true,
|
last_update: true,
|
||||||
status: true,
|
status: true,
|
||||||
hostGroupId: true,
|
host_group_id: true,
|
||||||
agentVersion: true,
|
agent_version: true,
|
||||||
autoUpdate: true,
|
auto_update: true,
|
||||||
createdAt: true,
|
created_at: true,
|
||||||
updatedAt: true,
|
updated_at: true,
|
||||||
hostGroup: {
|
host_groups: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ router.get('/:packageId', async (req, res) => {
|
|||||||
const packageData = await prisma.packages.findUnique({
|
const packageData = await prisma.packages.findUnique({
|
||||||
where: { id: packageId },
|
where: { id: packageId },
|
||||||
include: {
|
include: {
|
||||||
hostPackages: {
|
host_packages: {
|
||||||
include: {
|
include: {
|
||||||
host: {
|
host: {
|
||||||
select: {
|
select: {
|
||||||
@@ -171,21 +171,21 @@ router.get('/:packageId', async (req, res) => {
|
|||||||
|
|
||||||
// Calculate statistics
|
// Calculate statistics
|
||||||
const stats = {
|
const stats = {
|
||||||
totalInstalls: packageData.hostPackages.length,
|
totalInstalls: packageData.host_packages.length,
|
||||||
updatesNeeded: packageData.hostPackages.filter(hp => hp.needsUpdate).length,
|
updatesNeeded: packageData.host_packages.filter(hp => hp.needsUpdate).length,
|
||||||
securityUpdates: packageData.hostPackages.filter(hp => hp.needsUpdate && hp.isSecurityUpdate).length,
|
securityUpdates: packageData.host_packages.filter(hp => hp.needsUpdate && hp.isSecurityUpdate).length,
|
||||||
upToDate: packageData.hostPackages.filter(hp => !hp.needsUpdate).length
|
upToDate: packageData.host_packages.filter(hp => !hp.needsUpdate).length
|
||||||
};
|
};
|
||||||
|
|
||||||
// Group by version
|
// Group by version
|
||||||
const versionDistribution = packageData.hostPackages.reduce((acc, hp) => {
|
const versionDistribution = packageData.host_packages.reduce((acc, hp) => {
|
||||||
const version = hp.currentVersion;
|
const version = hp.currentVersion;
|
||||||
acc[version] = (acc[version] || 0) + 1;
|
acc[version] = (acc[version] || 0) + 1;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
// Group by OS type
|
// Group by OS type
|
||||||
const osDistribution = packageData.hostPackages.reduce((acc, hp) => {
|
const osDistribution = packageData.host_packages.reduce((acc, hp) => {
|
||||||
const osType = hp.host.osType;
|
const osType = hp.host.osType;
|
||||||
acc[osType] = (acc[osType] || 0) + 1;
|
acc[osType] = (acc[osType] || 0) + 1;
|
||||||
return acc;
|
return acc;
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ const prisma = new PrismaClient();
|
|||||||
// Get all repositories with host count
|
// Get all repositories with host count
|
||||||
router.get('/', authenticateToken, requireViewHosts, async (req, res) => {
|
router.get('/', authenticateToken, requireViewHosts, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const repositories = await prisma.repository.findMany({
|
const repositories = await prisma.repositories.findMany({
|
||||||
include: {
|
include: {
|
||||||
hostRepositories: {
|
host_repositories: {
|
||||||
include: {
|
include: {
|
||||||
host: {
|
hosts: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true,
|
friendly_name: true,
|
||||||
status: true
|
status: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ router.get('/', authenticateToken, requireViewHosts, async (req, res) => {
|
|||||||
},
|
},
|
||||||
_count: {
|
_count: {
|
||||||
select: {
|
select: {
|
||||||
hostRepositories: true
|
host_repositories: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -38,15 +38,15 @@ router.get('/', authenticateToken, requireViewHosts, async (req, res) => {
|
|||||||
// Transform data to include host counts and status
|
// Transform data to include host counts and status
|
||||||
const transformedRepos = repositories.map(repo => ({
|
const transformedRepos = repositories.map(repo => ({
|
||||||
...repo,
|
...repo,
|
||||||
hostCount: repo._count.hostRepositories,
|
hostCount: repo._count.host_repositories,
|
||||||
enabledHostCount: repo.hostRepositories.filter(hr => hr.isEnabled).length,
|
enabledHostCount: repo.host_repositories.filter(hr => hr.is_enabled).length,
|
||||||
activeHostCount: repo.hostRepositories.filter(hr => hr.host.status === 'active').length,
|
activeHostCount: repo.host_repositories.filter(hr => hr.hosts.status === 'active').length,
|
||||||
hosts: repo.hostRepositories.map(hr => ({
|
hosts: repo.host_repositories.map(hr => ({
|
||||||
id: hr.host.id,
|
id: hr.hosts.id,
|
||||||
friendlyName: hr.host.friendlyName,
|
friendlyName: hr.hosts.friendly_name,
|
||||||
status: hr.host.status,
|
status: hr.hosts.status,
|
||||||
isEnabled: hr.isEnabled,
|
isEnabled: hr.is_enabled,
|
||||||
lastChecked: hr.lastChecked
|
lastChecked: hr.last_checked
|
||||||
}))
|
}))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -62,19 +62,19 @@ router.get('/host/:hostId', authenticateToken, requireViewHosts, async (req, res
|
|||||||
try {
|
try {
|
||||||
const { hostId } = req.params;
|
const { hostId } = req.params;
|
||||||
|
|
||||||
const hostRepositories = await prisma.hostRepository.findMany({
|
const hostRepositories = await prisma.host_repositories.findMany({
|
||||||
where: { hostId },
|
where: { host_id: hostId },
|
||||||
include: {
|
include: {
|
||||||
repository: true,
|
repositories: true,
|
||||||
host: {
|
hosts: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true
|
friendly_name: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
repository: {
|
repositories: {
|
||||||
name: 'asc'
|
name: 'asc'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,27 +92,27 @@ router.get('/:repositoryId', authenticateToken, requireViewHosts, async (req, re
|
|||||||
try {
|
try {
|
||||||
const { repositoryId } = req.params;
|
const { repositoryId } = req.params;
|
||||||
|
|
||||||
const repository = await prisma.repository.findUnique({
|
const repository = await prisma.repositories.findUnique({
|
||||||
where: { id: repositoryId },
|
where: { id: repositoryId },
|
||||||
include: {
|
include: {
|
||||||
hostRepositories: {
|
host_repositories: {
|
||||||
include: {
|
include: {
|
||||||
host: {
|
hosts: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true,
|
friendly_name: true,
|
||||||
hostname: true,
|
hostname: true,
|
||||||
ip: true,
|
ip: true,
|
||||||
osType: true,
|
os_type: true,
|
||||||
osVersion: true,
|
os_version: true,
|
||||||
status: true,
|
status: true,
|
||||||
lastUpdate: true
|
last_update: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
host: {
|
hosts: {
|
||||||
friendlyName: 'asc'
|
friendly_name: 'asc'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,18 +146,18 @@ router.put('/:repositoryId', authenticateToken, requireManageHosts, [
|
|||||||
const { repositoryId } = req.params;
|
const { repositoryId } = req.params;
|
||||||
const { name, description, isActive, priority } = req.body;
|
const { name, description, isActive, priority } = req.body;
|
||||||
|
|
||||||
const repository = await prisma.repository.update({
|
const repository = await prisma.repositories.update({
|
||||||
where: { id: repositoryId },
|
where: { id: repositoryId },
|
||||||
data: {
|
data: {
|
||||||
...(name && { name }),
|
...(name && { name }),
|
||||||
...(description !== undefined && { description }),
|
...(description !== undefined && { description }),
|
||||||
...(isActive !== undefined && { isActive }),
|
...(isActive !== undefined && { is_active: isActive }),
|
||||||
...(priority !== undefined && { priority })
|
...(priority !== undefined && { priority })
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
_count: {
|
_count: {
|
||||||
select: {
|
select: {
|
||||||
hostRepositories: true
|
host_repositories: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,29 +183,29 @@ router.patch('/host/:hostId/repository/:repositoryId', authenticateToken, requir
|
|||||||
const { hostId, repositoryId } = req.params;
|
const { hostId, repositoryId } = req.params;
|
||||||
const { isEnabled } = req.body;
|
const { isEnabled } = req.body;
|
||||||
|
|
||||||
const hostRepository = await prisma.hostRepository.update({
|
const hostRepository = await prisma.host_repositories.update({
|
||||||
where: {
|
where: {
|
||||||
hostId_repositoryId: {
|
host_id_repository_id: {
|
||||||
hostId,
|
host_id: hostId,
|
||||||
repositoryId
|
repository_id: repositoryId
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
isEnabled,
|
is_enabled: isEnabled,
|
||||||
lastChecked: new Date()
|
last_checked: new Date()
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
repository: true,
|
repositories: true,
|
||||||
host: {
|
hosts: {
|
||||||
select: {
|
select: {
|
||||||
friendlyName: true
|
friendly_name: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
message: `Repository ${isEnabled ? 'enabled' : 'disabled'} for host ${hostRepository.host.friendlyName}`,
|
message: `Repository ${isEnabled ? 'enabled' : 'disabled'} for host ${hostRepository.hosts.friendly_name}`,
|
||||||
hostRepository
|
hostRepository
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -217,25 +217,25 @@ router.patch('/host/:hostId/repository/:repositoryId', authenticateToken, requir
|
|||||||
// Get repository statistics
|
// Get repository statistics
|
||||||
router.get('/stats/summary', authenticateToken, requireViewHosts, async (req, res) => {
|
router.get('/stats/summary', authenticateToken, requireViewHosts, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const stats = await prisma.repository.aggregate({
|
const stats = await prisma.repositories.aggregate({
|
||||||
_count: true
|
_count: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const hostRepoStats = await prisma.hostRepository.aggregate({
|
const hostRepoStats = await prisma.host_repositories.aggregate({
|
||||||
_count: {
|
_count: {
|
||||||
isEnabled: true
|
is_enabled: true
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
isEnabled: true
|
is_enabled: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const secureRepos = await prisma.repository.count({
|
const secureRepos = await prisma.repositories.count({
|
||||||
where: { isSecure: true }
|
where: { is_secure: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
const activeRepos = await prisma.repository.count({
|
const activeRepos = await prisma.repositories.count({
|
||||||
where: { isActive: true }
|
where: { is_active: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
@@ -257,9 +257,9 @@ router.delete('/cleanup/orphaned', authenticateToken, requireManageHosts, async
|
|||||||
console.log('Cleaning up orphaned repositories...');
|
console.log('Cleaning up orphaned repositories...');
|
||||||
|
|
||||||
// Find repositories with no host relationships
|
// Find repositories with no host relationships
|
||||||
const orphanedRepos = await prisma.repository.findMany({
|
const orphanedRepos = await prisma.repositories.findMany({
|
||||||
where: {
|
where: {
|
||||||
hostRepositories: {
|
host_repositories: {
|
||||||
none: {}
|
none: {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ router.delete('/cleanup/orphaned', authenticateToken, requireManageHosts, async
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete orphaned repositories
|
// Delete orphaned repositories
|
||||||
const deleteResult = await prisma.repository.deleteMany({
|
const deleteResult = await prisma.repositories.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
hostRepositories: {
|
hostRepositories: {
|
||||||
none: {}
|
none: {}
|
||||||
|
|||||||
@@ -14,16 +14,16 @@ async function triggerCrontabUpdates() {
|
|||||||
console.log('Triggering crontab updates on all hosts with auto-update enabled...');
|
console.log('Triggering crontab updates on all hosts with auto-update enabled...');
|
||||||
|
|
||||||
// Get all hosts that have auto-update enabled
|
// Get all hosts that have auto-update enabled
|
||||||
const hosts = await prisma.host.findMany({
|
const hosts = await prisma.hosts.findMany({
|
||||||
where: {
|
where: {
|
||||||
autoUpdate: true,
|
auto_update: true,
|
||||||
status: 'active' // Only update active hosts
|
status: 'active' // Only update active hosts
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
friendlyName: true,
|
friendly_name: true,
|
||||||
apiId: true,
|
api_id: true,
|
||||||
apiKey: true
|
api_key: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ async function triggerCrontabUpdates() {
|
|||||||
// This is done by sending a ping with a special flag
|
// This is done by sending a ping with a special flag
|
||||||
for (const host of hosts) {
|
for (const host of hosts) {
|
||||||
try {
|
try {
|
||||||
console.log(`Triggering crontab update for host: ${host.friendlyName}`);
|
console.log(`Triggering crontab update for host: ${host.friendly_name}`);
|
||||||
|
|
||||||
// We'll use the existing ping endpoint but add a special parameter
|
// We'll use the existing ping endpoint but add a special parameter
|
||||||
// The agent will detect this and run update-crontab command
|
// The agent will detect this and run update-crontab command
|
||||||
@@ -58,27 +58,27 @@ async function triggerCrontabUpdates() {
|
|||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Content-Length': Buffer.byteLength(postData),
|
'Content-Length': Buffer.byteLength(postData),
|
||||||
'X-API-ID': host.apiId,
|
'X-API-ID': host.api_id,
|
||||||
'X-API-KEY': host.apiKey
|
'X-API-KEY': host.api_key
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const req = client.request(options, (res) => {
|
const req = client.request(options, (res) => {
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
console.log(`Successfully triggered crontab update for ${host.friendlyName}`);
|
console.log(`Successfully triggered crontab update for ${host.friendly_name}`);
|
||||||
} else {
|
} else {
|
||||||
console.error(`Failed to trigger crontab update for ${host.friendlyName}: ${res.statusCode}`);
|
console.error(`Failed to trigger crontab update for ${host.friendly_name}: ${res.statusCode}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on('error', (error) => {
|
req.on('error', (error) => {
|
||||||
console.error(`Error triggering crontab update for ${host.friendlyName}:`, error.message);
|
console.error(`Error triggering crontab update for ${host.friendly_name}:`, error.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
req.write(postData);
|
req.write(postData);
|
||||||
req.end();
|
req.end();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error triggering crontab update for ${host.friendlyName}:`, error.message);
|
console.error(`Error triggering crontab update for ${host.friendly_name}:`, error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ router.put('/', authenticateToken, requireManageSettings, [
|
|||||||
repositoryType: repositoryType || 'public'
|
repositoryType: repositoryType || 'public'
|
||||||
});
|
});
|
||||||
console.log('Final githubRepoUrl value being saved:', githubRepoUrl !== undefined ? githubRepoUrl : 'git@github.com:9technologygroup/patchmon.net.git');
|
console.log('Final githubRepoUrl value being saved:', githubRepoUrl !== undefined ? githubRepoUrl : 'git@github.com:9technologygroup/patchmon.net.git');
|
||||||
const oldUpdateInterval = settings.updateInterval;
|
const oldUpdateInterval = settings.update_interval;
|
||||||
|
|
||||||
settings = await prisma.settings.update({
|
settings = await prisma.settings.update({
|
||||||
where: { id: settings.id },
|
where: { id: settings.id },
|
||||||
@@ -230,13 +230,13 @@ router.get('/server-url', async (req, res) => {
|
|||||||
const settings = await prisma.settings.findFirst();
|
const settings = await prisma.settings.findFirst();
|
||||||
|
|
||||||
if (!settings) {
|
if (!settings) {
|
||||||
return res.json({ serverUrl: 'http://localhost:3001' });
|
return res.json({ server_url: 'http://localhost:3001' });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({ serverUrl: settings.serverUrl });
|
res.json({ server_url: settings.server_url });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Server URL fetch error:', error);
|
console.error('Server URL fetch error:', error);
|
||||||
res.json({ serverUrl: 'http://localhost:3001' });
|
res.json({ server_url: 'http://localhost:3001' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -250,8 +250,8 @@ router.get('/update-interval', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
updateInterval: settings.updateInterval,
|
updateInterval: settings.update_interval,
|
||||||
cronExpression: `*/${settings.updateInterval} * * * *` // Generate cron expression
|
cronExpression: `*/${settings.update_interval} * * * *` // Generate cron expression
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Update interval fetch error:', error);
|
console.error('Update interval fetch error:', error);
|
||||||
@@ -269,7 +269,7 @@ router.get('/auto-update', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
autoUpdate: settings.autoUpdate || false
|
autoUpdate: settings.auto_update || false
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Auto-update fetch error:', error);
|
console.error('Auto-update fetch error:', error);
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ router.get('/setup', authenticateToken, async (req, res) => {
|
|||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
// Check if user already has TFA enabled
|
// Check if user already has TFA enabled
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
select: { tfaEnabled: true, tfaSecret: true }
|
select: { tfaEnabled: true, tfaSecret: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user.tfaEnabled) {
|
if (user.tfa_enabled) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Two-factor authentication is already enabled for this account'
|
error: 'Two-factor authentication is already enabled for this account'
|
||||||
});
|
});
|
||||||
@@ -36,9 +36,9 @@ router.get('/setup', authenticateToken, async (req, res) => {
|
|||||||
const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
|
const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
|
||||||
|
|
||||||
// Store the secret temporarily (not enabled yet)
|
// Store the secret temporarily (not enabled yet)
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
data: { tfaSecret: secret.base32 }
|
data: { tfa_secret: secret.base32 }
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
@@ -67,18 +67,18 @@ router.post('/verify-setup', authenticateToken, [
|
|||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
// Get user's TFA secret
|
// Get user's TFA secret
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
select: { tfaSecret: true, tfaEnabled: true }
|
select: { tfa_secret: true, tfa_enabled: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user.tfaSecret) {
|
if (!user.tfa_secret) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'No TFA secret found. Please start the setup process first.'
|
error: 'No TFA secret found. Please start the setup process first.'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.tfaEnabled) {
|
if (user.tfa_enabled) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Two-factor authentication is already enabled for this account'
|
error: 'Two-factor authentication is already enabled for this account'
|
||||||
});
|
});
|
||||||
@@ -104,11 +104,11 @@ router.post('/verify-setup', authenticateToken, [
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Enable TFA and store backup codes
|
// Enable TFA and store backup codes
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
data: {
|
data: {
|
||||||
tfaEnabled: true,
|
tfa_enabled: true,
|
||||||
tfaBackupCodes: JSON.stringify(backupCodes)
|
tfa_backup_codes: JSON.stringify(backupCodes)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -136,12 +136,12 @@ router.post('/disable', authenticateToken, [
|
|||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
// Verify password
|
// Verify password
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
select: { passwordHash: true, tfaEnabled: true }
|
select: { password_hash: true, tfa_enabled: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user.tfaEnabled) {
|
if (!user.tfa_enabled) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Two-factor authentication is not enabled for this account'
|
error: 'Two-factor authentication is not enabled for this account'
|
||||||
});
|
});
|
||||||
@@ -151,12 +151,12 @@ router.post('/disable', authenticateToken, [
|
|||||||
// For now, we'll skip password verification for simplicity
|
// For now, we'll skip password verification for simplicity
|
||||||
|
|
||||||
// Disable TFA
|
// Disable TFA
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: userId },
|
where: { id: id },
|
||||||
data: {
|
data: {
|
||||||
tfaEnabled: false,
|
tfa_enabled: false,
|
||||||
tfaSecret: null,
|
tfa_secret: null,
|
||||||
tfaBackupCodes: null
|
tfa_backup_codes: null
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -174,18 +174,18 @@ router.get('/status', authenticateToken, async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
select: {
|
select: {
|
||||||
tfaEnabled: true,
|
tfa_enabled: true,
|
||||||
tfaSecret: true,
|
tfa_secret: true,
|
||||||
tfaBackupCodes: true
|
tfa_backup_codes: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
enabled: user.tfaEnabled,
|
enabled: user.tfa_enabled,
|
||||||
hasBackupCodes: !!user.tfaBackupCodes
|
hasBackupCodes: !!user.tfa_backup_codes
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('TFA status error:', error);
|
console.error('TFA status error:', error);
|
||||||
@@ -199,12 +199,12 @@ router.post('/regenerate-backup-codes', authenticateToken, async (req, res) => {
|
|||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
// Check if TFA is enabled
|
// Check if TFA is enabled
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
select: { tfaEnabled: true }
|
select: { tfaEnabled: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user.tfaEnabled) {
|
if (!user.tfa_enabled) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Two-factor authentication is not enabled for this account'
|
error: 'Two-factor authentication is not enabled for this account'
|
||||||
});
|
});
|
||||||
@@ -216,7 +216,7 @@ router.post('/regenerate-backup-codes', authenticateToken, async (req, res) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Update backup codes
|
// Update backup codes
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
data: {
|
data: {
|
||||||
tfaBackupCodes: JSON.stringify(backupCodes)
|
tfaBackupCodes: JSON.stringify(backupCodes)
|
||||||
@@ -248,17 +248,17 @@ router.post('/verify', [
|
|||||||
const { username, token } = req.body;
|
const { username, token } = req.body;
|
||||||
|
|
||||||
// Get user's TFA secret
|
// Get user's TFA secret
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.users.findUnique({
|
||||||
where: { username },
|
where: { username },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
tfaEnabled: true,
|
tfa_enabled: true,
|
||||||
tfaSecret: true,
|
tfa_secret: true,
|
||||||
tfaBackupCodes: true
|
tfa_backup_codes: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user || !user.tfaEnabled || !user.tfaSecret) {
|
if (!user || !user.tfa_enabled || !user.tfa_secret) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Two-factor authentication is not enabled for this account'
|
error: 'Two-factor authentication is not enabled for this account'
|
||||||
});
|
});
|
||||||
@@ -273,7 +273,7 @@ router.post('/verify', [
|
|||||||
if (isBackupCode) {
|
if (isBackupCode) {
|
||||||
// Remove the used backup code
|
// Remove the used backup code
|
||||||
const updatedBackupCodes = backupCodes.filter(code => code !== token);
|
const updatedBackupCodes = backupCodes.filter(code => code !== token);
|
||||||
await prisma.user.update({
|
await prisma.users.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
data: {
|
data: {
|
||||||
tfaBackupCodes: JSON.stringify(updatedBackupCodes)
|
tfaBackupCodes: JSON.stringify(updatedBackupCodes)
|
||||||
@@ -283,7 +283,7 @@ router.post('/verify', [
|
|||||||
} else {
|
} else {
|
||||||
// Verify TOTP token
|
// Verify TOTP token
|
||||||
verified = speakeasy.totp.verify({
|
verified = speakeasy.totp.verify({
|
||||||
secret: user.tfaSecret,
|
secret: user.tfa_secret,
|
||||||
encoding: 'base32',
|
encoding: 'base32',
|
||||||
token: token,
|
token: token,
|
||||||
window: 2
|
window: 2
|
||||||
|
|||||||
@@ -159,21 +159,21 @@ router.get('/check-updates', authenticateToken, requireManageSettings, async (re
|
|||||||
}
|
}
|
||||||
|
|
||||||
const currentVersion = '1.2.6';
|
const currentVersion = '1.2.6';
|
||||||
const latestVersion = settings.latestVersion || currentVersion;
|
const latestVersion = settings.latest_version || currentVersion;
|
||||||
const isUpdateAvailable = settings.updateAvailable || false;
|
const isUpdateAvailable = settings.update_available || false;
|
||||||
const lastUpdateCheck = settings.lastUpdateCheck;
|
const lastUpdateCheck = settings.last_update_check || null;
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
currentVersion,
|
currentVersion,
|
||||||
latestVersion,
|
latestVersion,
|
||||||
isUpdateAvailable,
|
isUpdateAvailable,
|
||||||
lastUpdateCheck,
|
lastUpdateCheck,
|
||||||
repositoryType: settings.repositoryType || 'public',
|
repositoryType: settings.repo_type || 'public',
|
||||||
latestRelease: {
|
latestRelease: {
|
||||||
tagName: latestVersion ? `v${latestVersion}` : null,
|
tagName: latestVersion ? `v${latestVersion}` : null,
|
||||||
version: latestVersion,
|
version: latestVersion,
|
||||||
repository: settings.githubRepoUrl ? settings.githubRepoUrl.split('/').slice(-2).join('/') : null,
|
repository: settings.github_repo_url ? settings.githubRepoUrl.split('/').slice(-2).join('/') : null,
|
||||||
accessMethod: settings.repositoryType === 'private' ? 'ssh' : 'api'
|
accessMethod: settings.repo_type === 'private' ? 'ssh' : 'api'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user