Initial
This commit is contained in:
58
server/models/userModel.js
Normal file
58
server/models/userModel.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { db, id, now } from '../db.js';
|
||||
import { publicUser } from '../auth.js';
|
||||
|
||||
export function listUsers() {
|
||||
return db.prepare('SELECT * FROM users ORDER BY display_name').all().map((row) => ({
|
||||
...publicUser(row),
|
||||
groups: db.prepare(`
|
||||
SELECT g.id, g.name
|
||||
FROM groups g
|
||||
INNER JOIN user_groups ug ON ug.group_id = g.id
|
||||
WHERE ug.user_id = ?
|
||||
ORDER BY g.name
|
||||
`).all(row.id)
|
||||
}));
|
||||
}
|
||||
|
||||
// Provision (or refresh) a user that authenticated through Microsoft Entra.
|
||||
// Matches on email: an existing account is marked Entra-backed in place so the
|
||||
// operator keeps their resources, and a brand-new account is created with no
|
||||
// local password.
|
||||
export function findOrProvisionEntraUser({ email, displayName }) {
|
||||
const normalized = String(email || '').toLowerCase();
|
||||
const existing = db.prepare('SELECT * FROM users WHERE email = ?').get(normalized);
|
||||
if (existing) {
|
||||
db.prepare('UPDATE users SET display_name = ?, auth_provider = ?, updated_at = ? WHERE id = ?')
|
||||
.run(displayName || existing.display_name, 'entra', now(), existing.id);
|
||||
return db.prepare('SELECT * FROM users WHERE id = ?').get(existing.id);
|
||||
}
|
||||
const userId = id('usr');
|
||||
const timestamp = now();
|
||||
// First user on a fresh install becomes admin; subsequent Entra users are standard.
|
||||
const isFirstUser = db.prepare('SELECT COUNT(*) AS count FROM users').get().count === 0;
|
||||
db.prepare(`
|
||||
INSERT INTO users (id, email, display_name, password_hash, auth_provider, role, created_at, updated_at)
|
||||
VALUES (?, ?, ?, NULL, 'entra', ?, ?, ?)
|
||||
`).run(userId, normalized, displayName || normalized, isFirstUser ? 'admin' : 'user', timestamp, timestamp);
|
||||
return db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
|
||||
}
|
||||
|
||||
export function createUser(payload) {
|
||||
const userId = id('usr');
|
||||
const timestamp = now();
|
||||
db.prepare(`
|
||||
INSERT INTO users (id, email, display_name, password_hash, auth_provider, role, created_at)
|
||||
VALUES (?, ?, ?, ?, 'local', ?, ?)
|
||||
`).run(
|
||||
userId,
|
||||
payload.email.toLowerCase(),
|
||||
payload.displayName,
|
||||
payload.password ? bcrypt.hashSync(payload.password, 12) : null,
|
||||
payload.role,
|
||||
timestamp
|
||||
);
|
||||
const groupStmt = db.prepare('INSERT OR IGNORE INTO user_groups (user_id, group_id) VALUES (?, ?)');
|
||||
for (const groupId of payload.groupIds || []) groupStmt.run(userId, groupId);
|
||||
return listUsers().find((user) => user.id === userId);
|
||||
}
|
||||
Reference in New Issue
Block a user