feat: add password reset, SMTP settings, and Add Account button
Password reset: users with a registered email can request a reset link from the login screen. A one-hour signed token is emailed via SMTP; clicking the link opens a set-new-password form. Tokens are hashed (SHA-256) before storage and invalidated after use. SMTP settings: admin-only panel in the Users modal lets admins configure host, port, encryption, credentials, and from address. Settings persisted in a new key-value settings table. The SMTP password is never returned to the client. Users: email field added to the create/edit form and stored in a new users.email column. Email is used for password reset lookup. Add Account: admins now have a + button in the header that opens the existing setup wizard to add additional checking accounts. Schema: adds password_reset_tokens and settings tables with automatic runtime migrations for existing databases.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
const nodemailer = require('nodemailer');
|
||||
const db = require('../db/database');
|
||||
|
||||
function getSmtpSettings() {
|
||||
const rows = db.prepare("SELECT key, value FROM settings WHERE key LIKE 'smtp_%'").all();
|
||||
const s = Object.fromEntries(rows.map(r => [r.key, r.value || '']));
|
||||
return {
|
||||
host: s.smtp_host || '',
|
||||
port: parseInt(s.smtp_port, 10) || 587,
|
||||
secure: s.smtp_secure === '1',
|
||||
user: s.smtp_user || '',
|
||||
pass: s.smtp_pass || '',
|
||||
from: s.smtp_from || '',
|
||||
};
|
||||
}
|
||||
|
||||
async function sendPasswordReset(toEmail, resetLink) {
|
||||
const s = getSmtpSettings();
|
||||
if (!s.host || !s.from) {
|
||||
throw new Error('SMTP is not configured. Ask an admin to configure email settings.');
|
||||
}
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: s.host,
|
||||
port: s.port,
|
||||
secure: s.secure,
|
||||
auth: s.user ? { user: s.user, pass: s.pass } : undefined,
|
||||
});
|
||||
await transporter.sendMail({
|
||||
from: s.from,
|
||||
to: toEmail,
|
||||
subject: 'ezcheck Password Reset',
|
||||
text: `Click the link below to reset your password. This link expires in 1 hour.\n\n${resetLink}\n\nIf you did not request this, ignore this email.`,
|
||||
html: `<p>Click the link below to reset your password. This link expires in 1 hour.</p><p><a href="${resetLink}">${resetLink}</a></p><p>If you did not request this, ignore this email.</p>`,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { getSmtpSettings, sendPasswordReset };
|
||||
Reference in New Issue
Block a user