feat: add ability to disable API key expiration email

This commit is contained in:
Elias Schneider
2025-04-20 18:41:03 +02:00
parent fe1c4b18cd
commit 9122e75101
8 changed files with 28 additions and 8 deletions

View File

@@ -46,4 +46,5 @@ type AppConfigUpdateDto struct {
EmailOneTimeAccessAsAdminEnabled string `json:"emailOneTimeAccessAsAdminEnabled" binding:"required"`
EmailOneTimeAccessAsUnauthenticatedEnabled string `json:"emailOneTimeAccessAsUnauthenticatedEnabled" binding:"required"`
EmailLoginNotificationEnabled string `json:"emailLoginNotificationEnabled" binding:"required"`
EmailApiKeyExpirationEnabled string `json:"emailApiKeyExpirationEnabled" binding:"required"`
}

View File

@@ -30,6 +30,10 @@ func RegisterApiKeyExpiryJob(ctx context.Context, apiKeyService *service.ApiKeyS
}
func (j *ApiKeyEmailJobs) checkAndNotifyExpiringApiKeys(ctx context.Context) error {
// Skip if the feature is disabled
if !j.appConfigService.GetDbConfig().EmailApiKeyExpirationEnabled.IsTrue() {
return nil
}
apiKeys, err := j.apiKeyService.ListExpiringApiKeys(ctx, 7)
if err != nil {

View File

@@ -51,6 +51,7 @@ type AppConfig struct {
EmailLoginNotificationEnabled AppConfigVariable `key:"emailLoginNotificationEnabled"`
EmailOneTimeAccessAsUnauthenticatedEnabled AppConfigVariable `key:"emailOneTimeAccessAsUnauthenticatedEnabled,public"` // Public
EmailOneTimeAccessAsAdminEnabled AppConfigVariable `key:"emailOneTimeAccessAsAdminEnabled,public"` // Public
EmailApiKeyExpirationEnabled AppConfigVariable `key:"emailApiKeyExpirationEnabled"`
// LDAP
LdapEnabled AppConfigVariable `key:"ldapEnabled,public"` // Public
LdapUrl AppConfigVariable `key:"ldapUrl"`

View File

@@ -75,6 +75,7 @@ func (s *AppConfigService) getDefaultDbConfig() *model.AppConfig {
EmailLoginNotificationEnabled: model.AppConfigVariable{Value: "false"},
EmailOneTimeAccessAsUnauthenticatedEnabled: model.AppConfigVariable{Value: "false"},
EmailOneTimeAccessAsAdminEnabled: model.AppConfigVariable{Value: "false"},
EmailApiKeyExpirationEnabled: model.AppConfigVariable{Value: "false"},
// LDAP
LdapEnabled: model.AppConfigVariable{Value: "false"},
LdapUrl: model.AppConfigVariable{},

View File

@@ -340,5 +340,7 @@
"login_code_email_success": "The login code has been sent to the user.",
"send_email": "Send Email",
"show_code": "Show Code",
"callback_url_description": "URL(s) provided by your client. Wildcards (*) are supported, but best avoided for better security."
"callback_url_description": "URL(s) provided by your client. Wildcards (*) are supported, but best avoided for better security.",
"api_key_expiration": "API Key Expiration",
"send_an_email_to_the_user_when_their_api_key_is_about_to_expire": "Send an email to the user when their API key is about to expire."
}

View File

@@ -20,6 +20,7 @@ export type AllAppConfig = AppConfig & {
smtpTls: 'none' | 'starttls' | 'tls';
smtpSkipCertVerify: boolean;
emailLoginNotificationEnabled: boolean;
emailApiKeyExpirationEnabled: boolean;
// LDAP
ldapUrl: string;
ldapBindDn: string;

View File

@@ -41,7 +41,8 @@
smtpSkipCertVerify: z.boolean(),
emailOneTimeAccessAsUnauthenticatedEnabled: z.boolean(),
emailOneTimeAccessAsAdminEnabled: z.boolean(),
emailLoginNotificationEnabled: z.boolean()
emailLoginNotificationEnabled: z.boolean(),
emailApiKeyExpirationEnabled: z.boolean()
});
const { inputs, ...form } = createForm<typeof formSchema>(formSchema, appConfig);
@@ -134,18 +135,25 @@
description={m.send_an_email_to_the_user_when_they_log_in_from_a_new_device()}
bind:checked={$inputs.emailLoginNotificationEnabled.value}
/>
<CheckboxWithLabel
id="email-login-user"
label={m.emai_login_code_requested_by_user()}
description={m.allow_users_to_sign_in_with_a_login_code_sent_to_their_email()}
bind:checked={$inputs.emailOneTimeAccessAsUnauthenticatedEnabled.value}
/>
<CheckboxWithLabel
id="email-login-admin"
label={m.email_login_code_from_admin()}
description={m.allows_an_admin_to_send_a_login_code_to_the_user()}
bind:checked={$inputs.emailOneTimeAccessAsAdminEnabled.value}
/>
<CheckboxWithLabel
id="api-key-expiration"
label={m.api_key_expiration()}
description={m.send_an_email_to_the_user_when_their_api_key_is_about_to_expire()}
bind:checked={$inputs.emailApiKeyExpirationEnabled.value}
/>
<CheckboxWithLabel
id="email-login-user"
label={m.emai_login_code_requested_by_user()}
description={m.allow_users_to_sign_in_with_a_login_code_sent_to_their_email()}
bind:checked={$inputs.emailOneTimeAccessAsUnauthenticatedEnabled.value}
/>
</div>
</fieldset>
<div class="mt-8 flex flex-wrap justify-end gap-3">

View File

@@ -34,6 +34,7 @@ test('Update email configuration', async ({ page }) => {
await page.getByLabel('Email Login Notification').click();
await page.getByLabel('Email Login Code Requested by User').click();
await page.getByLabel('Email Login Code from Admin').click();
await page.getByLabel('API Key Expiration').click();
await page.getByRole('button', { name: 'Save' }).nth(1).click();
@@ -49,6 +50,7 @@ test('Update email configuration', async ({ page }) => {
await expect(page.getByLabel('Email Login Notification')).toBeChecked();
await expect(page.getByLabel('Email Login Code Requested by User')).toBeChecked();
await expect(page.getByLabel('Email Login Code from Admin')).toBeChecked();
await expect(page.getByLabel('API Key Expiration')).toBeChecked();
});
test('Update LDAP configuration', async ({ page }) => {