Skip to content

Commit

Permalink
Merge pull request #89 from Web3Auth/feat/variable-session-time
Browse files Browse the repository at this point in the history
enable variable session time for mpcCoreKit
  • Loading branch information
himanshuchawla009 authored Apr 9, 2024
2 parents 6066484 + 1e9fb83 commit 99e0553
Show file tree
Hide file tree
Showing 9 changed files with 3,580 additions and 2,111 deletions.
6 changes: 3 additions & 3 deletions demo/redirect-flow-example/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion demo/redirect-flow-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@types/node": "^16.18.48",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@web3auth/mpc-core-kit": "file://../../",
"@web3auth/mpc-core-kit": "file:../..",
"browserify-zlib": "^0.2.0",
"copy-webpack-plugin": "^11.0.0",
"html-webpack-plugin": "^5.5.3",
Expand Down
3 changes: 2 additions & 1 deletion demo/redirect-flow-example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const coreKitInstance = new Web3AuthMPCCoreKit(
web3AuthNetwork: selectedNetwork,
uxMode: 'redirect',
manualSync: true,
setupProviderOnInit: false
setupProviderOnInit: false,
// sessionTime: 3600, // <== can provide variable session time based on user subscribed plan
}
);

Expand Down
5,526 changes: 3,450 additions & 2,076 deletions package-lock.json

Large diffs are not rendered by default.

