-
-
Notifications
You must be signed in to change notification settings - Fork 256
feat(seedless-onboarding): add dataType support for secret data items #7284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add dataType parameter to createToprfKeyAndBackupSeedPhrase and addNewSecretData - Add updateSecretDataItem and batchUpdateSecretDataItems methods - Update fetchAllSecretData to return SecretDataItemWithMetadata[]
| /** | ||
| * The client-assigned data type classification. | ||
| */ | ||
| dataType?: EncAccountDataType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this extra type SecretMetadata already has it has type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type is in encrypted data, which the server can't access to
data_type is a server-side column
the server needs to know the type of key for the deletion api: we're preventing clients from deleting the default srp
| /** | ||
| * The server-assigned item ID for this row. | ||
| */ | ||
| itemId?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add to the SecretMetadata instead of creating another wrapping types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
itemId is not part of the secret data, hence it shouldn't belong inside SecretMetadata. Only data, timestamp, type and version are part of SecretMetadata
| /** | ||
| * A secret data item with storage-level metadata from the metadata store. | ||
| */ | ||
| export type SecretDataItemWithMetadata< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the required metadata to the SecretMetadata class instead of creating another type defs.
The purpose the metadata class is to store and do things with extra non-secret data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
itemId and dataType are not part of the secret data. They belong outside of it, hence the wrapper type SecretDataItemWithMetadata is introduced.
The purpose the metadata class is to store and do things with extra non-secret data.
by the metadata class, did u mean the SecretMetadata class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved itemId and dataType here
| export { SecretMetadata } from './SecretMetadata'; | ||
| export { RecoveryError } from './errors'; | ||
|
|
||
| export { EncAccountDataType } from '@metamask/toprf-secure-backup'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why we export this, but this should not be determined from the users (ext or mobile).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's exported so clients can use it in createToprfKeyAndBackupSeedPhrase, addNewSecretData, updateSecretDataItem and batchUpdateSecretDataItems. The clients do determine the type of secret, e.g. in addNewSecretData, there's a type param of type SecretType where the client can decide if it's a mnemonic or privateKey
| password: string, | ||
| seedPhrase: Uint8Array, | ||
| keyringId: string, | ||
| dataType: EncAccountDataType = EncAccountDataType.PrimarySrp, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createToprfKeyAndBackupSeedPhrase only used for new users scenario, this param should not be exposed at all and type is always primary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed here
| type: SecretType, | ||
| options?: { | ||
| keyringId?: string; | ||
| dataType?: EncAccountDataType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have type field in 2nd param, we don't need new field here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SecretType and EncAccountDataType are slightly different:
SecretTypeonly has 2 types: SRP or private key;EncAccountDataTypehas 3: Primary SRP, imported SRP, imported private key- Even if we were to extend
SecretTypeto include a primary SRP, using string values should be avoided to protect user privacy when data is transmitted to the server
we can attempt to migrate SecretType from string to number, making it essentially the same as EncAccountDataType. Though they are essentially different things, and in the future we might want to remove type from the encrypted data since we will use dataType as the source of truth. What do u think?
| * @param params.dataType - The data type to set for the item. | ||
| * @returns A promise that resolves when the update is complete. | ||
| */ | ||
| async updateSecretDataItem(params: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we specify why and when we need to call this? since in the clients, update* is not something we usually do with SRPs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's used to migrate existing users to update the data_type column in the metadata service. Currently the server doesn't know the type of secret (it's encrypted). It needs to know for the deletion API to work: to prevent clients from deleting the default SRP
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added more notes here
| * @param params.updates - Array of objects containing itemId and fields to update. | ||
| * @returns A promise that resolves when all updates are complete. | ||
| */ | ||
| async batchUpdateSecretDataItems(params: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added more notes here
| // validate the primary secret data is a mnemonic (SRP) | ||
| const primarySecret = secrets[0]; | ||
| if (primarySecret.type !== SecretType.Mnemonic) { | ||
| if (!SecretMetadata.matchesType(results[0].secret, SecretType.Mnemonic)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we have Primary type, why don't we use here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed here
now we're validating both the .type in the encrypted data and also dataType
| authKeyPair: KeyPair; | ||
| options?: { | ||
| keyringId?: string; | ||
| dataType?: EncAccountDataType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have type in the params object. Please use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
related question and answer here: #7284 (comment)
…ckupSeedPhrase method
… PrimarySrp first, then createdAt
…etadata - Add itemId, dataType, createdAt properties to SecretMetadata class - Remove SecretDataItemWithMetadata wrapper type - Update fetchAllSecretData to return SecretMetadata[] directly - Add tests for storage metadata properties
…EUUID sorting TIMEUUID strings are not lexicographically sortable. Replace localeCompare with compareTimeuuid utility that extracts and compares actual timestamps.
| ); | ||
|
|
||
| // Sort: PrimarySrp first, then by createdAt/timestamp (oldest first) | ||
| results.sort((a, b) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorting is required here even though /get in metadata already does sorting because we need this for the migration since dataType and createdAt could be null thus we'll need a fallback to use the client-side timestamp
Explanation
The metadata service now supports a
dataTypecolumn for categorizing secret data (PrimarySrp, ImportedSrp, ImportedPrivateKey). This enables clients to distinguish between different types of backed-up secretsChanges include:
dataTypeparameter to insert operationsupdateSecretDataItemandbatchUpdateSecretDataItemsfor updating existing itemsfetchAllSecretDatato return storage metadata (itemId,dataType) alongside secret dataSecretMetadatato separate local metadata from storage-level metadataReferences
https://consensyssoftware.atlassian.net/browse/SL-350
Checklist