1
0
mirror of https://github.com/pocket-id/pocket-id.git synced 2026-02-04 12:46:45 +00:00

fix: allow changing "require email address" if no SMTP credentials present

This commit is contained in:
Elias Schneider
2026-01-06 13:49:10 +01:00
parent 646f849441
commit 8c68b08c12
3 changed files with 57 additions and 17 deletions

View File

@@ -499,5 +499,7 @@
"save_and_sync": "Save and Sync", "save_and_sync": "Save and Sync",
"scim_save_changes_description": "You have to save the changes before starting a SCIM sync. Do you want to save now?", "scim_save_changes_description": "You have to save the changes before starting a SCIM sync. Do you want to save now?",
"scopes": "Scopes", "scopes": "Scopes",
"issuer_url": "Issuer URL" "issuer_url": "Issuer URL",
"smtp_field_required_when_other_provided": "Required when any SMTP setting is provided",
"smtp_field_required_when_email_enabled": "Required when email notifications are enabled"
} }

View File

@@ -21,7 +21,7 @@ export type AllAppConfig = AppConfig & {
signupDefaultCustomClaims: CustomClaim[]; signupDefaultCustomClaims: CustomClaim[];
// Email // Email
smtpHost: string; smtpHost: string;
smtpPort: number; smtpPort: string;
smtpFrom: string; smtpFrom: string;
smtpUser: string; smtpUser: string;
smtpPassword: string; smtpPassword: string;

View File

@@ -31,20 +31,58 @@
let isSendingTestEmail = $state(false); let isSendingTestEmail = $state(false);
const formSchema = z.object({ const formSchema = z
requireUserEmail: z.boolean(), .object({
smtpHost: z.string().min(1), requireUserEmail: z.boolean(),
smtpPort: z.number().min(1), smtpHost: z.string().optional(),
smtpUser: z.string(), smtpPort: z
smtpPassword: z.string(), .preprocess((v: string) => (!v ? undefined : parseInt(v)), z.number().optional().nullable())
smtpFrom: z.email(), .transform((v) => v?.toString() ?? '')
smtpTls: z.enum(['none', 'starttls', 'tls']), .optional(),
smtpSkipCertVerify: z.boolean(), smtpUser: z.string().optional(),
emailOneTimeAccessAsUnauthenticatedEnabled: z.boolean(), smtpPassword: z.string().optional(),
emailOneTimeAccessAsAdminEnabled: z.boolean(), smtpFrom: z.email().optional(),
emailLoginNotificationEnabled: z.boolean(), smtpTls: z.enum(['none', 'starttls', 'tls']),
emailApiKeyExpirationEnabled: z.boolean() smtpSkipCertVerify: z.boolean(),
}); emailOneTimeAccessAsUnauthenticatedEnabled: z.boolean(),
emailOneTimeAccessAsAdminEnabled: z.boolean(),
emailLoginNotificationEnabled: z.boolean(),
emailApiKeyExpirationEnabled: z.boolean()
})
.superRefine((data, ctx) => {
const requiredSmtpFields: (keyof z.infer<typeof formSchema>)[] = [
'smtpHost',
'smtpPort',
'smtpFrom'
];
const emailFields: (keyof z.infer<typeof formSchema>)[] = [
'emailOneTimeAccessAsUnauthenticatedEnabled',
'emailOneTimeAccessAsAdminEnabled',
'emailLoginNotificationEnabled',
'emailApiKeyExpirationEnabled'
];
function requireFieldsWhen(condition: boolean, message: string) {
if (!condition) return;
for (const f of requiredSmtpFields) {
if (!data[f]) {
ctx.addIssue({
code: 'custom',
path: [f],
message
});
}
}
}
const anyProvided = requiredSmtpFields.some((f) => !!data[f]);
requireFieldsWhen(anyProvided, m.smtp_field_required_when_other_provided());
const emailEnabled = emailFields.some((f) => data[f]);
requireFieldsWhen(emailEnabled, m.smtp_field_required_when_email_enabled());
});
let { inputs, ...form } = $derived(createForm(formSchema, appConfig)); let { inputs, ...form } = $derived(createForm(formSchema, appConfig));
@@ -106,7 +144,7 @@
bind:checked={$inputs.requireUserEmail.value} bind:checked={$inputs.requireUserEmail.value}
/> />
<h4 class="mt-10 text-lg font-semibold">{m.smtp_configuration()}</h4> <h4 class="mt-10 text-lg font-semibold">{m.smtp_configuration()}</h4>
<div class="mt-4 grid grid-cols-1 items-end gap-5 md:grid-cols-2"> <div class="mt-4 grid grid-cols-1 items-start gap-5 md:grid-cols-2">
<FormInput label={m.smtp_host()} bind:input={$inputs.smtpHost} /> <FormInput label={m.smtp_host()} bind:input={$inputs.smtpHost} />
<FormInput label={m.smtp_port()} type="number" bind:input={$inputs.smtpPort} /> <FormInput label={m.smtp_port()} type="number" bind:input={$inputs.smtpPort} />
<FormInput label={m.smtp_user()} bind:input={$inputs.smtpUser} /> <FormInput label={m.smtp_user()} bind:input={$inputs.smtpUser} />