diff --git a/migrations/202605061441.ts b/migrations/202605061441.ts new file mode 100644 index 0000000..1d65bb7 --- /dev/null +++ b/migrations/202605061441.ts @@ -0,0 +1,34 @@ +import { Pool } from "mariadb/*"; +import { MigrationParams } from "umzug"; + +/** + * Migration pour insérer le paramètre "maintenance" à "true" + * seulement s'il n'existe pas déjà dans la table "settings". + */ + +export async function up({ context: pool }: MigrationParams) { + const conn = await pool.getConnection(); + try { + await conn.query( + `INSERT INTO settings ( + \`key\`, + \`value\` + ) + SELECT 'maintenance', 'true' + WHERE NOT EXISTS ( + SELECT 1 FROM settings WHERE \`key\` = 'maintenance' + );`, + ); + } finally { + conn.release(); + } +} + +export async function down({ context: pool }: MigrationParams) { + const conn = await pool.getConnection(); + try { + // No-op: la migration ne doit pas supprimer une ligne potentiellement préexistante. + } finally { + conn.release(); + } +} diff --git a/src/graphql/graphqlSchema.ts b/src/graphql/graphqlSchema.ts index 69050d3..a643500 100644 --- a/src/graphql/graphqlSchema.ts +++ b/src/graphql/graphqlSchema.ts @@ -49,6 +49,12 @@ import { mediaTypes, } from "./schemas/mediaSchema"; import mediaResolver from "./resolvers/mediaResolver"; +import { + settingsMutations, + settingsQueries, + settingsTypes, +} from "./schemas/settingsSchema"; +import settingsResolver from "./resolvers/settingsResolver"; /** * Construit le schéma GraphQL en combinant les types, requêtes et mutations de tous les modules. @@ -70,6 +76,7 @@ export function getSchema() { ${coworkerInputs} ${projectTypes} ${projectInputs} + ${settingsTypes} type Query { ${accountQueries} ${categoryQueries} @@ -78,6 +85,7 @@ export function getSchema() { ${coworkerQueries} ${projectQueries} ${mediaQueries} + ${settingsQueries} } type Mutation { ${authMutations} @@ -88,6 +96,7 @@ export function getSchema() { ${coworkerMutations} ${projectMutations} ${mediaMutations} + ${settingsMutations} } `); } @@ -106,5 +115,6 @@ export function getRoot() { ...coworkerResolver, ...projectResolver, ...mediaResolver, + ...settingsResolver, }; } diff --git a/src/graphql/resolvers/settingsResolver.ts b/src/graphql/resolvers/settingsResolver.ts new file mode 100644 index 0000000..5c5db83 --- /dev/null +++ b/src/graphql/resolvers/settingsResolver.ts @@ -0,0 +1,34 @@ +import { SettingsRepository } from "../../repositories/SettingsRepository"; +import { checkAuth } from "../../utils/validationUtils"; +import jwt from "jsonwebtoken"; + +function parseBooleanSetting(value: string | null): boolean { + if (value === null) return false; + const normalized = value.trim().toLowerCase(); + return normalized === "true" || normalized === "1"; +} + +const settingsResolver = { + // Résolveur pour la requête de récupération des paramètres + settings: async ( + _args: Record, + context: { settingsRepo: SettingsRepository }, + ) => { + // Récupérer les paramètres depuis la base de données ou une source de données + const maintenanceRaw = await context.settingsRepo.get("maintenance"); + return { maintenance: parseBooleanSetting(maintenanceRaw) }; + }, + // Résolveur pour la mutation de mise à jour des paramètres + updateSettings: async ( + args: { maintenance: boolean }, + context: { user: jwt.JwtPayload | null; settingsRepo: SettingsRepository }, + ) => { + // Vérifier que l'utilisateur est authentifié et a les droits nécessaires + checkAuth(context); + // Mettre à jour les paramètres dans la base de données ou une source de données + await context.settingsRepo.set("maintenance", String(args.maintenance)); + return { maintenance: args.maintenance }; + }, +}; + +export default settingsResolver; diff --git a/src/graphql/schemas/settingsSchema.ts b/src/graphql/schemas/settingsSchema.ts new file mode 100644 index 0000000..ad9044c --- /dev/null +++ b/src/graphql/schemas/settingsSchema.ts @@ -0,0 +1,14 @@ +// Type GraphQL pour les paramètres +export const settingsTypes = ` + type Settings { + maintenance: Boolean! + } +`; + +// Requête GraphQL pour les paramètres +export const settingsQueries = `settings: Settings!`; + +// Mutations GraphQL pour les paramètres +export const settingsMutations = ` + updateSettings(maintenance: Boolean!): Settings! +`; diff --git a/src/utils/initAdmin.ts b/src/utils/initAdmin.ts index 65d8216..1ab6f04 100644 --- a/src/utils/initAdmin.ts +++ b/src/utils/initAdmin.ts @@ -39,6 +39,7 @@ export async function initAdmin( await settingsRepo.set("login", INIT_LOGIN); await settingsRepo.set("password_hash", hash); await settingsRepo.set("email", INIT_EMAIL); + await settingsRepo.set("maintenance", "true"); console.log("Initial admin credentials set."); }