portail-associations/server/salleSignatureDelegation.ts

102 lines
3.6 KiB
TypeScript

import * as db from "./db";
const SALLE_SIGNATURE_DELEGATION_SETTING_KEY = "system.salle_signature.delegations";
type DirectriceDelegationEntry = {
delegateUserIds: number[];
};
type SalleSignatureDelegationSettings = {
directriceDelegations: Record<string, DirectriceDelegationEntry>;
};
function sanitizeUserIds(values: unknown): number[] {
if (!Array.isArray(values)) return [];
return Array.from(
new Set(
values
.map((value) => Number(value))
.filter((value) => Number.isInteger(value) && value > 0)
)
);
}
function sanitizeSettings(value: unknown): SalleSignatureDelegationSettings {
if (!value || typeof value !== "object") {
return { directriceDelegations: {} };
}
const record = (value as { directriceDelegations?: unknown }).directriceDelegations;
if (!record || typeof record !== "object") {
return { directriceDelegations: {} };
}
const entries = Object.entries(record as Record<string, unknown>).reduce<Record<string, DirectriceDelegationEntry>>(
(acc, [directriceId, entry]) => {
const userId = Number(directriceId);
if (!Number.isInteger(userId) || userId <= 0) return acc;
const delegateUserIds = sanitizeUserIds((entry as { delegateUserIds?: unknown })?.delegateUserIds);
acc[String(userId)] = { delegateUserIds };
return acc;
},
{}
);
return { directriceDelegations: entries };
}
export async function getSalleSignatureDelegationSettings(): Promise<SalleSignatureDelegationSettings> {
const raw = await db.getPortalSetting(SALLE_SIGNATURE_DELEGATION_SETTING_KEY);
if (!raw) {
return { directriceDelegations: {} };
}
try {
return sanitizeSettings(JSON.parse(raw));
} catch {
return { directriceDelegations: {} };
}
}
export async function saveSalleSignatureDelegationSettings(settings: SalleSignatureDelegationSettings) {
await db.setPortalSetting(
SALLE_SIGNATURE_DELEGATION_SETTING_KEY,
JSON.stringify(sanitizeSettings(settings)),
"Délégations de signature des demandes de salle"
);
}
export async function getDelegatedSignerIdsForDirectrice(directriceUserId: number) {
const settings = await getSalleSignatureDelegationSettings();
return settings.directriceDelegations[String(directriceUserId)]?.delegateUserIds || [];
}
export async function setDelegatedSignerIdsForDirectrice(directriceUserId: number, delegateUserIds: number[]) {
const settings = await getSalleSignatureDelegationSettings();
settings.directriceDelegations[String(directriceUserId)] = {
delegateUserIds: sanitizeUserIds(delegateUserIds),
};
await saveSalleSignatureDelegationSettings(settings);
}
export async function addDelegatedSignerForDirectrice(directriceUserId: number, delegateUserId: number) {
const current = await getDelegatedSignerIdsForDirectrice(directriceUserId);
const next = Array.from(new Set([...current, delegateUserId]));
await setDelegatedSignerIdsForDirectrice(directriceUserId, next);
return next;
}
export async function removeDelegatedSignerForDirectrice(directriceUserId: number, delegateUserId: number) {
const current = await getDelegatedSignerIdsForDirectrice(directriceUserId);
const next = current.filter((entry) => entry !== delegateUserId);
await setDelegatedSignerIdsForDirectrice(directriceUserId, next);
return next;
}
export async function getDirectriceIdsDelegatingToUser(userId: number) {
const settings = await getSalleSignatureDelegationSettings();
return Object.entries(settings.directriceDelegations)
.filter(([, entry]) => sanitizeUserIds(entry.delegateUserIds).includes(userId))
.map(([directriceId]) => Number(directriceId))
.filter((value) => Number.isInteger(value) && value > 0);
}