update translation and send password reset email

This commit is contained in:
miloschwartz
2025-10-24 17:18:34 -07:00
parent 1e70e4289b
commit 460df46abc
3 changed files with 28 additions and 13 deletions

View File

@@ -1766,8 +1766,13 @@
"maxSessionLengthDisabledDescription": "This feature requires a valid license (Enterprise) or active subscription (SaaS)", "maxSessionLengthDisabledDescription": "This feature requires a valid license (Enterprise) or active subscription (SaaS)",
"selectSessionLength": "Select session length", "selectSessionLength": "Select session length",
"passwordExpiryDays": "Password Expiry", "passwordExpiryDays": "Password Expiry",
"passwordExpiryDescription": "Set the number of days before users are required to change their password.", "editPasswordExpiryDescription": "Set the number of days before users are required to change their password.",
"selectPasswordExpiry": "Select password expiry", "selectPasswordExpiry": "Select password expiry",
"30Days": "30 days",
"60Days": "60 days",
"90Days": "90 days",
"180Days": "180 days",
"1Year": "1 year",
"subscriptionBadge": "Subscription Required", "subscriptionBadge": "Subscription Required",
"authPageErrorUpdateMessage": "An error occurred while updating the auth page settings", "authPageErrorUpdateMessage": "An error occurred while updating the auth page settings",
"authPageUpdated": "Auth page updated successfully", "authPageUpdated": "Auth page updated successfully",

View File

@@ -18,6 +18,9 @@ import { sessions, resourceSessions } from "@server/db";
import { and, eq, ne, inArray } from "drizzle-orm"; import { and, eq, ne, inArray } from "drizzle-orm";
import { passwordSchema } from "@server/auth/passwordSchema"; import { passwordSchema } from "@server/auth/passwordSchema";
import { UserType } from "@server/types/UserTypes"; import { UserType } from "@server/types/UserTypes";
import { sendEmail } from "@server/emails";
import ConfirmPasswordReset from "@server/emails/templates/NotifyResetPassword";
import config from "@server/lib/config";
export const changePasswordBody = z export const changePasswordBody = z
.object({ .object({
@@ -158,7 +161,16 @@ export async function changePassword(
// Invalidate all sessions except the current one // Invalidate all sessions except the current one
await invalidateAllSessionsExceptCurrent(user.userId, req.session.sessionId); await invalidateAllSessionsExceptCurrent(user.userId, req.session.sessionId);
// TODO: send email to user confirming password change try {
const email = user.email!;
await sendEmail(ConfirmPasswordReset({ email }), {
from: config.getNoReplyEmail(),
to: email,
subject: "Password Reset Confirmation"
});
} catch (e) {
logger.error("Failed to send password reset confirmation email", e);
}
return response(res, { return response(res, {
data: null, data: null,

View File

@@ -65,14 +65,14 @@ const SESSION_LENGTH_OPTIONS = [
{ value: 4320, label: "180 days" } // 180 * 24 = 4320 hours { value: 4320, label: "180 days" } // 180 * 24 = 4320 hours
]; ];
// Password expiry options in days // Password expiry options in days - will be translated in component
const PASSWORD_EXPIRY_OPTIONS = [ const PASSWORD_EXPIRY_OPTIONS = [
{ value: null, label: "Never Expire" }, { value: null, labelKey: "neverExpire" },
{ value: 30, label: "30 days" }, { value: 30, labelKey: "30Days" },
{ value: 60, label: "60 days" }, { value: 60, labelKey: "60Days" },
{ value: 90, label: "90 days" }, { value: 90, labelKey: "90Days" },
{ value: 180, label: "180 days" }, { value: 180, labelKey: "180Days" },
{ value: 365, label: "1 year" } { value: 365, labelKey: "1Year" }
]; ];
// Schema for general organization settings // Schema for general organization settings
@@ -511,9 +511,7 @@ export default function GeneralPage() {
: option.value.toString() : option.value.toString()
} }
> >
{ {t(option.labelKey)}
option.label
}
</SelectItem> </SelectItem>
) )
)} )}
@@ -523,7 +521,7 @@ export default function GeneralPage() {
<FormDescription> <FormDescription>
<FormMessage /> <FormMessage />
{t( {t(
"passwordExpiryDescription" "editPasswordExpiryDescription"
)} )}
</FormDescription> </FormDescription>
</FormItem> </FormItem>