Skip to content

Commit

Permalink
Replace updatePrivateDataCache with CommitCallback
Browse files Browse the repository at this point in the history
  • Loading branch information
emlun committed Sep 22, 2023
1 parent 35e2ac2 commit e0138de
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
8 changes: 4 additions & 4 deletions src/pages/AccountSettings/AccountSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const WebauthnRegistation = ({
if (beginData && pendingCredential && existingPrfKey && wrappedMainKey) {
setIsSubmitting(true);

const newPrivateData = await keystore.addPrf(
const [newPrivateData, keystoreCommit] = await keystore.addPrf(
pendingCredential,
beginData.createOptions.publicKey.rp.id,
existingPrfKey,
Expand All @@ -98,7 +98,7 @@ const WebauthnRegistation = ({
});
onSuccess();
setNickname("");
keystore.updatePrivateDataCache(newPrivateData);
await keystoreCommit();

} catch (e) {
console.error("Failed to finish registration", e);
Expand Down Expand Up @@ -322,12 +322,12 @@ const Home = () => {
);

const deleteWebauthnCredential = async (credential: WebauthnCredential) => {
const newPrivateData = keystore.deletePrf(credential.credentialId);
const [newPrivateData, keystoreCommit] = keystore.deletePrf(credential.credentialId);
const deleteResp = await api.post(`/user/session/webauthn/credential/${credential.id}/delete`, {
privateData: jsonStringifyTaggedBinary(newPrivateData),
});
if (deleteResp.status === 204) {
keystore.updatePrivateDataCache(newPrivateData);
await keystoreCommit();
} else {
console.error("Failed to delete WebAuthn credential", deleteResp.status, deleteResp);
}
Expand Down
28 changes: 17 additions & 11 deletions src/services/LocalStorageKeystore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ async function getPrfOutput(
}


export type CommitCallback = () => Promise<void>;
export interface LocalStorageKeystore {
close(): Promise<void>,
updatePrivateDataCache(privateData: EncryptedContainer): void,

initPassword(password: string): Promise<{ publicData: PublicData, privateData: EncryptedContainer }>,
initPrf(
Expand All @@ -272,8 +272,8 @@ export interface LocalStorageKeystore {
rpId: string,
existingPrfKey: CryptoKey,
wrappedMainKey: WrappedKeyInfo,
): Promise<EncryptedContainer>,
deletePrf(credentialId: Uint8Array): EncryptedContainer,
): Promise<[EncryptedContainer, CommitCallback]>,
deletePrf(credentialId: Uint8Array): [EncryptedContainer, CommitCallback],
unlockPassword(privateData: EncryptedContainer, password: string, keyInfo: PasswordKeyInfo): Promise<void>,
unlockPrf(privateData: EncryptedContainer, credential: PublicKeyCredential, rpId: string): Promise<void>,
getPrfKeyFromSession(): Promise<[CryptoKey, WebauthnPrfEncryptionKeyInfo]>,
Expand Down Expand Up @@ -495,10 +495,6 @@ export function useLocalStorageKeystore(): LocalStorageKeystore {
clearSessionStorage();
},

updatePrivateDataCache: (privateData: EncryptedContainer): void => {
setPrivateDataCache(privateData);
},

initPassword: async (password: string): Promise<{ publicData: PublicData, privateData: EncryptedContainer }> => {
console.log("initPassword");

Expand Down Expand Up @@ -532,7 +528,7 @@ export function useLocalStorageKeystore(): LocalStorageKeystore {
rpId: string,
existingPrfKey: CryptoKey,
wrappedMainKey: WrappedKeyInfo,
): Promise<EncryptedContainer> => {
): Promise<[EncryptedContainer, CommitCallback]> => {
const prfSalt = crypto.getRandomValues(new Uint8Array(32))
const [, keyInfo] = await createPrfKey(credential, prfSalt, rpId, wrappedMainKey, existingPrfKey);
const newPrivateData = {
Expand All @@ -542,17 +538,27 @@ export function useLocalStorageKeystore(): LocalStorageKeystore {
keyInfo,
],
};
return newPrivateData;
return [
newPrivateData,
async () => {
setPrivateDataCache(newPrivateData);
},
];
},

deletePrf: (credentialId: Uint8Array): EncryptedContainer => {
deletePrf: (credentialId: Uint8Array): [EncryptedContainer, CommitCallback] => {
const newPrivateData = {
...privateDataCache,
prfKeys: privateDataCache.prfKeys.filter((keyInfo) => (
toBase64Url(keyInfo.credentialId) !== toBase64Url(credentialId)
)),
};
return newPrivateData;
return [
newPrivateData,
async () => {
setPrivateDataCache(newPrivateData);
},
];
},

unlockPassword,
Expand Down

0 comments on commit e0138de

Please sign in to comment.