diff --git a/src/interfaces.ts b/src/interfaces.ts index 2a77d3af..e0db789f 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -136,6 +136,7 @@ export interface Web3AuthState { tssShareIndex?: number; tssPubKey?: Buffer; factorKey?: BN; + isMFAEnabled?: boolean; } export interface ICoreKit { @@ -382,6 +383,7 @@ export interface SessionData { tssPubKey: string; signatures: string[]; userInfo: UserInfo; + isMFAEnabled: boolean; } export interface TkeyLocalStoreData { diff --git a/src/mpcCoreKit.ts b/src/mpcCoreKit.ts index 90956ee0..0bddf29c 100644 --- a/src/mpcCoreKit.ts +++ b/src/mpcCoreKit.ts @@ -445,6 +445,11 @@ export class Web3AuthMPCCoreKit implements ICoreKit { return this.tKey.getTSSPub(); } + public isMFAEnabled(): boolean { + this.checkReady(); + return !!this.state.isMFAEnabled; + } + public async enableMFA(enableMFAParams: EnableMFAParams, recoveryFactor = true): Promise { this.checkReady(); @@ -481,6 +486,8 @@ export class Web3AuthMPCCoreKit implements ICoreKit { await this.deleteFactor(hashedFactorPub, hashedFactorKey); await this.deleteMetadataShareBackup(hashedFactorKey); + this.updateState({ isMFAEnabled: true }); + // only recovery factor = true if (recoveryFactor) { const backupFactorKey = await this.createFactor({ shareType: TssShareType.RECOVERY, ...enableMFAParams }); @@ -769,6 +776,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit { if (!this.state.oAuthKey) { throw new Error("user not logged in"); } + this.updateState({ isMFAEnabled: false }); const existingUser = await this.isMetadataPresent(this.state.oAuthKey); if (!existingUser) { @@ -807,6 +815,8 @@ export class Web3AuthMPCCoreKit implements ICoreKit { await this.tKey.inputShareStoreSafe(factorKeyMetadata, true); await this.tKey.reconstructKey(); await this.finalizeTkey(hashedFactorKey); + } else { + this.updateState({ isMFAEnabled: true }); } } } @@ -849,14 +859,18 @@ export class Web3AuthMPCCoreKit implements ICoreKit { await this.tKey.inputShareStoreSafe(factorKeyMetadata, true); await this.tKey.reconstructKey(); - this.updateState({ - factorKey: new BN(result.factorKey, "hex"), - oAuthKey: result.oAuthKey, - tssShareIndex: result.tssShareIndex, - tssPubKey: Buffer.from(result.tssPubKey.padStart(FIELD_ELEMENT_HEX_LEN, "0"), "hex"), - signatures: result.signatures, - userInfo: result.userInfo, - }); + this.updateState( + { + factorKey: new BN(result.factorKey, "hex"), + oAuthKey: result.oAuthKey, + tssShareIndex: result.tssShareIndex, + tssPubKey: Buffer.from(result.tssPubKey.padStart(FIELD_ELEMENT_HEX_LEN, "0"), "hex"), + signatures: result.signatures, + userInfo: result.userInfo, + isMFAEnabled: result.isMFAEnabled, + }, + false + ); } catch (err) { log.error("error trying to authorize session", err); } @@ -866,20 +880,14 @@ export class Web3AuthMPCCoreKit implements ICoreKit { try { const sessionId = OpenloginSessionManager.generateRandomSessionKey(); this.sessionManager.sessionId = sessionId; - const { oAuthKey, factorKey, userInfo, tssShareIndex, tssPubKey } = this.state; + const { oAuthKey, factorKey, userInfo, tssPubKey } = this.state; if (!this.state.factorKey) throw new Error("factorKey not present"); const { tssShare } = await this.tKey.getTSSShare(this.state.factorKey); if (!oAuthKey || !factorKey || !tssShare || !tssPubKey || !userInfo) { throw new Error("User not logged in"); } - const payload: SessionData = { - oAuthKey, - factorKey: factorKey?.toString("hex"), - tssShareIndex: tssShareIndex as number, - tssPubKey: Buffer.from(tssPubKey).toString("hex"), - signatures: this.signatures, - userInfo, - }; + const payload: SessionData = this.createSessionData(); + await this.sessionManager.createSession(payload); this.currentStorage.set("sessionId", sessionId); } catch (err) { @@ -887,6 +895,20 @@ export class Web3AuthMPCCoreKit implements ICoreKit { } } + private createSessionData(): SessionData { + const { oAuthKey, factorKey, userInfo, tssShareIndex, tssPubKey, isMFAEnabled } = this.state; + const payload: SessionData = { + oAuthKey, + factorKey: factorKey?.toString("hex"), + tssShareIndex: tssShareIndex as number, + tssPubKey: Buffer.from(tssPubKey).toString("hex"), + signatures: this.signatures, + userInfo, + isMFAEnabled, + }; + return payload; + } + private async isMetadataPresent(privateKey: string) { const privateKeyBN = new BN(privateKey, "hex"); const metadata = await this.tKey?.storageLayer.getMetadata<{ message: string }>({ privKey: privateKeyBN }); @@ -945,11 +967,6 @@ export class Web3AuthMPCCoreKit implements ICoreKit { // Generate new share. await addFactorAndRefresh(this.tKey, newFactorPub, newFactorTSSIndex, this.state.factorKey, this.signatures); - // Update local share. - const { tssIndex } = await this.tKey.getTSSShare(this.state.factorKey); - this.updateState({ - tssShareIndex: tssIndex, - }); return; } @@ -1032,8 +1049,12 @@ export class Web3AuthMPCCoreKit implements ICoreKit { this.privKeyProvider = signingProvider; } - private updateState(newState: Partial): void { + private updateState(newState: Partial, updateSession = true): void { this.state = { ...this.state, ...newState }; + if (this.sessionManager.sessionId && updateSession) { + const payload: SessionData = this.createSessionData(); + this.sessionManager.updateSession(payload); + } } private resetState(): void {