/** * Gestionnaire de nonce unifié pour le frontend * Assure la cohérence avec le système backend NonceManager */ /** * Configuration du nonce côté client */ interface NonceConfig { nonce: string; action: string; ajaxUrl: string; timestamp: number; } /** * Réponse de nonce du serveur */ interface NonceResponse { success: boolean; data?: { nonce?: string; message?: string; code?: string; }; } import { getPdfBuilderData, updatePdfBuilderData, } from "./editorFeatures"; /** * Gestionnaire de nonce client */ export class ClientNonceManager { /** * Action nonce unifié - doit correspondre au backend */ static readonly NONCE_ACTION = "pdfib_ajax"; /** * Clé pour stocker le nonce */ static readonly STORAGE_KEY = "pdfBuilderNonce"; /** * TTL du nonce en secondes (12 heures) */ static readonly NONCE_TTL = 43200; /** * Obtenir le nonce actuel depuis la fenêtre globale */ static getCurrentNonce(): string | null { const nonce = window.pdfBuilderAjax?.nonce || getPdfBuilderData().nonce || window.pdfBuilderNonce || null; return nonce; } /** * Obtenir l'URL AJAX */ static getAjaxUrl(): string { const url = window.pdfBuilderAjax?.ajax_url || window.pdfBuilderAjax?.url || getPdfBuilderData().ajaxUrl || window.ajaxurl || "/wp-admin/admin-ajax.php"; return url; } /** * Mettre à jour le nonce globalement */ static setNonce(nonce: string): void { if (window.pdfBuilderAjax) { window.pdfBuilderAjax.nonce = nonce; } updatePdfBuilderData((editorData) => { editorData.nonce = nonce; }); if (window.pdfBuilderReactData) { window.pdfBuilderReactData.nonce = nonce; } window.pdfBuilderNonce = nonce; sessionStorage.setItem(this.STORAGE_KEY, nonce); } /** * Obtenir un nonce frais du serveur */ static async refreshNonce(currentNonce?: string): Promise { const formData = new FormData(); formData.append("action", "pdfib_get_fresh_nonce"); if (currentNonce) { formData.append("nonce", currentNonce); } try { const response = await fetch(this.getAjaxUrl(), { method: "POST", body: formData, }); if (!response.ok) { return null; } const result: NonceResponse = await response.json(); if (result.success && result.data?.nonce) { const freshNonce = result.data.nonce; this.setNonce(freshNonce); return freshNonce; } else { return null; } } catch (error) { return null; } } /** * Ajouter le nonce à un FormData */ static addToFormData(formData: FormData, nonce?: string): FormData { const nonceToUse = nonce || this.getCurrentNonce(); if (nonceToUse) { formData.append("nonce", nonceToUse); } return formData; } /** * Ajouter le nonce à une URL (GET) */ static addToUrl(url: string, nonce?: string): string { const nonceToUse = nonce || this.getCurrentNonce(); if (!nonceToUse) { return url; } const separator = url.includes("?") ? "&" : "?"; return `${url}${separator}nonce=${encodeURIComponent(nonceToUse)}`; } /** * Obtenir la configuration actuelle du nonce */ static getConfig(): NonceConfig | null { const nonce = this.getCurrentNonce(); if (!nonce) { return null; } return { nonce, action: this.NONCE_ACTION, ajaxUrl: this.getAjaxUrl(), timestamp: Math.floor(Date.now() / 1000), }; } /** * Vérifier si le nonce est valide */ static isValid(): boolean { const nonce = this.getCurrentNonce(); return nonce !== null && nonce.length > 0; } /** * Logger une information */ static log(_message: string): void { // logging suppressed in production } /** * Logger une erreur */ static logError(_message: string): void { // logging suppressed in production } } export default ClientNonceManager;