refactor(notification): make username and password optional (smtp) (#126)
This commit is contained in:
parent
ef8fd7228f
commit
c3acc26e05
5 changed files with 83 additions and 31 deletions
|
|
@ -164,6 +164,11 @@ export type ListVolumesResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -191,7 +196,7 @@ export type ListVolumesResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
}>;
|
||||
};
|
||||
|
|
@ -211,6 +216,11 @@ export type CreateVolumeData = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -255,6 +265,11 @@ export type CreateVolumeResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -282,7 +297,7 @@ export type CreateVolumeResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
};
|
||||
};
|
||||
|
|
@ -302,6 +317,11 @@ export type TestConnectionData = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -399,6 +419,11 @@ export type GetVolumeResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -426,7 +451,7 @@ export type GetVolumeResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
};
|
||||
};
|
||||
|
|
@ -448,6 +473,11 @@ export type UpdateVolumeData = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -501,6 +531,11 @@ export type UpdateVolumeResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -528,7 +563,7 @@ export type UpdateVolumeResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
};
|
||||
};
|
||||
|
|
@ -1397,6 +1432,11 @@ export type ListBackupSchedulesResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -1424,7 +1464,7 @@ export type ListBackupSchedulesResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
};
|
||||
volumeId: number;
|
||||
|
|
@ -1636,6 +1676,11 @@ export type GetBackupScheduleResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -1663,7 +1708,7 @@ export type GetBackupScheduleResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
};
|
||||
volumeId: number;
|
||||
|
|
@ -1856,6 +1901,11 @@ export type GetBackupScheduleForVolumeResponses = {
|
|||
version: '3' | '4' | '4.1';
|
||||
port?: number;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'rclone';
|
||||
path: string;
|
||||
remote: string;
|
||||
readOnly?: boolean;
|
||||
} | {
|
||||
backend: 'smb';
|
||||
password: string;
|
||||
|
|
@ -1883,7 +1933,7 @@ export type GetBackupScheduleForVolumeResponses = {
|
|||
name: string;
|
||||
shortId: string;
|
||||
status: 'error' | 'mounted' | 'unmounted';
|
||||
type: 'directory' | 'nfs' | 'smb' | 'webdav';
|
||||
type: 'directory' | 'nfs' | 'rclone' | 'smb' | 'webdav';
|
||||
updatedAt: number;
|
||||
};
|
||||
volumeId: number;
|
||||
|
|
@ -1987,13 +2037,13 @@ export type GetScheduleNotificationsResponses = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2077,13 +2127,13 @@ export type UpdateScheduleNotificationsResponses = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2380,13 +2430,13 @@ export type ListNotificationDestinationsResponses = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2441,13 +2491,13 @@ export type CreateNotificationDestinationData = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2501,13 +2551,13 @@ export type CreateNotificationDestinationResponses = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2608,13 +2658,13 @@ export type GetNotificationDestinationResponses = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2669,13 +2719,13 @@ export type UpdateNotificationDestinationData = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
@ -2739,13 +2789,13 @@ export type UpdateNotificationDestinationResponses = {
|
|||
type: 'telegram';
|
||||
} | {
|
||||
from: string;
|
||||
password: string;
|
||||
smtpHost: string;
|
||||
smtpPort: number;
|
||||
to: Array<string>;
|
||||
type: 'email';
|
||||
useTLS: boolean;
|
||||
username: string;
|
||||
password?: string;
|
||||
username?: string;
|
||||
} | {
|
||||
priority: 'default' | 'high' | 'low' | 'max' | 'min';
|
||||
topic: string;
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValue
|
|||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormLabel>Username (Optional)</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder="user@example.com" />
|
||||
</FormControl>
|
||||
|
|
@ -211,7 +211,7 @@ export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValue
|
|||
name="password"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Password</FormLabel>
|
||||
<FormLabel>Password (Optional)</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} type="password" placeholder="••••••••" />
|
||||
</FormControl>
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ export const emailNotificationConfigSchema = type({
|
|||
type: "'email'",
|
||||
smtpHost: "string",
|
||||
smtpPort: "1 <= number <= 65535",
|
||||
username: "string",
|
||||
password: "string",
|
||||
username: "string?",
|
||||
password: "string?",
|
||||
from: "string",
|
||||
to: "string[]",
|
||||
useTLS: "boolean",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import type { NotificationConfig } from "~/schemas/notifications";
|
||||
|
||||
export function buildEmailShoutrrrUrl(config: Extract<NotificationConfig, { type: "email" }>): string {
|
||||
const auth = `${encodeURIComponent(config.username)}:${encodeURIComponent(config.password)}`;
|
||||
const auth = config.username && config.password
|
||||
? `${encodeURIComponent(config.username)}:${encodeURIComponent(config.password)}@`
|
||||
: "";
|
||||
const host = `${config.smtpHost}:${config.smtpPort}`;
|
||||
const toRecipients = config.to.map((email) => encodeURIComponent(email)).join(",");
|
||||
const useStartTLS = config.useTLS ? "yes" : "no";
|
||||
|
||||
return `smtp://${auth}@${host}/?from=${encodeURIComponent(config.from)}&to=${toRecipients}&starttls=${useStartTLS}`;
|
||||
return `smtp://${auth}${host}/?from=${encodeURIComponent(config.from)}&to=${toRecipients}&starttls=${useStartTLS}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ async function encryptSensitiveFields(config: NotificationConfig): Promise<Notif
|
|||
case "email":
|
||||
return {
|
||||
...config,
|
||||
password: await cryptoUtils.encrypt(config.password),
|
||||
password: config.password ? await cryptoUtils.encrypt(config.password) : undefined,
|
||||
};
|
||||
case "slack":
|
||||
return {
|
||||
|
|
@ -85,7 +85,7 @@ async function decryptSensitiveFields(config: NotificationConfig): Promise<Notif
|
|||
case "email":
|
||||
return {
|
||||
...config,
|
||||
password: await cryptoUtils.decrypt(config.password),
|
||||
password: config.password ? await cryptoUtils.decrypt(config.password) : undefined,
|
||||
};
|
||||
case "slack":
|
||||
return {
|
||||
|
|
|
|||
Loading…
Reference in a new issue