From 7b3ce50a17b111a4f838a6c74020a1fd9f591b03 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 27 May 2026 14:01:47 +0200 Subject: [PATCH] feat: add set-password endpoint for admin user management Co-Authored-By: Claude Sonnet 4.6 --- src/routes/users.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/routes/users.js b/src/routes/users.js index 5f6f257..1582cf8 100644 --- a/src/routes/users.js +++ b/src/routes/users.js @@ -1,4 +1,5 @@ const router = require('express').Router(); +const bcrypt = require('bcryptjs'); const { query } = require('../db'); const ROLES = ['end-user', 'admin']; @@ -50,6 +51,23 @@ router.patch('/:id', async (req, res, next) => { } catch (err) { next(err); } }); +// POST /api/users/:id/set-password (admin only — sets a new bcrypt password) +router.post('/:id/set-password', async (req, res, next) => { + try { + const { password } = req.body; + if (!password || password.length < 8) + return res.status(400).json({ error: 'password must be at least 8 characters' }); + const hash = await bcrypt.hash(password, 12); + const result = await query( + `UPDATE users SET password_hash = $1, is_active = true, updated_at = now() + WHERE id = $2 RETURNING id, email, role, is_active`, + [hash, req.params.id] + ); + if (!result.rows.length) return res.status(404).json({ error: 'Not found' }); + res.json({ message: 'Password updated', user: result.rows[0] }); + } catch (err) { next(err); } +}); + // DELETE /api/users/:id router.delete('/:id', async (req, res, next) => { try {