Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / drive / src / app / store / _links / useLinksKeys.tsx
blobf625b6b4d2e0fcc2debf189fbab70fb53b36f5a3
1 import { createContext, useContext } from 'react';
3 import type { PrivateKeyReference, SessionKey } from '@proton/crypto';
5 type LinksKeysByShare = {
6     [shareId: string]: {
7         [linkId: string]: LinkKeys;
8     };
9 };
11 type LinkKeys = FileLinkKeys & FolderLinkKeys;
13 type FileLinkKeys = {
14     passphrase?: string;
15     passphraseSessionKey?: SessionKey;
16     privateKey?: PrivateKeyReference;
17     sessionKey?: SessionKey;
20 type FolderLinkKeys = {
21     passphrase?: string;
22     passphraseSessionKey?: SessionKey;
23     privateKey?: PrivateKeyReference;
24     hashKey?: Uint8Array;
27 /**
28  * LinksKeys provides a simple storage to cache link keys.
29  * Ideally, there should be only one instance in the whole app.
30  */
31 export class LinksKeys {
32     private keys: LinksKeysByShare;
34     constructor() {
35         this.keys = {};
36     }
38     getPassphrase(shareId: string, linkId: string): string | undefined {
39         return this.keys[shareId]?.[linkId]?.passphrase;
40     }
42     getPassphraseSessionKey(shareId: string, linkId: string): SessionKey | undefined {
43         return this.keys[shareId]?.[linkId]?.passphraseSessionKey;
44     }
46     getPrivateKey(shareId: string, linkId: string): PrivateKeyReference | undefined {
47         return this.keys[shareId]?.[linkId]?.privateKey;
48     }
50     getSessionKey(shareId: string, linkId: string): SessionKey | undefined {
51         return this.keys[shareId]?.[linkId]?.sessionKey;
52     }
54     getHashKey(shareId: string, linkId: string): Uint8Array | undefined {
55         return this.keys[shareId]?.[linkId]?.hashKey;
56     }
58     setPassphrase(shareId: string, linkId: string, passphrase: string) {
59         this.setKey(shareId, linkId, (keys: LinkKeys) => {
60             keys.passphrase = passphrase;
61         });
62     }
64     setPassphraseSessionKey(shareId: string, linkId: string, sessionKey: SessionKey) {
65         this.setKey(shareId, linkId, (keys: LinkKeys) => {
66             keys.passphraseSessionKey = sessionKey;
67         });
68     }
70     setPrivateKey(shareId: string, linkId: string, privateKey: PrivateKeyReference) {
71         this.setKey(shareId, linkId, (keys: LinkKeys) => {
72             keys.privateKey = privateKey;
73         });
74     }
76     setSessionKey(shareId: string, linkId: string, sessionKey: SessionKey) {
77         this.setKey(shareId, linkId, (keys: LinkKeys) => {
78             keys.sessionKey = sessionKey;
79         });
80     }
82     setHashKey(shareId: string, linkId: string, hashKey: Uint8Array) {
83         this.setKey(shareId, linkId, (keys: LinkKeys) => {
84             keys.hashKey = hashKey;
85         });
86     }
88     private setKey(shareId: string, linkId: string, setter: (keys: LinkKeys) => void) {
89         if (!this.keys[shareId]) {
90             this.keys[shareId] = {};
91         }
92         if (!this.keys[shareId][linkId]) {
93             this.keys[shareId][linkId] = {};
94         }
95         setter(this.keys[shareId][linkId]);
96     }
99 const LinksKeysContext = createContext<LinksKeys | null>(null);
101 export function LinksKeysProvider({ children }: { children: React.ReactNode }) {
102     const value = new LinksKeys();
103     return <LinksKeysContext.Provider value={value}>{children}</LinksKeysContext.Provider>;
106 export default function useLinksKeys() {
107     const state = useContext(LinksKeysContext);
108     if (!state) {
109         throw new Error('Trying to use uninitialized LinksKeysProvider');
110     }
111     return state;