Skip to content

Conversation

@ieow
Copy link
Contributor

@ieow ieow commented Nov 6, 2025

Motivation and Context

Jira Link:

Description

  • Add check for valid factorKey from tkey.metadata.factorEncs which will reduce the metadata call and avoid dirty deleted factorkey metadata.

Previously we check for valid factorkey by checking the metadata availability. This could cause issue if user deleted share with factor pub only but not factorkey where it delete the metadata.

  • Add new user indication. for manual sync, new user indication is required to decide commit_changes

How has this been tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • My code follows the code style of this project. (run lint)
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My code requires a db migration.

Note

Validate factor keys using metadata.factorEncs, introduce newUser lifecycle flag, and extend tests to cover MFA device factor replacement.

  • Core (src/mpcCoreKit.ts):
    • Validate factor keys via tkey.metadata.factorEncs in checkIfFactorKeyValid and inputFactorKey before metadata reads.
    • Add public newUser flag; set in handleNewUser/handleExistingUser, reset in resetState.
    • Minor flows: ensure device-factor checks during MFA/setup remain unchanged functionally.
  • Tests (tests/factors.spec.ts):
    • Import getPubKeyPoint and capture browserFactor for reuse.
    • Add "replace factor" test: create new DEVICE factor, switch active factor, delete old device factor, and assert old factor no longer works.
    • Adjust MFA test to use stored device factor and invalid input assertions.

Written by Cursor Bugbot for commit 826e944. This will update automatically on new commits. Configure here.

@ieow ieow marked this pull request as ready for review November 6, 2025 13:05
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: NewUser Flag Malfunction on Reset/Init Rehydrate

The resetState method doesn't reset the newUser flag to false. According to the comment, newUser should only be true during new user sign up and should be false after reinit or rehydration. Since resetState is called during init and logout, the flag will incorrectly remain true after these operations for users who were initially new users.

src/mpcCoreKit.ts#L1406-L1413

mpc-core-kit/src/mpcCoreKit.ts

Lines 1406 to 1413 in d28e51c

private resetState(): void {
this.ready = false;
this.tkey = null;
this.torusSp = null;
this.storageLayer = null;
this.state = { accountIndex: 0 };
}

Fix in Cursor Fix in Web


@ieow ieow force-pushed the fix/checkIfFactorKeyValid branch from d28e51c to 856f3af Compare December 1, 2025 05:09
assert.strictEqual(instance.status, COREKIT_STATUS.LOGGED_IN);


const deviceFactorPub = getPubKeyPoint(deviceFactorKeyBN);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Test uses wrong import and missing curve parameter

The test imports getPubKeyPoint from @tkey/common-types but all source code imports it from @tkey/tss and calls it with two arguments: the key and factorKeyCurve. The test call getPubKeyPoint(deviceFactorKeyBN) only passes one argument. When this Point is passed to deleteFactor, it's compared against Points created using factorKeyCurve. Using a different function or missing the curve parameter will cause incorrect Point comparisons, making the test unreliable. The factorKeyCurve is already imported in the test file but not used with getPubKeyPoint.

Additional Locations (1)

Fix in Cursor Fix in Web

throw Error("should not be able to deleted input factor");
} catch (e) {
assert(e instanceof Error);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Test assertion passes even when test should fail

The test's catch block uses assert(e instanceof Error) which will pass for both the expected error from inputFactorKey (when it correctly rejects a deleted factor) AND the manually thrown error on line 234 (when inputFactorKey incorrectly succeeds). If inputFactorKey fails to reject the deleted factor key, the test will still pass because the fallback throw Error(...) is also caught and satisfies the instanceof Error check. This masks potential regressions in the production code.

Fix in Cursor Fix in Web

throw Error("should not be able to deleted input factor");
} catch (e) {
assert(e instanceof Error);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Test fails silently when expected error not thrown

The test's error handling logic is flawed. The catch block checks assert(e instanceof Error), which passes for both the expected error from inputFactorKey AND the manually thrown error at line 234. If inputFactorKey succeeds unexpectedly, the test throws "should not be able to deleted input factor", catches it, and the assertion still passes since that error is also an Error instance. This masks test failures - the test will pass even when the deleted factor key is incorrectly accepted.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants