internal: incomplete vault systems behind feature flag (#2340)
This commit is contained in:
@@ -1,8 +1,48 @@
|
||||
import { Base64String } from '@standardnotes/sncrypto-common'
|
||||
import { UserRequestType } from '@standardnotes/common'
|
||||
import { Either, UserRequestType } from '@standardnotes/common'
|
||||
import { DeinitSource } from '../Application/DeinitSource'
|
||||
import { UserRegistrationResponseBody } from '@standardnotes/api'
|
||||
import { HttpError, HttpResponse, SignInResponse } from '@standardnotes/responses'
|
||||
import { AbstractService } from '../Service/AbstractService'
|
||||
|
||||
export interface UserClientInterface {
|
||||
export type CredentialsChangeFunctionResponse = { error?: HttpError }
|
||||
|
||||
export enum AccountEvent {
|
||||
SignedInOrRegistered = 'SignedInOrRegistered',
|
||||
SignedOut = 'SignedOut',
|
||||
}
|
||||
|
||||
export interface SignedInOrRegisteredEventPayload {
|
||||
ephemeral: boolean
|
||||
mergeLocal: boolean
|
||||
awaitSync: boolean
|
||||
checkIntegrity: boolean
|
||||
}
|
||||
|
||||
export interface SignedOutEventPayload {
|
||||
source: DeinitSource
|
||||
}
|
||||
|
||||
export interface AccountEventData {
|
||||
payload: Either<SignedInOrRegisteredEventPayload, SignedOutEventPayload>
|
||||
}
|
||||
|
||||
export interface UserClientInterface extends AbstractService<AccountEvent, AccountEventData> {
|
||||
isSignedIn(): boolean
|
||||
register(
|
||||
email: string,
|
||||
password: string,
|
||||
ephemeral: boolean,
|
||||
mergeLocal: boolean,
|
||||
): Promise<UserRegistrationResponseBody>
|
||||
signIn(
|
||||
email: string,
|
||||
password: string,
|
||||
strict: boolean,
|
||||
ephemeral: boolean,
|
||||
mergeLocal: boolean,
|
||||
awaitSync: boolean,
|
||||
): Promise<HttpResponse<SignInResponse>>
|
||||
deleteAccount(): Promise<{
|
||||
error: boolean
|
||||
message?: string
|
||||
@@ -10,4 +50,9 @@ export interface UserClientInterface {
|
||||
signOut(force?: boolean, source?: DeinitSource): Promise<void>
|
||||
submitUserRequest(requestType: UserRequestType): Promise<boolean>
|
||||
populateSessionFromDemoShareToken(token: Base64String): Promise<void>
|
||||
updateAccountWithFirstTimeKeyPair(): Promise<{
|
||||
success?: true
|
||||
canceled?: true
|
||||
error?: { message: string }
|
||||
}>
|
||||
}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import { Base64String } from '@standardnotes/sncrypto-common'
|
||||
import { EncryptionProviderInterface, SNRootKey, SNRootKeyParams } from '@standardnotes/encryption'
|
||||
import { HttpResponse, SignInResponse, User, HttpError, isErrorResponse } from '@standardnotes/responses'
|
||||
import { Either, KeyParamsOrigination, UserRequestType } from '@standardnotes/common'
|
||||
import { HttpResponse, SignInResponse, User, isErrorResponse } from '@standardnotes/responses'
|
||||
import { KeyParamsOrigination, UserRequestType } from '@standardnotes/common'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { UserApiServiceInterface, UserRegistrationResponseBody } from '@standardnotes/api'
|
||||
import {
|
||||
AccountEventData,
|
||||
AccountEvent,
|
||||
SignedInOrRegisteredEventPayload,
|
||||
CredentialsChangeFunctionResponse,
|
||||
} from '@standardnotes/services'
|
||||
|
||||
import * as Messages from '../Strings/Messages'
|
||||
import { InfoStrings } from '../Strings/InfoStrings'
|
||||
@@ -28,28 +34,6 @@ import { ProtectionsClientInterface } from '../Protection/ProtectionClientInterf
|
||||
import { InternalEventHandlerInterface } from '../Internal/InternalEventHandlerInterface'
|
||||
import { InternalEventInterface } from '../Internal/InternalEventInterface'
|
||||
|
||||
export type CredentialsChangeFunctionResponse = { error?: HttpError }
|
||||
|
||||
export enum AccountEvent {
|
||||
SignedInOrRegistered = 'SignedInOrRegistered',
|
||||
SignedOut = 'SignedOut',
|
||||
}
|
||||
|
||||
export interface SignedInOrRegisteredEventPayload {
|
||||
ephemeral: boolean
|
||||
mergeLocal: boolean
|
||||
awaitSync: boolean
|
||||
checkIntegrity: boolean
|
||||
}
|
||||
|
||||
export interface SignedOutEventPayload {
|
||||
source: DeinitSource
|
||||
}
|
||||
|
||||
export interface AccountEventData {
|
||||
payload: Either<SignedInOrRegisteredEventPayload, SignedOutEventPayload>
|
||||
}
|
||||
|
||||
export class UserService
|
||||
extends AbstractService<AccountEvent, AccountEventData>
|
||||
implements UserClientInterface, InternalEventHandlerInterface
|
||||
@@ -125,6 +109,10 @@ export class UserService
|
||||
;(this.userApiService as unknown) = undefined
|
||||
}
|
||||
|
||||
isSignedIn(): boolean {
|
||||
return this.sessionManager.isSignedIn()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mergeLocal Whether to merge existing offline data into account. If false,
|
||||
* any pre-existing data will be fully deleted upon success.
|
||||
@@ -352,6 +340,20 @@ export class UserService
|
||||
}
|
||||
}
|
||||
|
||||
async updateAccountWithFirstTimeKeyPair(): Promise<{
|
||||
success?: true
|
||||
canceled?: true
|
||||
error?: { message: string }
|
||||
}> {
|
||||
if (!this.sessionManager.isUserMissingKeyPair()) {
|
||||
throw Error('Cannot update account with first time keypair if user already has a keypair')
|
||||
}
|
||||
|
||||
const result = await this.performProtocolUpgrade()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public async performProtocolUpgrade(): Promise<{
|
||||
success?: true
|
||||
canceled?: true
|
||||
@@ -524,7 +526,7 @@ export class UserService
|
||||
private async rewriteItemsKeys(): Promise<void> {
|
||||
const itemsKeys = this.itemManager.getDisplayableItemsKeys()
|
||||
const payloads = itemsKeys.map((key) => key.payloadRepresentation())
|
||||
await this.storageService.forceDeletePayloads(payloads)
|
||||
await this.storageService.deletePayloads(payloads)
|
||||
await this.syncService.persistPayloads(payloads)
|
||||
}
|
||||
|
||||
@@ -571,7 +573,7 @@ export class UserService
|
||||
|
||||
const user = this.sessionManager.getUser() as User
|
||||
const currentEmail = user.email
|
||||
const rootKeys = await this.recomputeRootKeysForCredentialChange({
|
||||
const { currentRootKey, newRootKey } = await this.recomputeRootKeysForCredentialChange({
|
||||
currentPassword: parameters.currentPassword,
|
||||
currentEmail,
|
||||
origination: parameters.origination,
|
||||
@@ -583,8 +585,8 @@ export class UserService
|
||||
|
||||
/** Now, change the credentials on the server. Roll back on failure */
|
||||
const { response } = await this.sessionManager.changeCredentials({
|
||||
currentServerPassword: rootKeys.currentRootKey.serverPassword as string,
|
||||
newRootKey: rootKeys.newRootKey,
|
||||
currentServerPassword: currentRootKey.serverPassword as string,
|
||||
newRootKey: newRootKey,
|
||||
wrappingKey,
|
||||
newEmail: parameters.newEmail,
|
||||
})
|
||||
@@ -596,7 +598,7 @@ export class UserService
|
||||
}
|
||||
|
||||
const rollback = await this.protocolService.createNewItemsKeyWithRollback()
|
||||
await this.protocolService.reencryptItemsKeys()
|
||||
await this.protocolService.reencryptApplicableItemsAfterUserRootKeyChange()
|
||||
await this.syncService.sync({ awaitAll: true })
|
||||
|
||||
const defaultItemsKey = this.protocolService.getSureDefaultItemsKey()
|
||||
@@ -604,11 +606,11 @@ export class UserService
|
||||
|
||||
if (!itemsKeyWasSynced) {
|
||||
await this.sessionManager.changeCredentials({
|
||||
currentServerPassword: rootKeys.newRootKey.serverPassword as string,
|
||||
newRootKey: rootKeys.currentRootKey,
|
||||
currentServerPassword: newRootKey.serverPassword as string,
|
||||
newRootKey: currentRootKey,
|
||||
wrappingKey,
|
||||
})
|
||||
await this.protocolService.reencryptItemsKeys()
|
||||
await this.protocolService.reencryptApplicableItemsAfterUserRootKeyChange()
|
||||
await rollback()
|
||||
await this.syncService.sync({ awaitAll: true })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user