Merge branch 'develop' into feat/add-module-lint

# Conflicts:
#	components/BackupRun.vue
#	composables/useApiAuth.ts
#	pages/index.vue
#	server/api/disk.get.ts
This commit is contained in:
2026-03-13 10:03:18 +01:00
18 changed files with 276 additions and 108 deletions

View File

@@ -1,4 +1,4 @@
import { exec } from "node:child_process"
import { execFile } from "node:child_process"
import scripts from "../config/backup-script.json"
type BackupScript = {
@@ -6,11 +6,12 @@ type BackupScript = {
label: string
downloadFolders?: string[]
command: string
args?: string[]
}
function runCommand(command: string): Promise<string> {
function runCommand(command: string, args: string[] = []): Promise<string> {
return new Promise((resolve, reject) => {
exec(command, { timeout: 10 * 60 * 1000 }, (error, stdout, stderr) => {
execFile(command, args, { timeout: 10 * 60 * 1000 }, (error, stdout, stderr) => {
if (error) {
reject(stderr || error.message)
return
@@ -40,7 +41,7 @@ export default defineEventHandler(async (event) => {
}
try {
const output = await runCommand(script.command)
const output = await runCommand(script.command, script.args || [])
return {
ok: true,
key: script.key,
@@ -49,9 +50,11 @@ export default defineEventHandler(async (event) => {
output: output.trim()
}
} catch (error) {
console.error("Erreur execution script:", error)
throw createError({
statusCode: 500,
statusMessage: `Erreur execution script: ${String(error)}`
statusMessage: "Erreur lors de l'opération"
})
}
})

View File

@@ -31,9 +31,11 @@ function isMissingPathError(error: unknown): boolean {
}
function toServerError(error: unknown) {
console.error("Erreur backups:", error)
return createError({
statusCode: 500,
statusMessage: `Erreur SSH backups: ${String(error)}`
statusMessage: "Erreur lors de l'opération"
})
}

View File

@@ -1,15 +1,31 @@
export default defineEventHandler(async () => {
const token = process.env.DISCORD_BOT_TOKEN
const channel = process.env.DISCORD_CHANNEL_ID
const token = process.env.DISCORD_BOT_TOKEN
const channel = process.env.DISCORD_CHANNEL_ID
if (!token || !channel) {
throw createError({
statusCode: 503,
statusMessage: "Service indisponible"
})
}
try {
const messages = await $fetch(
`https://discord.com/api/v10/channels/${channel}/messages?limit=20`,
{
headers: {
Authorization: `Bot ${token}`
}
`https://discord.com/api/v10/channels/${channel}/messages?limit=20`,
{
headers: {
Authorization: `Bot ${token}`
}
}
)
return messages
})
} catch (error) {
console.error("Erreur Discord messages:", error)
throw createError({
statusCode: 500,
statusMessage: "Erreur lors de l'opération"
})
}
})

View File

@@ -1,10 +1,11 @@
import { exec } from "child_process"
import { execFile } from "child_process"
import diskSources from "../config/disk-commands.json"
type DiskSource = {
key: string
label: string
command: string
args?: string[]
}
function getCommand(source: DiskSource) {
@@ -15,9 +16,9 @@ function getCommand(source: DiskSource) {
return process.env[envKey] || (legacyEnvKey ? process.env[legacyEnvKey] : undefined) || null
}
function runCommand(command: string): Promise<string> {
function runCommand(command: string, args: string[] = []): Promise<string> {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
execFile(command, args, (error, stdout, stderr) => {
if (error) {
reject(stderr || error.message)
return
@@ -45,11 +46,12 @@ export default defineEventHandler(async () => {
output
}
} catch (error) {
console.error(`Erreur disk source ${source.key}:`, error)
return {
key: source.key,
label: source.label,
ok: false,
output: `Erreur: ${String(error)}`
output: "Erreur lors de l'opération"
}
}
})

View File

@@ -7,7 +7,7 @@ const REMOTE_ROOT = process.env.BACKUPS_REMOTE_ROOT || "/home/malio-b/backups"
const FOLDER_MAP = folderMap as Record<string, string>
const isSafeFolder = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)
const isSafeFile = (value: string) => /^[^/\\]+$/.test(value)
const isSafeFile = (value: string) => /^[a-zA-Z0-9._-]+$/.test(value)
const shellQuote = (value: string) => `'${value.replace(/'/g, `'\\''`)}'`
function runSsh(command: string): Promise<string> {