1 import { createContext, useContext } from 'react';
3 import type { PrivateKeyReference, SessionKey } from '@proton/crypto';
5 type LinksKeysByShare = {
7 [linkId: string]: LinkKeys;
11 type LinkKeys = FileLinkKeys & FolderLinkKeys;
15 passphraseSessionKey?: SessionKey;
16 privateKey?: PrivateKeyReference;
17 sessionKey?: SessionKey;
20 type FolderLinkKeys = {
22 passphraseSessionKey?: SessionKey;
23 privateKey?: PrivateKeyReference;
28 * LinksKeys provides a simple storage to cache link keys.
29 * Ideally, there should be only one instance in the whole app.
31 export class LinksKeys {
32 private keys: LinksKeysByShare;
38 getPassphrase(shareId: string, linkId: string): string | undefined {
39 return this.keys[shareId]?.[linkId]?.passphrase;
42 getPassphraseSessionKey(shareId: string, linkId: string): SessionKey | undefined {
43 return this.keys[shareId]?.[linkId]?.passphraseSessionKey;
46 getPrivateKey(shareId: string, linkId: string): PrivateKeyReference | undefined {
47 return this.keys[shareId]?.[linkId]?.privateKey;
50 getSessionKey(shareId: string, linkId: string): SessionKey | undefined {
51 return this.keys[shareId]?.[linkId]?.sessionKey;
54 getHashKey(shareId: string, linkId: string): Uint8Array | undefined {
55 return this.keys[shareId]?.[linkId]?.hashKey;
58 setPassphrase(shareId: string, linkId: string, passphrase: string) {
59 this.setKey(shareId, linkId, (keys: LinkKeys) => {
60 keys.passphrase = passphrase;
64 setPassphraseSessionKey(shareId: string, linkId: string, sessionKey: SessionKey) {
65 this.setKey(shareId, linkId, (keys: LinkKeys) => {
66 keys.passphraseSessionKey = sessionKey;
70 setPrivateKey(shareId: string, linkId: string, privateKey: PrivateKeyReference) {
71 this.setKey(shareId, linkId, (keys: LinkKeys) => {
72 keys.privateKey = privateKey;
76 setSessionKey(shareId: string, linkId: string, sessionKey: SessionKey) {
77 this.setKey(shareId, linkId, (keys: LinkKeys) => {
78 keys.sessionKey = sessionKey;
82 setHashKey(shareId: string, linkId: string, hashKey: Uint8Array) {
83 this.setKey(shareId, linkId, (keys: LinkKeys) => {
84 keys.hashKey = hashKey;
88 private setKey(shareId: string, linkId: string, setter: (keys: LinkKeys) => void) {
89 if (!this.keys[shareId]) {
90 this.keys[shareId] = {};
92 if (!this.keys[shareId][linkId]) {
93 this.keys[shareId][linkId] = {};
95 setter(this.keys[shareId][linkId]);
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);
109 throw new Error('Trying to use uninitialized LinksKeysProvider');