50 changes: 26 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,64 +42,66 @@
"@tkey-mpc/share-serialization": "^9.1.0",
"@tkey-mpc/storage-layer-torus": "^9.1.0",
"@toruslabs/constants": "^13.0.1",
"@toruslabs/customauth": "^16.0.6",
"@toruslabs/customauth": "^18.1.0",
"@toruslabs/eccrypto": "4.0.0",
"@toruslabs/fetch-node-details": "^13.0.1",
"@toruslabs/fetch-node-details": "^13.1.1",
"@toruslabs/fnd-base": "^13.1.1",
"@toruslabs/metadata-helpers": "^5.x",
"@toruslabs/openlogin-session-manager": "^3.0.0",
"@toruslabs/openlogin-utils": "^8.0.0",
"@toruslabs/torus.js": "^12.1.0",
"@toruslabs/torus.js": "12.2.0",
"@toruslabs/tss-client": "^2.1.0",
"@toruslabs/tss-lib": "^2.0.0",
"@web3auth-mpc/ethereum-provider": "^2.3.0",
"@web3auth/base": "^7.0.1",
"@web3auth/base-provider": "^7.0.1",
"@web3auth-mpc/ethereum-provider": "^3.1.0",
"@web3auth/base": "^7.3.1",
"@web3auth/base-provider": "^7.3.1",
"bn.js": "^5.2.1",
"bowser": "^2.11.0",
"elliptic": "^6.5.4"
},
"devDependencies": {
"@babel/register": "^7.22.15",
"@babel/register": "^7.23.7",
"@toruslabs/config": "^2.0.2",
"@toruslabs/eslint-config-typescript": "^3.0.1",
"@toruslabs/torus-scripts": "^5.0.5",
"@toruslabs/eslint-config-typescript": "^3.1.0",
"@toruslabs/torus-scripts": "^5.2.0",
"@toruslabs/tss-lib-node": "^1.1.3",
"@types/chai": "^4.3.6",
"@types/elliptic": "^6.4.14",
"@types/chai": "^4.3.11",
"@types/elliptic": "^6.4.18",
"@types/jsonwebtoken": "^9.0.5",
"@types/node": "^20.6.3",
"@typescript-eslint/eslint-plugin": "^6.7.0",
"chai": "^4.3.8",
"@types/node": "^20.11.16",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"chai": "^5.0.3",
"cross-env": "^7.0.3",
"dotenv": "^16.3.1",
"dotenv": "^16.4.1",
"esbuild-register": "^3.5.0",
"eslint": "^8.49.0",
"husky": "^8.0.3",
"eslint": "^8.56.0",
"husky": "^9.0.10",
"jsonwebtoken": "^9.0.2",
"lint-staged": "^14.0.1",
"lint-staged": "^15.2.1",
"mocha": "^10.2.0",
"node-fetch": "^3.3.2",
"prettier": "^3.0.3",
"rimraf": "^5.0.1",
"ts-node": "^10.9.1",
"prettier": "^3.2.4",
"rimraf": "^5.0.5",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"tslib": "^2.6.2",
"typescript": "^5.2.2"
"typescript": "^5.3.3"
},
"engines": {
"node": ">=20.x"
},
"overrides": {
"@toruslabs/customauth": "^18.1.0",
"@tkey-mpc/storage-layer-torus": {
"@toruslabs/http-helpers": "^6.0.0"
},
"@toruslabs/base-session-manager": {
"@toruslabs/http-helpers": "^6.0.0"
},
"@toruslabs/customauth": {
"@toruslabs/http-helpers": "^6.0.0"
"@tkey-mpc/service-provider-torus": {
"@toruslabs/torus.js": "^12.2.0",
"@toruslabs/customauth": "^18.1.0"
}
},
"lint-staged": {
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ export interface Web3AuthOptions {
* Setup Provider after `login success` reconstruct.
*/
setupProviderOnInit?: boolean;

serverTimeOffset?: number;
}

export type Web3AuthOptionsWithDefaults = Required<Web3AuthOptions>;
Expand Down
13 changes: 8 additions & 5 deletions src/mpcCoreKit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
if (typeof options.manualSync !== "boolean") options.manualSync = false;
if (!options.web3AuthNetwork) options.web3AuthNetwork = WEB3AUTH_NETWORK.MAINNET;
if (!options.sessionTime) options.sessionTime = 86400;
if (!options.serverTimeOffset) options.serverTimeOffset = 0;
if (!options.uxMode) options.uxMode = UX_MODE.REDIRECT;
if (!options.redirectPathName) options.redirectPathName = "redirect";
if (!options.baseUrl) options.baseUrl = isNodejsOrRN ? "https://localhost" : `${window?.location.origin}/serviceworker`;
Expand Down Expand Up @@ -262,6 +263,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
network: this.options.web3AuthNetwork,
redirectPathName: this.options.redirectPathName,
locationReplaceOnRedirect: true,
serverTimeOffset: this.options.serverTimeOffset,
},
nodeEndpoints: nodeDetails.torusNodeEndpoints,
nodePubKeys: nodeDetails.torusNodePub.map((i) => ({ x: i.X, y: i.Y })),
Expand Down Expand Up @@ -304,7 +306,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
} else if (params.rehydrate && this.sessionManager.sessionId) {
// swallowed, should not throw on rehydrate timed out session
const sessionResult = await this.sessionManager.authorizeSession().catch(async (err) => {
log.info("rehydrate session error", err);
log.error("rehydrate session error", err);
});

// try rehydrate session
Expand All @@ -313,10 +315,12 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
} else {
// feature gating on no session rehydration
await this.featureRequest();
TorusUtils.setSessionTime(this.options.sessionTime);
}
} else {
// feature gating if not redirect flow or session rehydration
await this.featureRequest();
TorusUtils.setSessionTime(this.options.sessionTime);
}

// if not redirect flow or session rehydration, ask for factor key to login
Expand Down Expand Up @@ -712,7 +716,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
throw new Error(`sessionAuth does not exist ${currentSession}`);
}

const signatures = await this.getSigningSignatures(msgHash.toString("hex"));
const signatures = await this.getSigningSignatures();
if (!signatures) {
throw new Error(`Signature does not exist ${signatures}`);
}
Expand Down Expand Up @@ -1032,7 +1036,6 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
if (!factorKeyMetadata || factorKeyMetadata.message === "KEY_NOT_FOUND" || factorKeyMetadata.message === "SHARE_DELETED") {
return false;
}
log.info("factorKeyMetadata", factorKeyMetadata);
return true;
}

Expand Down Expand Up @@ -1192,9 +1195,8 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
return sessionData.map((session) => JSON.stringify({ data: session.token, sig: session.signature }));
}

private async getSigningSignatures(data: string): Promise<string[]> {
private async getSigningSignatures(): Promise<string[]> {
if (!this.signatures) throw new Error("signatures not present");
log.info("data", data);
return this.signatures;
}

Expand All @@ -1211,6 +1213,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
client_id: this.options.web3AuthClientId,
is_mpc_core_kit: "true",
enable_gating: "true",
session_time: this.options.sessionTime.toString(),
};
const url = new URL(`${accessUrl}/api/feature-access`);
url.search = new URLSearchParams(accessRequest).toString();
Expand Down
2 changes: 1 addition & 1 deletion tests/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type TestVariable = {
email: string;
};

