fix: systeme metrics chart

This commit is contained in:
2026-03-19 09:29:28 +01:00
parent 403bc91f33
commit 6aa85ac683
26 changed files with 272 additions and 120 deletions

View File

@@ -30,27 +30,23 @@ function parseLines(output: string): string[] {
.filter(Boolean)
}
function quoteDir(pathValue: string) {
return shellQuote(pathValue)
}
async function listRemoteFiles(remoteDir: string): Promise<string[]> {
const output = await runSsh(
`cd ${quoteDir(remoteDir)} && ls -1A | sort -r | head -n ${MAX_FILES_PER_FOLDER}`
`cd ${shellQuote(remoteDir)} && ls -1A | sort -r | head -n ${MAX_FILES_PER_FOLDER}`
)
return parseLines(output)
}
async function listRemoteDirs(remoteRoot: string): Promise<string[]> {
const output = await runSsh(
`cd ${quoteDir(remoteRoot)} && for d in */; do [ -d "$d" ] && printf '%s\n' "\${d%/}"; done`
`cd ${shellQuote(remoteRoot)} && for d in */; do [ -d "$d" ] && printf '%s\n' "\${d%/}"; done`
)
return parseLines(output)
}
async function getLatestRemoteFile(remoteDir: string): Promise<string | null> {
const output = await runSsh(
`cd ${quoteDir(remoteDir)} && ls -1A | sort -r | head -n 1`
`cd ${shellQuote(remoteDir)} && ls -1A | sort -r | head -n 1`
)
const files = parseLines(output)
return files[0] || null

View File

@@ -4,10 +4,9 @@ import {
resolveFolderRemoteDir
} from "../utils/ssh.ts"
import {process} from "std-env";
import backupOptions from "../config/backup-options.json"
export const BACKUP_HOUR = process.env.BACKUPS_HOUR
export const BACKUP_HOUR = Number(process.env.BACKUPS_HOUR) || 19
type BackupTarget = {
name: string
@@ -141,7 +140,7 @@ export default defineEventHandler(async () => {
latestBackupAt: null,
backupDate: null,
expectedBackupDate: expectedDateKey,
error: error instanceof Error ? error.message : String(error)
error: "Erreur lors de la verification"
}
}
})

View File

@@ -20,7 +20,11 @@ export default defineEventHandler(async (event) => {
}
)
return messages
return (messages as any[]).map((m) => ({
id: m.id,
content: m.content,
author: { username: m.author?.username ?? "Inconnu" }
}))
} catch (error) {
console.error("Erreur Discord messages:", error)

View File

@@ -3,7 +3,8 @@ import {
shellQuote,
resolveFolderRemoteDir,
REMOTE_HOST,
isSafeFolder
isSafeFolder,
isSafeFile
} from "../utils/ssh.ts"
import { spawn } from "node:child_process"
@@ -29,6 +30,9 @@ export default defineEventHandler(async (event) => {
if (folderNames.length === 0) {
throw createError({ statusCode: 400, statusMessage: "Paramètre folders invalide" })
}
if (!REMOTE_HOST) {
throw createError({ statusCode: 503, statusMessage: "Service non configure" })
}
if (folderNames.some((folder) => !isSafeFolder(folder))) {
throw createError({ statusCode: 400, statusMessage: "Paramètre folders invalide" })
@@ -44,10 +48,7 @@ export default defineEventHandler(async (event) => {
}
const fileName = await getLatestRemoteFile(remoteDir)
if (!fileName || !isSafeFolder(fileName)) {
continue
}
if (!fileName) {
if (!fileName || !isSafeFile(fileName)) {
continue
}

View File

@@ -18,6 +18,10 @@ export default defineEventHandler(async (event) => {
const folderName = typeof folder === "string" ? folder : null
const fileName = typeof file === "string" ? file : null
if (!REMOTE_HOST) {
throw createError({ statusCode: 503, statusMessage: "Service non configure" })
}
if (!folderName || !fileName) {
throw createError({ statusCode: 400, statusMessage: "Paramètres manquants" })
}

View File

@@ -4,9 +4,11 @@ export default defineEventHandler(async (event) => {
let received = 0
for await (const chunk of req) {
if (received > MAX_UPLOAD_BYTES) throw createError({ statusCode: 413, statusMessage: "Fichier trop volumineux" })
received += chunk.length
if (received > MAX_UPLOAD_BYTES) {
event.node.res.destroy()
throw createError({statusCode: 413, statusMessage: "Fichier trop volumineux"})
}
}
return { received }
})
return {received}
})

View File

@@ -22,7 +22,7 @@ export default defineEventHandler((event) => {
return
}
const secureCookie = process.env.AUTH_COOKIE_SECURE === "true"
const secureCookie = runtimeConfig.authCookieSecure
setCookie(event, "api_auth_token", expectedToken, {
httpOnly: true,

View File

@@ -1,3 +1,5 @@
import { shellQuote } from "./ssh"
export type BackupScript = {
key: string
label: string
@@ -32,10 +34,10 @@ const getDefaultBackupScriptCommands = (): Record<string, string> => {
process.env.VAULTWARDEN_SCRIPTS_DIR || "/home/matt/vaultwarden/Malio-ops/BackupVaultWarden"
return {
"backup-bdd-recette": `cd ${recetteScriptsDir} && bash backup-bdd-recette.sh`,
"check-statut-recette": `cd ${recetteScriptsDir} && bash check-statut-recette.sh`,
"backup-bdd-recette": `cd ${shellQuote(recetteScriptsDir)} && bash backup-bdd-recette.sh`,
"check-statut-recette": `cd ${shellQuote(recetteScriptsDir)} && bash check-statut-recette.sh`,
"backup-vaultwarden":
`ssh ${vaultwardenHost} "cd ${vaultwardenScriptsDir} && bash backup-vaultwarden.sh"`
`ssh ${shellQuote(vaultwardenHost)} "cd ${shellQuote(vaultwardenScriptsDir)} && bash backup-vaultwarden.sh"`
}
}