feat: add sending user requests to process (#1908)

* feat: add sending user requests to process

* fix(snjs): yarn lock

* fix(snjs): imports

* fix: specs
This commit is contained in:
Karol Sójko
2022-11-02 11:33:02 +01:00
committed by GitHub
parent f687334d7d
commit b2faa815e9
81 changed files with 766 additions and 325 deletions

View File

@@ -0,0 +1,117 @@
import { assertUnreachable } from '@standardnotes/utils'
import { ChallengeModalTitle, ChallengeStrings } from '../Strings/Messages'
import { ChallengeInterface } from './ChallengeInterface'
import { ChallengePrompt } from './Prompt/ChallengePrompt'
import { ChallengeReason } from './Types/ChallengeReason'
import { ChallengeValidation } from './Types/ChallengeValidation'
/**
* A challenge is a stateless description of what the client needs to provide
* in order to proceed.
*/
export class Challenge implements ChallengeInterface {
public readonly id = Math.random()
constructor(
public readonly prompts: ChallengePrompt[],
public readonly reason: ChallengeReason,
public readonly cancelable: boolean,
public readonly _heading?: string,
public readonly _subheading?: string,
) {
Object.freeze(this)
}
/** Outside of the modal, this is the title of the modal itself */
get modalTitle(): string {
switch (this.reason) {
case ChallengeReason.Migration:
return ChallengeModalTitle.Migration
default:
return ChallengeModalTitle.Generic
}
}
/** Inside of the modal, this is the H1 */
get heading(): string | undefined {
if (this._heading) {
return this._heading
} else {
switch (this.reason) {
case ChallengeReason.ApplicationUnlock:
return ChallengeStrings.UnlockApplication
case ChallengeReason.Migration:
return ChallengeStrings.EnterLocalPasscode
case ChallengeReason.ResaveRootKey:
return ChallengeStrings.EnterPasscodeForRootResave
case ChallengeReason.ProtocolUpgrade:
return ChallengeStrings.EnterCredentialsForProtocolUpgrade
case ChallengeReason.AccessProtectedNote:
return ChallengeStrings.NoteAccess
case ChallengeReason.AccessProtectedFile:
return ChallengeStrings.FileAccess
case ChallengeReason.ImportFile:
return ChallengeStrings.ImportFile
case ChallengeReason.AddPasscode:
return ChallengeStrings.AddPasscode
case ChallengeReason.RemovePasscode:
return ChallengeStrings.RemovePasscode
case ChallengeReason.ChangePasscode:
return ChallengeStrings.ChangePasscode
case ChallengeReason.ChangeAutolockInterval:
return ChallengeStrings.ChangeAutolockInterval
case ChallengeReason.CreateDecryptedBackupWithProtectedItems:
return ChallengeStrings.EnterCredentialsForDecryptedBackupDownload
case ChallengeReason.RevokeSession:
return ChallengeStrings.RevokeSession
case ChallengeReason.DecryptEncryptedFile:
return ChallengeStrings.DecryptEncryptedFile
case ChallengeReason.ExportBackup:
return ChallengeStrings.ExportBackup
case ChallengeReason.DisableBiometrics:
return ChallengeStrings.DisableBiometrics
case ChallengeReason.UnprotectNote:
return ChallengeStrings.UnprotectNote
case ChallengeReason.UnprotectFile:
return ChallengeStrings.UnprotectFile
case ChallengeReason.SearchProtectedNotesText:
return ChallengeStrings.SearchProtectedNotesText
case ChallengeReason.SelectProtectedNote:
return ChallengeStrings.SelectProtectedNote
case ChallengeReason.DisableMfa:
return ChallengeStrings.DisableMfa
case ChallengeReason.DeleteAccount:
return ChallengeStrings.DeleteAccount
case ChallengeReason.AuthorizeNoteForListed:
return ChallengeStrings.ListedAuthorization
case ChallengeReason.Custom:
return ''
default:
return assertUnreachable(this.reason)
}
}
}
/** Inside of the modal, this is the H2 */
get subheading(): string | undefined {
if (this._subheading) {
return this._subheading
}
switch (this.reason) {
case ChallengeReason.Migration:
return ChallengeStrings.EnterPasscodeForMigration
default:
return undefined
}
}
hasPromptForValidationType(type: ChallengeValidation): boolean {
for (const prompt of this.prompts) {
if (prompt.validation === type) {
return true
}
}
return false
}
}

View File

@@ -1,3 +1,5 @@
import { RootKeyInterface } from '@standardnotes/models'
import { AbstractService } from '../Service/AbstractService'
import { ChallengeInterface } from './ChallengeInterface'
import { ChallengePromptInterface } from './Prompt/ChallengePromptInterface'
@@ -10,7 +12,6 @@ export interface ChallengeServiceInterface extends AbstractService {
* For non-validated challenges, will resolve when the first value is submitted.
*/
promptForChallengeResponse(challenge: ChallengeInterface): Promise<ChallengeResponseInterface | undefined>
createChallenge(
prompts: ChallengePromptInterface[],
reason: ChallengeReason,
@@ -18,6 +19,19 @@ export interface ChallengeServiceInterface extends AbstractService {
heading?: string,
subheading?: string,
): ChallengeInterface
completeChallenge(challenge: ChallengeInterface): void
getWrappingKeyIfApplicable(passcode?: string): Promise<
| {
canceled?: undefined
wrappingKey?: undefined
}
| {
canceled: boolean
wrappingKey?: undefined
}
| {
wrappingKey: RootKeyInterface
canceled?: undefined
}
>
}

View File

@@ -1,3 +1,4 @@
export * from './Challenge'
export * from './ChallengeInterface'
export * from './ChallengeResponseInterface'
export * from './ChallengeServiceInterface'