const defaultTestEmail = "testEmail1";
const defaultTestEmail = "testEmailForLogin";
const variable: TestVariable[] = [
{ web3AuthNetwork: WEB3AUTH_NETWORK.DEVNET, uxMode: "nodejs", email: defaultTestEmail },
// { web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET, uxMode: UX_MODE.REDIRECT, email: defaultTestEmail },
Expand Down
87 changes: 87 additions & 0 deletions tests/sessionTime.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* eslint-disable mocha/handle-done-callback */
import assert from "node:assert";
import test from "node:test";

import { UX_MODE_TYPE } from "@toruslabs/customauth";
import * as TssLib from "@toruslabs/tss-lib-node";

import { COREKIT_STATUS, WEB3AUTH_NETWORK, WEB3AUTH_NETWORK_TYPE, Web3AuthMPCCoreKit } from "../src";
import { criticalResetAccount, mockLogin } from "./setup";

type TestVariable = {
web3AuthNetwork: WEB3AUTH_NETWORK_TYPE;
web3ClientID: string;
uxMode: UX_MODE_TYPE | "nodejs";
manualSync?: boolean;
email: string;
gated?: boolean;
sessionTime?: number;
};

const defaultTestEmail = "testEmail1";
const variable: TestVariable[] = [
{ web3AuthNetwork: WEB3AUTH_NETWORK.DEVNET, uxMode: "nodejs", email: defaultTestEmail, web3ClientID: "torus-key-test", sessionTime: 3600 },
{
web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET,
uxMode: "nodejs",
email: defaultTestEmail,
web3ClientID: "BJ57yveG_XBLqZUpjtJCnJMrord0AaXpd_9OSy4HzkxpnpPn6Co73h-vR6GEI1VogtW4yMHq13GNPKmVpliFXY0",
sessionTime: 7200,
},
{
web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET,
uxMode: "nodejs",
email: defaultTestEmail,
web3ClientID: "BCriFlI9ihm81N-bc7x6N-xbqwBLuxfRDMmSH87spKH27QTNOPj1W9s2K3-mp9NzXuaRiqxvAGHyuGlXG5wLD1g",
sessionTime: 172800,
},
];

variable.forEach((testVariable) => {
const { web3AuthNetwork, uxMode, manualSync, email, web3ClientID: web3AuthClientId, sessionTime } = variable[0];
const coreKitInstance = new Web3AuthMPCCoreKit({
web3AuthClientId,
web3AuthNetwork,
baseUrl: "http://localhost:3000",
uxMode,
tssLib: TssLib,
storageKey: "memory",
manualSync,
sessionTime,
});

test(`#Variable SessionTime test : ${JSON.stringify({ sessionTime: testVariable.sessionTime })}`, async (t) => {
t.before(async function () {
if (coreKitInstance.status === COREKIT_STATUS.INITIALIZED) await criticalResetAccount(coreKitInstance);
});

t.after(async function () {
// after all test tear down
await coreKitInstance.logout();
});

await t.test("`sessionTime` should be equal to `sessionTokenDuration` from #Login", async function () {
// mocklogin
const { idToken, parsedToken } = await mockLogin(email);

await coreKitInstance.init({ handleRedirectResult: false });

await coreKitInstance.loginWithJWT({
verifier: "torus-test-health",
verifierId: parsedToken.email,
idToken,
});

coreKitInstance.signatures.forEach((sig) => {
const parsedSig = JSON.parse(sig);
const parsedSigData = JSON.parse(atob(parsedSig.data));

const sessionTokenDuration = parsedSigData.exp - Math.floor(Date.now() / 1000);
// in success case, sessionTimeDiff (diff between provided sessionTime and generated session token duration from sss-service)
// should not be more than 3s(supposed 3s as the network latency)
const sessionTimeDiff = Math.abs(sessionTokenDuration - sessionTime);
assert.strictEqual(sessionTimeDiff <= 3, true);
});
});
});
});

0 comments on commit 99e0553

Please sign in to comment.