feat(api): add authenticators api (#2124)

* feat(api): add authenticators api

* fix(services): responses interpreting in authenticator manager
This commit is contained in:
Karol Sójko
2022-12-29 16:04:53 +01:00
committed by GitHub
parent 5a8a37413e
commit 59e8b5c8b5
32 changed files with 585 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
export interface AuthenticatorClientInterface {
list(): Promise<Array<{ id: string; name: string }>>
delete(authenticatorId: string): Promise<boolean>
generateRegistrationOptions(userUuid: string, username: string): Promise<Record<string, unknown> | null>
verifyRegistrationResponse(
userUuid: string,
name: string,
registrationCredential: Record<string, unknown>,
): Promise<boolean>
generateAuthenticationOptions(): Promise<Record<string, unknown> | null>
verifyAuthenticationResponse(userUuid: string, authenticationCredential: Record<string, unknown>): Promise<boolean>
}

View File

@@ -0,0 +1,111 @@
/* istanbul ignore file */
import { AuthenticatorApiServiceInterface } from '@standardnotes/api'
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { AbstractService } from '../Service/AbstractService'
import { AuthenticatorClientInterface } from './AuthenticatorClientInterface'
export class AuthenticatorManager extends AbstractService implements AuthenticatorClientInterface {
constructor(
private authenticatorApiService: AuthenticatorApiServiceInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
}
async list(): Promise<{ id: string; name: string }[]> {
try {
const result = await this.authenticatorApiService.list()
if (result.data.error) {
return []
}
return result.data.authenticators
} catch (error) {
return []
}
}
async delete(authenticatorId: string): Promise<boolean> {
try {
const result = await this.authenticatorApiService.delete(authenticatorId)
if (result.data.error) {
return false
}
return true
} catch (error) {
return false
}
}
async generateRegistrationOptions(userUuid: string, username: string): Promise<Record<string, unknown> | null> {
try {
const result = await this.authenticatorApiService.generateRegistrationOptions(userUuid, username)
if (result.data.error) {
return null
}
return result.data.options
} catch (error) {
return null
}
}
async verifyRegistrationResponse(
userUuid: string,
name: string,
registrationCredential: Record<string, unknown>,
): Promise<boolean> {
try {
const result = await this.authenticatorApiService.verifyRegistrationResponse(
userUuid,
name,
registrationCredential,
)
if (result.data.error) {
return false
}
return result.data.success
} catch (error) {
return false
}
}
async generateAuthenticationOptions(): Promise<Record<string, unknown> | null> {
try {
const result = await this.authenticatorApiService.generateAuthenticationOptions()
if (result.data.error) {
return null
}
return result.data.options
} catch (error) {
return null
}
}
async verifyAuthenticationResponse(
userUuid: string,
authenticationCredential: Record<string, unknown>,
): Promise<boolean> {
try {
const result = await this.authenticatorApiService.verifyAuthenticationResponse(userUuid, authenticationCredential)
if (result.data.error) {
return false
}
return result.data.success
} catch (error) {
return false
}
}
}

View File

@@ -6,6 +6,8 @@ export * from './Application/ApplicationStage'
export * from './Application/DeinitCallback'
export * from './Application/DeinitSource'
export * from './Application/DeinitMode'
export * from './Authenticator/AuthenticatorClientInterface'
export * from './Authenticator/AuthenticatorManager'
export * from './User/UserClientInterface'
export * from './Application/WebApplicationInterface'
export * from './Backups/BackupService'