Merge branch 'main' into config-export-feature
This commit is contained in:
commit
b84ae02ec6
5 changed files with 51 additions and 9 deletions
|
|
@ -518,6 +518,22 @@ export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValue
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="accessToken"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Access token (Optional)</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<SecretInput {...field} placeholder="••••••••" />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
Access token for server authentication. Will take precedence over username/password if set.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="priority"
|
name="priority"
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ export const ntfyNotificationConfigSchema = type({
|
||||||
priority: "'max' | 'high' | 'default' | 'low' | 'min'",
|
priority: "'max' | 'high' | 'default' | 'low' | 'min'",
|
||||||
username: "string?",
|
username: "string?",
|
||||||
password: "string?",
|
password: "string?",
|
||||||
|
accessToken: "string?",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const pushoverNotificationConfigSchema = type({
|
export const pushoverNotificationConfigSchema = type({
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
throw new BadRequestError("Volume is not mounted");
|
throw new BadRequestError("Volume is not mounted");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Starting backup for volume ${volume.name} to repository ${repository.name}`);
|
logger.info(`Starting backup ${schedule.name} for volume ${volume.name} to repository ${repository.name}`);
|
||||||
|
|
||||||
serverEvents.emit("backup:started", {
|
serverEvents.emit("backup:started", {
|
||||||
scheduleId,
|
scheduleId,
|
||||||
|
|
@ -248,6 +248,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
.sendBackupNotification(scheduleId, "start", {
|
.sendBackupNotification(scheduleId, "start", {
|
||||||
volumeName: volume.name,
|
volumeName: volume.name,
|
||||||
repositoryName: repository.name,
|
repositoryName: repository.name,
|
||||||
|
scheduleName: schedule.name,
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.error(`Failed to send backup start notification: ${toMessage(error)}`);
|
logger.error(`Failed to send backup start notification: ${toMessage(error)}`);
|
||||||
|
|
@ -341,9 +342,13 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
.where(eq(backupSchedulesTable.id, scheduleId));
|
.where(eq(backupSchedulesTable.id, scheduleId));
|
||||||
|
|
||||||
if (finalStatus === "warning") {
|
if (finalStatus === "warning") {
|
||||||
logger.warn(`Backup completed with warnings for volume ${volume.name} to repository ${repository.name}`);
|
logger.warn(
|
||||||
|
`Backup ${schedule.name} completed with warnings for volume ${volume.name} to repository ${repository.name}`,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Backup completed successfully for volume ${volume.name} to repository ${repository.name}`);
|
logger.info(
|
||||||
|
`Backup ${schedule.name} completed successfully for volume ${volume.name} to repository ${repository.name}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
serverEvents.emit("backup:completed", {
|
serverEvents.emit("backup:completed", {
|
||||||
|
|
@ -357,12 +362,15 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
.sendBackupNotification(scheduleId, finalStatus === "success" ? "success" : "warning", {
|
.sendBackupNotification(scheduleId, finalStatus === "success" ? "success" : "warning", {
|
||||||
volumeName: volume.name,
|
volumeName: volume.name,
|
||||||
repositoryName: repository.name,
|
repositoryName: repository.name,
|
||||||
|
scheduleName: schedule.name,
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.error(`Failed to send backup success notification: ${toMessage(error)}`);
|
logger.error(`Failed to send backup success notification: ${toMessage(error)}`);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Backup failed for volume ${volume.name} to repository ${repository.name}: ${toMessage(error)}`);
|
logger.error(
|
||||||
|
`Backup ${schedule.name} failed for volume ${volume.name} to repository ${repository.name}: ${toMessage(error)}`,
|
||||||
|
);
|
||||||
|
|
||||||
await db
|
await db
|
||||||
.update(backupSchedulesTable)
|
.update(backupSchedulesTable)
|
||||||
|
|
@ -385,6 +393,7 @@ const executeBackup = async (scheduleId: number, manual = false) => {
|
||||||
.sendBackupNotification(scheduleId, "failure", {
|
.sendBackupNotification(scheduleId, "failure", {
|
||||||
volumeName: volume.name,
|
volumeName: volume.name,
|
||||||
repositoryName: repository.name,
|
repositoryName: repository.name,
|
||||||
|
scheduleName: schedule.name,
|
||||||
error: toMessage(error),
|
error: toMessage(error),
|
||||||
})
|
})
|
||||||
.catch((notifError) => {
|
.catch((notifError) => {
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,17 @@ export function buildNtfyShoutrrrUrl(config: Extract<NotificationConfig, { type:
|
||||||
let shoutrrrUrl: string;
|
let shoutrrrUrl: string;
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
|
const { username, password, accessToken } = config;
|
||||||
|
|
||||||
const auth =
|
let auth = "";
|
||||||
config.username && config.password
|
|
||||||
? `${encodeURIComponent(config.username)}:${encodeURIComponent(config.password)}@`
|
if (username && password) {
|
||||||
: "";
|
auth = `${encodeURIComponent(username)}:${encodeURIComponent(password)}@`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accessToken) {
|
||||||
|
auth = `:${encodeURIComponent(accessToken)}@`;
|
||||||
|
}
|
||||||
|
|
||||||
if (config.serverUrl) {
|
if (config.serverUrl) {
|
||||||
const url = new URL(config.serverUrl);
|
const url = new URL(config.serverUrl);
|
||||||
|
|
|
||||||
|
|
@ -388,6 +388,7 @@ function buildNotificationMessage(
|
||||||
body: [
|
body: [
|
||||||
`Volume: ${context.volumeName}`,
|
`Volume: ${context.volumeName}`,
|
||||||
`Repository: ${context.repositoryName}`,
|
`Repository: ${context.repositoryName}`,
|
||||||
|
context.scheduleName ? `Schedule: ${context.scheduleName}` : null,
|
||||||
context.duration ? `Duration: ${Math.round(context.duration / 1000)}s` : null,
|
context.duration ? `Duration: ${Math.round(context.duration / 1000)}s` : null,
|
||||||
context.filesProcessed !== undefined ? `Files: ${context.filesProcessed}` : null,
|
context.filesProcessed !== undefined ? `Files: ${context.filesProcessed}` : null,
|
||||||
context.bytesProcessed ? `Size: ${context.bytesProcessed}` : null,
|
context.bytesProcessed ? `Size: ${context.bytesProcessed}` : null,
|
||||||
|
|
@ -404,6 +405,7 @@ function buildNotificationMessage(
|
||||||
body: [
|
body: [
|
||||||
`Volume: ${context.volumeName}`,
|
`Volume: ${context.volumeName}`,
|
||||||
`Repository: ${context.repositoryName}`,
|
`Repository: ${context.repositoryName}`,
|
||||||
|
context.scheduleName ? `Schedule: ${context.scheduleName}` : null,
|
||||||
context.duration ? `Duration: ${Math.round(context.duration / 1000)}s` : null,
|
context.duration ? `Duration: ${Math.round(context.duration / 1000)}s` : null,
|
||||||
context.filesProcessed !== undefined ? `Files: ${context.filesProcessed}` : null,
|
context.filesProcessed !== undefined ? `Files: ${context.filesProcessed}` : null,
|
||||||
context.bytesProcessed ? `Size: ${context.bytesProcessed}` : null,
|
context.bytesProcessed ? `Size: ${context.bytesProcessed}` : null,
|
||||||
|
|
@ -421,6 +423,7 @@ function buildNotificationMessage(
|
||||||
body: [
|
body: [
|
||||||
`Volume: ${context.volumeName}`,
|
`Volume: ${context.volumeName}`,
|
||||||
`Repository: ${context.repositoryName}`,
|
`Repository: ${context.repositoryName}`,
|
||||||
|
context.scheduleName ? `Schedule: ${context.scheduleName}` : null,
|
||||||
context.error ? `Error: ${context.error}` : null,
|
context.error ? `Error: ${context.error}` : null,
|
||||||
`Time: ${date} - ${time}`,
|
`Time: ${date} - ${time}`,
|
||||||
]
|
]
|
||||||
|
|
@ -431,7 +434,14 @@ function buildNotificationMessage(
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
title: "Backup Notification",
|
title: "Backup Notification",
|
||||||
body: `Volume: ${context.volumeName}\nRepository: ${context.repositoryName}\nTime: ${date} - ${time}`,
|
body: [
|
||||||
|
`Volume: ${context.volumeName}`,
|
||||||
|
`Repository: ${context.repositoryName}`,
|
||||||
|
context.scheduleName ? `Schedule: ${context.scheduleName}` : null,
|
||||||
|
`Time: ${date} - ${time}`,
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join("\n"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue