Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ export enum AuthenticatorApiOperations {
GenerateRegistrationOptions,
GenerateAuthenticationOptions,
VerifyRegistrationResponse,
VerifyAuthenticationResponse,
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'
import { AuthenticatorServerInterface } from '../../Server/Authenticator/AuthenticatorServerInterface'

Expand Down Expand Up @@ -79,7 +78,7 @@ export class AuthenticatorApiService implements AuthenticatorApiServiceInterface
async verifyRegistrationResponse(
userUuid: string,
name: string,
registrationCredential: Record<string, unknown>,
attestationResponse: Record<string, unknown>,
): Promise<VerifyAuthenticatorRegistrationResponseResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.VerifyRegistrationResponse)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
Expand All @@ -91,7 +90,7 @@ export class AuthenticatorApiService implements AuthenticatorApiServiceInterface
const response = await this.authenticatorServer.verifyRegistrationResponse({
userUuid,
name,
registrationCredential,
attestationResponse,
})

return response
Expand All @@ -102,45 +101,23 @@ export class AuthenticatorApiService implements AuthenticatorApiServiceInterface
}
}

async generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
async generateAuthenticationOptions(username: string): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.GenerateAuthenticationOptions)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}

this.operationsInProgress.set(AuthenticatorApiOperations.GenerateAuthenticationOptions, true)

try {
const response = await this.authenticatorServer.generateAuthenticationOptions()

return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateAuthenticationOptions, false)
}
}

async verifyAuthenticationResponse(
userUuid: string,
authenticationCredential: Record<string, unknown>,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.VerifyAuthenticationResponse)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}

this.operationsInProgress.set(AuthenticatorApiOperations.VerifyAuthenticationResponse, true)

