Files
poshmanager/server/models/profileModel.js
2026-06-25 12:05:53 -05:00

78 lines
2.1 KiB
JavaScript

import bcrypt from 'bcryptjs';
import { db, now } from '../db.js';
import { publicUser } from '../auth.js';
import { config } from '../config.js';
function fullUser(userId) {
return db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
}
export function updateProfile(userId, payload) {
const current = fullUser(userId);
if (!current) throw new Error('User not found');
const nextEmail = current.auth_provider === 'local'
? (payload.email || current.email).toLowerCase()
: current.email;
const duplicate = db.prepare('SELECT id FROM users WHERE email = ? AND id <> ?').get(nextEmail, userId);
if (duplicate) throw new Error('Email address is already in use');
db.prepare(`
UPDATE users
SET email = ?,
display_name = ?,
job_title = ?,
phone = ?,
timezone = ?,
avatar_url = ?,
updated_at = ?
WHERE id = ?
`).run(
nextEmail,
payload.displayName,
payload.jobTitle || '',
payload.phone || '',
payload.timezone || '',
payload.avatarUrl || '',
now(),
userId
);
return publicUser(fullUser(userId));
}
export function updateTheme(userId, theme) {
db.prepare('UPDATE users SET theme = ?, updated_at = ? WHERE id = ?').run(theme, now(), userId);
return publicUser(fullUser(userId));
}
export function changePassword(userId, payload) {
const current = fullUser(userId);
if (!current) throw new Error('User not found');
if (current.auth_provider !== 'local') {
return {
external: true,
provider: current.auth_provider || 'entra',
redirectUrl: config.entra.passwordChangeUrl
};
}
if (!current.password_hash || !bcrypt.compareSync(payload.currentPassword || '', current.password_hash)) {
throw new Error('Current password is incorrect');
}
if (!payload.newPassword || payload.newPassword.length < 8) {
throw new Error('New password must be at least 8 characters');
}
db.prepare('UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?').run(
bcrypt.hashSync(payload.newPassword, 12),
now(),
userId
);
return { changed: true };
}