Files
pulse-signage/src/web/routes/account/password.js
T

66 lines
3.3 KiB
JavaScript

// Account password page renderer and return URL normalization.
const { renderView } = require('#src/web/view');
const { resolvePasskeyRpID } = require('#src/web/lib/auth/better-auth');
function buildPasswordRequirementsText(requirements) {
const requiredCategories = [];
if (requirements.requireLowercase) requiredCategories.push('lowercase');
if (requirements.requireUppercase) requiredCategories.push('uppercase');
if (requirements.requireNumber) requiredCategories.push('number');
if (requirements.requireSymbol) requiredCategories.push('symbol');
return requiredCategories.length
? 'Use at least ' + requirements.minimumLength + ' characters and include ' + requiredCategories.join(', ') + '.'
: requirements.minimumCategories === 4
? 'Use at least ' + requirements.minimumLength + ' characters and include uppercase, lowercase, number, and symbol.'
: 'Use at least ' + requirements.minimumLength + ' characters and include ' + requirements.minimumCategories + ' of: uppercase, lowercase, number, and symbol.';
}
function normalizeReturnUrl(value) {
const url = String(value || '').trim();
if (!url || url === '/account' || url.indexOf('/account?') === 0) {
return '/dashboard';
}
if (!/^\/(?:account|dashboard)(?:\/|\?|$)/.test(url)) {
return '/dashboard';
}
return url;
}
module.exports = function renderAccountPage(currentUser, message, returnUrl, allowUserSessionRevocation, sessions, passwordRequirements, authMethods, passkeys) {
const requirements = passwordRequirements || {
minimumLength: 10,
minimumCategories: 3,
requireLowercase: false,
requireUppercase: false,
requireNumber: false,
requireSymbol: false
};
return renderView('account/index', {
title: 'My account',
active: 'account',
currentUser: currentUser || null,
message: message || '',
username: currentUser ? currentUser.username : '',
name: currentUser ? String(currentUser.name || '') : '',
email: currentUser ? String(currentUser.email || '') : '',
emailPending: Boolean(currentUser && currentUser.pending_email),
pendingEmail: currentUser ? String(currentUser.pending_email || '') : '',
pendingEmailChange: Boolean(currentUser && currentUser.pending_email && String(currentUser.pending_email).trim().toLowerCase() !== String(currentUser.email || '').trim().toLowerCase()),
emailVerified: Boolean(currentUser && currentUser.email_verified),
authMethods: Array.isArray(authMethods) ? authMethods : [],
passkeys: Array.isArray(passkeys) ? passkeys : [],
passkeyRpID: resolvePasskeyRpID(process.env.BETTER_AUTH_URL || process.env.WEB_PUBLIC_URL),
returnUrl: normalizeReturnUrl(returnUrl),
allowUserSessionRevocation: Boolean(allowUserSessionRevocation),
sessions: Array.isArray(sessions) ? sessions : [],
passwordMinimumLength: requirements.minimumLength,
passwordRequirementsText: buildPasswordRequirementsText(requirements),
twoFactorEnabled: Boolean(currentUser && currentUser.twoFactorEnabled),
requiresTwoFactor: Boolean(currentUser && currentUser.requiresTwoFactor),
canManageTwoFactor: Boolean(currentUser && !currentUser.isViewingAs),
scripts: ['vendor/qr-code-styling/qr-code-styling-loader.js', 'js/auth/passkey-client.js', 'js/account/two-factor.js', 'js/account/passkeys.js']
});
};
module.exports.buildPasswordRequirementsText = buildPasswordRequirementsText;