try {
const response = await this.authenticatorServer.verifyAuthenticationResponse({
authenticationCredential,
userUuid,
const response = await this.authenticatorServer.generateAuthenticationOptions({
username,
})

return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyAuthenticationResponse, false)
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateAuthenticationOptions, false)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'

export interface AuthenticatorApiServiceInterface {
Expand All @@ -14,11 +13,7 @@ export interface AuthenticatorApiServiceInterface {
verifyRegistrationResponse(
userUuid: string,
name: string,
registrationCredential: Record<string, unknown>,
attestationResponse: Record<string, unknown>,
): Promise<VerifyAuthenticatorRegistrationResponseResponse>
generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
verifyAuthenticationResponse(
userUuid: string,
authenticationCredential: Record<string, unknown>,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse>
generateAuthenticationOptions(username: string): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface GenerateAuthenticatorAuthenticationOptionsRequestParams {
username: string
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export interface VerifyAuthenticatorRegistrationResponseRequestParams {
userUuid: string
name: string
registrationCredential: Record<string, unknown>
attestationResponse: Record<string, unknown>
[additionalParam: string]: unknown
}
2 changes: 1 addition & 1 deletion packages/api/src/Domain/Request/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export * from './ApiEndpointParam'
export * from './Authenticator/DeleteAuthenticatorRequestParams'
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsRequestParams'
export * from './Authenticator/ListAuthenticatorsRequestParams'
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseRequestParams'
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseRequestParams'
export * from './Recovery/RecoveryKeyParamsRequestParams'
export * from './Recovery/SignInWithRecoveryCodesRequestParams'
Expand Down

This file was deleted.

This file was deleted.

2 changes: 0 additions & 2 deletions packages/api/src/Domain/Response/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ export * from './Authenticator/GenerateAuthenticatorRegistrationOptionsResponse'
export * from './Authenticator/GenerateAuthenticatorRegistrationOptionsResponseBody'
export * from './Authenticator/ListAuthenticatorsResponse'
export * from './Authenticator/ListAuthenticatorsResponseBody'
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseResponse'
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseResponseBody'
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseResponse'
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseResponseBody'
export * from './Recovery/GenerateRecoveryCodesResponse'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
import {
ListAuthenticatorsRequestParams,
GenerateAuthenticatorAuthenticationOptionsRequestParams,
DeleteAuthenticatorRequestParams,
VerifyAuthenticatorRegistrationResponseRequestParams,
VerifyAuthenticatorAuthenticationResponseRequestParams,
} from '../../Request'
import {
ListAuthenticatorsResponse,
DeleteAuthenticatorResponse,
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'
import { AuthenticatorServerInterface } from './AuthenticatorServerInterface'
import { Paths } from './Paths'
Expand Down Expand Up @@ -45,17 +44,11 @@ export class AuthenticatorServer implements AuthenticatorServerInterface {
return response as VerifyAuthenticatorRegistrationResponseResponse
}

async generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
const response = await this.httpService.get(Paths.v1.generateAuthenticationOptions)
async generateAuthenticationOptions(
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
const response = await this.httpService.post(Paths.v1.generateAuthenticationOptions, params)

return response as GenerateAuthenticatorAuthenticationOptionsResponse
}

async verifyAuthenticationResponse(
params: VerifyAuthenticatorAuthenticationResponseRequestParams,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse> {
const response = await this.httpService.post(Paths.v1.verifyAuthenticationResponse, params)

return response as VerifyAuthenticatorAuthenticationResponseResponse
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import {
ListAuthenticatorsRequestParams,
DeleteAuthenticatorRequestParams,
VerifyAuthenticatorRegistrationResponseRequestParams,
VerifyAuthenticatorAuthenticationResponseRequestParams,
GenerateAuthenticatorAuthenticationOptionsRequestParams,
} from '../../Request'
import {
ListAuthenticatorsResponse,
DeleteAuthenticatorResponse,
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'

export interface AuthenticatorServerInterface {
Expand All @@ -20,8 +19,7 @@ export interface AuthenticatorServerInterface {
verifyRegistrationResponse(
params: VerifyAuthenticatorRegistrationResponseRequestParams,
): Promise<VerifyAuthenticatorRegistrationResponseResponse>
generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
verifyAuthenticationResponse(
params: VerifyAuthenticatorAuthenticationResponseRequestParams,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse>
generateAuthenticationOptions(
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
}
1 change: 0 additions & 1 deletion packages/api/src/Domain/Server/Authenticator/Paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const AuthenticatorPaths = {
generateRegistrationOptions: '/v1/authenticators/generate-registration-options',
verifyRegistrationResponse: '/v1/authenticators/verify-registration',
generateAuthenticationOptions: '/v1/authenticators/generate-authentication-options',
verifyAuthenticationResponse: '/v1/authenticators/verify-authentication',
}

export const Paths = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Uuid } from '@standardnotes/domain-core'
import { Username, Uuid } from '@standardnotes/domain-core'

export interface AuthenticatorClientInterface {
list(): Promise<Array<{ id: string; name: string }>>
Expand All @@ -9,6 +9,5 @@ export interface AuthenticatorClientInterface {
name: string,
registrationCredential: Record<string, unknown>,
): Promise<boolean>
generateAuthenticationOptions(): Promise<Record<string, unknown> | null>
verifyAuthenticationResponse(userUuid: Uuid, authenticationCredential: Record<string, unknown>): Promise<boolean>
generateAuthenticationOptions(username: Username): Promise<Record<string, unknown> | null>
}
26 changes: 3 additions & 23 deletions packages/services/src/Domain/Authenticator/AuthenticatorManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* istanbul ignore file */

import { AuthenticatorApiServiceInterface } from '@standardnotes/api'
import { Uuid } from '@standardnotes/domain-core'
import { Username, Uuid } from '@standardnotes/domain-core'

import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { AbstractService } from '../Service/AbstractService'
Expand Down Expand Up @@ -79,9 +79,9 @@ export class AuthenticatorManager extends AbstractService implements Authenticat
}
}

async generateAuthenticationOptions(): Promise<Record<string, unknown> | null> {
async generateAuthenticationOptions(username: Username): Promise<Record<string, unknown> | null> {
try {
const result = await this.authenticatorApiService.generateAuthenticationOptions()
const result = await this.authenticatorApiService.generateAuthenticationOptions(username.value)

if (result.data.error) {
return null
Expand All @@ -92,24 +92,4 @@ export class AuthenticatorManager extends AbstractService implements Authenticat
return null
}
}

async verifyAuthenticationResponse(
userUuid: Uuid,
authenticationCredential: Record<string, unknown>,
): Promise<boolean> {
try {
const result = await this.authenticatorApiService.verifyAuthenticationResponse(
userUuid.value,
authenticationCredential,
)

if (result.data.error) {
return false
}

return result.data.success
} catch (error) {
return false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class ChallengePrompt implements ChallengePromptInterface {
public readonly secureTextEntry = true,
public readonly keyboardType?: ChallengeKeyboardType,
public readonly initialValue?: ChallengeRawValue,
public readonly contextData?: Record<string, unknown>,
) {
switch (this.validation) {
case ChallengeValidation.AccountPassword:
Expand All @@ -37,6 +38,11 @@ export class ChallengePrompt implements ChallengePromptInterface {
this.placeholder = placeholder ?? ''
this.validates = true
break
case ChallengeValidation.Authenticator:
this.title = title ?? ChallengePromptTitle.U2F
this.placeholder = placeholder ?? ''
this.validates = true
break
case ChallengeValidation.ProtectionSessionDuration:
this.title = title ?? ChallengePromptTitle.RememberFor
this.placeholder = placeholder ?? ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export const ChallengePromptTitle = {
Biometrics: 'Biometrics',
RememberFor: 'Remember For',
Mfa: 'Two-factor Authentication Code',
U2F: 'Security Key',
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* istanbul ignore file */

export type ChallengeRawValue = number | string | boolean
export type ChallengeRawValue = number | string | boolean | Record<string, unknown>
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export enum ChallengeValidation {
AccountPassword = 2,
Biometric = 3,
ProtectionSessionDuration = 4,
Authenticator = 5,
}
1 change: 1 addition & 0 deletions packages/services/src/Domain/Strings/Messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const SessionStrings = {
},
SessionRestored: 'Your session has been successfully restored.',
EnterMfa: 'Please enter your two-factor authentication code.',
InputU2FDevice: 'Please authenticate with your U2F device.',
MfaInputPlaceholder: 'Two-factor authentication code',
EmailInputPlaceholder: 'Email',
PasswordInputPlaceholder: 'Password',
Expand Down
12 changes: 6 additions & 6 deletions packages/snjs/lib/Application/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ import { GetRecoveryCodes } from '@Lib/Domain/UseCase/GetRecoveryCodes/GetRecove
import { AddAuthenticator } from '@Lib/Domain/UseCase/AddAuthenticator/AddAuthenticator'
import { ListAuthenticators } from '@Lib/Domain/UseCase/ListAuthenticators/ListAuthenticators'
import { DeleteAuthenticator } from '@Lib/Domain/UseCase/DeleteAuthenticator/DeleteAuthenticator'
import { VerifyAuthenticator } from '@Lib/Domain/UseCase/VerifyAuthenticator/VerifyAuthenticator'
import { ListRevisions } from '@Lib/Domain/UseCase/ListRevisions/ListRevisions'
import { GetRevision } from '@Lib/Domain/UseCase/GetRevision/GetRevision'
import { DeleteRevision } from '@Lib/Domain/UseCase/DeleteRevision/DeleteRevision'
import { RevisionMetadata } from '@Lib/Domain/Revision/RevisionMetadata'
import { GetAuthenticatorAuthenticationResponse } from '@Lib/Domain/UseCase/GetAuthenticatorAuthenticationResponse/GetAuthenticatorAuthenticationResponse'

/** How often to automatically sync, in milliseconds */
const DEFAULT_AUTO_SYNC_INTERVAL = 30_000
Expand Down Expand Up @@ -193,7 +193,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
private declare _addAuthenticator: AddAuthenticator
private declare _listAuthenticators: ListAuthenticators
private declare _deleteAuthenticator: DeleteAuthenticator
private declare _verifyAuthenticator: VerifyAuthenticator
private declare _getAuthenticatorAuthenticationResponse: GetAuthenticatorAuthenticationResponse
private declare _listRevisions: ListRevisions
private declare _getRevision: GetRevision
private declare _deleteRevision: DeleteRevision
Expand Down Expand Up @@ -299,8 +299,8 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
return this._deleteAuthenticator
}

get verifyAuthenticator(): UseCaseInterface<void> {
return this._verifyAuthenticator
get getAuthenticatorAuthenticationResponse(): UseCaseInterface<Record<string, unknown>> {
return this._getAuthenticatorAuthenticationResponse
}

get listRevisions(): UseCaseInterface<Array<RevisionMetadata>> {
Expand Down Expand Up @@ -1272,7 +1272,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
;(this._addAuthenticator as unknown) = undefined
;(this._listAuthenticators as unknown) = undefined
;(this._deleteAuthenticator as unknown) = undefined
;(this._verifyAuthenticator as unknown) = undefined
;(this._getAuthenticatorAuthenticationResponse as unknown) = undefined
;(this._listRevisions as unknown) = undefined
;(this._getRevision as unknown) = undefined
;(this._deleteRevision as unknown) = undefined
Expand Down Expand Up @@ -1849,7 +1849,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli

this._deleteAuthenticator = new DeleteAuthenticator(this.authenticatorManager)

this._verifyAuthenticator = new VerifyAuthenticator(
this._getAuthenticatorAuthenticationResponse = new GetAuthenticatorAuthenticationResponse(
this.authenticatorManager,
this.options.u2fAuthenticatorVerificationPromptFunction,
)
Expand Down
Loading