feat: add services package
This commit is contained in:
21
packages/services/src/Domain/Challenge/ChallengeInterface.ts
Normal file
21
packages/services/src/Domain/Challenge/ChallengeInterface.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ChallengePromptInterface } from './Prompt/ChallengePromptInterface'
|
||||
import { ChallengeReason } from './Types/ChallengeReason'
|
||||
import { ChallengeValidation } from './Types/ChallengeValidation'
|
||||
|
||||
export interface ChallengeInterface {
|
||||
readonly id: number
|
||||
readonly prompts: ChallengePromptInterface[]
|
||||
readonly reason: ChallengeReason
|
||||
readonly cancelable: boolean
|
||||
|
||||
/** Outside of the modal, this is the title of the modal itself */
|
||||
get modalTitle(): string
|
||||
|
||||
/** Inside of the modal, this is the H1 */
|
||||
get heading(): string | undefined
|
||||
|
||||
/** Inside of the modal, this is the H2 */
|
||||
get subheading(): string | undefined
|
||||
|
||||
hasPromptForValidationType(type: ChallengeValidation): boolean
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ChallengeInterface } from './ChallengeInterface'
|
||||
import { ChallengeArtifacts } from './Types/ChallengeArtifacts'
|
||||
import { ChallengeValidation } from './Types/ChallengeValidation'
|
||||
import { ChallengeValue } from './Types/ChallengeValue'
|
||||
|
||||
export interface ChallengeResponseInterface {
|
||||
readonly challenge: ChallengeInterface
|
||||
readonly values: ChallengeValue[]
|
||||
readonly artifacts?: ChallengeArtifacts
|
||||
|
||||
getValueForType(type: ChallengeValidation): ChallengeValue
|
||||
getDefaultValue(): ChallengeValue
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { AbstractService } from '../Service/AbstractService'
|
||||
import { ChallengeInterface } from './ChallengeInterface'
|
||||
import { ChallengePromptInterface } from './Prompt/ChallengePromptInterface'
|
||||
import { ChallengeResponseInterface } from './ChallengeResponseInterface'
|
||||
import { ChallengeReason } from './Types/ChallengeReason'
|
||||
|
||||
export interface ChallengeServiceInterface extends AbstractService {
|
||||
/**
|
||||
* Resolves when the challenge has been completed.
|
||||
* For non-validated challenges, will resolve when the first value is submitted.
|
||||
*/
|
||||
promptForChallengeResponse(challenge: ChallengeInterface): Promise<ChallengeResponseInterface | undefined>
|
||||
|
||||
createChallenge(
|
||||
prompts: ChallengePromptInterface[],
|
||||
reason: ChallengeReason,
|
||||
cancelable: boolean,
|
||||
heading?: string,
|
||||
subheading?: string,
|
||||
): ChallengeInterface
|
||||
|
||||
completeChallenge(challenge: ChallengeInterface): void
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { assertUnreachable } from '@standardnotes/utils'
|
||||
import { ChallengeKeyboardType } from '../Types/ChallengeKeyboardType'
|
||||
import { ChallengeRawValue } from '../Types/ChallengeRawValue'
|
||||
import { ChallengeValidation } from '../Types/ChallengeValidation'
|
||||
import { ChallengePromptInterface } from './ChallengePromptInterface'
|
||||
import { ChallengePromptTitle } from './PromptTitles'
|
||||
|
||||
/* istanbul ignore file */
|
||||
|
||||
export class ChallengePrompt implements ChallengePromptInterface {
|
||||
public readonly id = Math.random()
|
||||
public readonly placeholder: string
|
||||
public readonly title: string
|
||||
public readonly validates: boolean
|
||||
|
||||
constructor(
|
||||
public readonly validation: ChallengeValidation,
|
||||
title?: string,
|
||||
placeholder?: string,
|
||||
public readonly secureTextEntry = true,
|
||||
public readonly keyboardType?: ChallengeKeyboardType,
|
||||
public readonly initialValue?: ChallengeRawValue,
|
||||
) {
|
||||
switch (this.validation) {
|
||||
case ChallengeValidation.AccountPassword:
|
||||
this.title = title ?? ChallengePromptTitle.AccountPassword
|
||||
this.placeholder = placeholder ?? ChallengePromptTitle.AccountPassword
|
||||
this.validates = true
|
||||
break
|
||||
case ChallengeValidation.LocalPasscode:
|
||||
this.title = title ?? ChallengePromptTitle.LocalPasscode
|
||||
this.placeholder = placeholder ?? ChallengePromptTitle.LocalPasscode
|
||||
this.validates = true
|
||||
break
|
||||
case ChallengeValidation.Biometric:
|
||||
this.title = title ?? ChallengePromptTitle.Biometrics
|
||||
this.placeholder = placeholder ?? ''
|
||||
this.validates = true
|
||||
break
|
||||
case ChallengeValidation.ProtectionSessionDuration:
|
||||
this.title = title ?? ChallengePromptTitle.RememberFor
|
||||
this.placeholder = placeholder ?? ''
|
||||
this.validates = true
|
||||
break
|
||||
case ChallengeValidation.None:
|
||||
this.title = title ?? ''
|
||||
this.placeholder = placeholder ?? ''
|
||||
this.validates = false
|
||||
break
|
||||
default:
|
||||
assertUnreachable(this.validation)
|
||||
}
|
||||
Object.freeze(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { ChallengeKeyboardType } from '../Types/ChallengeKeyboardType'
|
||||
import { ChallengeRawValue } from '../Types/ChallengeRawValue'
|
||||
import { ChallengeValidation } from '../Types/ChallengeValidation'
|
||||
|
||||
/**
|
||||
* A Challenge can have many prompts. Each prompt represents a unique input,
|
||||
* such as a text field, or biometric scanner.
|
||||
*/
|
||||
export interface ChallengePromptInterface {
|
||||
readonly id: number
|
||||
readonly placeholder: string
|
||||
readonly title: string
|
||||
readonly validates: boolean
|
||||
|
||||
readonly validation: ChallengeValidation
|
||||
readonly secureTextEntry: boolean
|
||||
readonly keyboardType?: ChallengeKeyboardType
|
||||
readonly initialValue?: ChallengeRawValue
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
export const ChallengePromptTitle = {
|
||||
AccountPassword: 'Account Password',
|
||||
LocalPasscode: 'Application Passcode',
|
||||
Biometrics: 'Biometrics',
|
||||
RememberFor: 'Remember For',
|
||||
Mfa: 'Two-factor Authentication Code',
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { RootKeyInterface } from '@standardnotes/models'
|
||||
|
||||
/* istanbul ignore file */
|
||||
|
||||
export type ChallengeArtifacts = {
|
||||
wrappingKey?: RootKeyInterface
|
||||
rootKey?: RootKeyInterface
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
/** For mobile */
|
||||
export enum ChallengeKeyboardType {
|
||||
Alphanumeric = 'default',
|
||||
Numeric = 'numeric',
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
export type ChallengeRawValue = number | string | boolean
|
||||
@@ -0,0 +1,27 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
export enum ChallengeReason {
|
||||
AccessProtectedFile,
|
||||
AccessProtectedNote,
|
||||
AddPasscode,
|
||||
ApplicationUnlock,
|
||||
ChangeAutolockInterval,
|
||||
ChangePasscode,
|
||||
CreateDecryptedBackupWithProtectedItems,
|
||||
Custom,
|
||||
DecryptEncryptedFile,
|
||||
DisableBiometrics,
|
||||
DisableMfa,
|
||||
ExportBackup,
|
||||
ImportFile,
|
||||
Migration,
|
||||
ProtocolUpgrade,
|
||||
RemovePasscode,
|
||||
ResaveRootKey,
|
||||
RevokeSession,
|
||||
SearchProtectedNotesText,
|
||||
SelectProtectedNote,
|
||||
UnprotectFile,
|
||||
UnprotectNote,
|
||||
DeleteAccount,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
export enum ChallengeValidation {
|
||||
None = 0,
|
||||
LocalPasscode = 1,
|
||||
AccountPassword = 2,
|
||||
Biometric = 3,
|
||||
ProtectionSessionDuration = 4,
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ChallengePromptInterface } from '../Prompt/ChallengePromptInterface'
|
||||
import { ChallengeRawValue } from './ChallengeRawValue'
|
||||
|
||||
export interface ChallengeValue {
|
||||
readonly prompt: ChallengePromptInterface
|
||||
readonly value: ChallengeRawValue
|
||||
}
|
||||
|
||||
/* istanbul ignore file */
|
||||
|
||||
export function CreateChallengeValue(prompt: ChallengePromptInterface, value: ChallengeRawValue): ChallengeValue {
|
||||
return { prompt, value }
|
||||
}
|
||||
12
packages/services/src/Domain/Challenge/index.ts
Normal file
12
packages/services/src/Domain/Challenge/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export * from './ChallengeInterface'
|
||||
export * from './ChallengeResponseInterface'
|
||||
export * from './ChallengeServiceInterface'
|
||||
export * from './Prompt/ChallengePrompt'
|
||||
export * from './Prompt/ChallengePromptInterface'
|
||||
export * from './Prompt/PromptTitles'
|
||||
export * from './Types/ChallengeArtifacts'
|
||||
export * from './Types/ChallengeKeyboardType'
|
||||
export * from './Types/ChallengeRawValue'
|
||||
export * from './Types/ChallengeReason'
|
||||
export * from './Types/ChallengeValidation'
|
||||
export * from './Types/ChallengeValue'
|
||||
Reference in New Issue
Block a user