import { defineStore } from 'pinia' import type { List, WPListEncrypted } from '~/types/lists' import {useCryptoStore} from '~/composables/crypto' import sodium from "libsodium-wrappers" const crypto = useCryptoStore() export const useListStore = defineStore('lists', { state: () => ({ lists: [] as List[], loading: false as boolean, masterKey: null as Uint8Array | null, publicKey: new Uint8Array() as Uint8Array, privateKey: new Uint8Array() as Uint8Array, }), actions: { saveLists(lists:Array){ this.lists = lists }, resetLists(){ this.lists = [] }, setMasterKey(key: Uint8Array){ this.masterKey = key }, async fetchLists() { // On récupère notre plugin API injecté const { $api } = useNuxtApp(); this.loading = true; try { // L'appel est maintenant ultra simple et typé const data = await $api.lists.getAll(); this.lists = data; } catch (error) { // La gestion d'erreur est centralisée, // mais tu peux ajouter une logique spécifique ici (ex: notification) console.error("Erreur lors du chargement des listes:", error); throw error; } finally { this.loading = false; } }, async processRawData(rawData: [WPListEncrypted]){ const { $api } = useNuxtApp(); await crypto.init() if (rawData && rawData.length > 0) { const item = rawData[0]; if (item && this.masterKey){ if (this.isWPListEncrypted(item)) { if (item.content_cipher === "initialize-me"){ /* 1- Création de la paire de clés (TODO : à déporter ailleurs (Key Store ?)) */ const { publicKey, privateKey } = crypto.generateUserKeyPair() this.publicKey = publicKey; this.privateKey = privateKey; // On les envoie au BO // /* Chiffrage de la private avec la master : */ const privKeyCipher = crypto.encryptPrivateKey(this.privateKey, this.masterKey) /* empaquetage */ const payload = { 'user_id': item.user_id, // pour vérification au BO 'private_key_cipher': privKeyCipher, 'public_key': publicKey, } /* Et on envoie ! */ await $api.lists.uploadKeys(JSON.stringify(payload)) // On crée la liste // /* D'abord la clé AES de la liste */ const key = crypto.generateListKey(); /* Puis la liste */ const user_id = Number(item.user_id) const data: List = { id: Number(item.id), user_id: user_id, aesKey: key, list_title: 'THE VERY première liste', list_type: 'basic', content: '{[\'vide\']}', is_open: true, created_at: Date.now(), updated_at: Date.now(), } this.lists[0] = data /* Et on envoie au BO */ this.syncData(data, this.publicKey, this.privateKey) } else{ console.log('coucou : ' + rawData); } } } } }, async syncData(decryptedData: List, userPublicKey: Uint8Array, userPrivateKey: Uint8Array) { const { $api } = useNuxtApp(); const aesKey = decryptedData.aesKey; await crypto.init(); // 1. On prépare les données (en excluant la clé elle-même du contenu) const { aesKey: _, ...pureData } = decryptedData; const stringData = JSON.stringify(pureData); // 2. Chiffrement du contenu par la clé AES (XChaCha20) const encryptedContent = crypto.encryptList(stringData, aesKey); // 3. Chiffrement de la clé AES par la clé Publique (Asymétrique) // On utilise ici ta fonction de l'étape 11 const encryptedKeyPayload = crypto.encryptListKeyForUser( aesKey, userPublicKey, userPrivateKey ); // 4. On empaquette le tout pour le Back-Office const dataToBO: WPListEncrypted = { id: decryptedData.id.toString(), user_id: decryptedData.user_id.toString(), // La clé AES verrouillée pour l'utilisateur key_cipher: sodium.to_base64(encryptedKeyPayload.cipher), key_nonce: sodium.to_base64(encryptedKeyPayload.nonce), // Le contenu de la liste content_cipher: sodium.to_base64(encryptedContent.cipher), content_nonce: sodium.to_base64(encryptedContent.nonce), created_at: null, updated_at: null, }; await $api.lists.update(dataToBO) }, // async updateList(id, title, content) { // const config = useRuntimeConfig(); // try { // const data = await $fetch<[]|null>(`${config.public.apiBase}/lists`, { // method: 'GET', // headers: { // // On injecte le token ici // 'Authorization': `Bearer ${this.token}` // }, // // Si tu as besoin d'envoyer un corps de message vide ou spécifique // // body: {} // }); // this.lists = data; // console.log(data); // console.log(this.token); // return data; // } catch (error) { // console.error("Erreur lors de la récupération des listes:", error); // } // } isWPListEncrypted(obj: any): obj is WPListEncrypted { console.log(obj !== null) console.log(typeof obj) console.log(typeof obj.id) console.log(typeof obj.key_cipher ) console.log(typeof obj.key_nonce ) console.log(typeof obj.content_cipher) console.log(typeof obj.content_nonce) return ( obj !== null && typeof obj === 'object' && typeof obj.id === 'string' && typeof obj.key_cipher === 'string' && typeof obj.key_nonce === 'string' && typeof obj.content_cipher === 'string' && typeof obj.content_nonce === 'string' ); } } })