feat(api): add authenticators api (#2124)
* feat(api): add authenticators api * fix(services): responses interpreting in authenticator manager
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
export enum AuthenticatorApiOperations {
|
||||||
|
List,
|
||||||
|
Delete,
|
||||||
|
GenerateRegistrationOptions,
|
||||||
|
GenerateAuthenticationOptions,
|
||||||
|
VerifyRegistrationResponse,
|
||||||
|
VerifyAuthenticationResponse,
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { ErrorMessage } from '../../Error/ErrorMessage'
|
||||||
|
import { ApiCallError } from '../../Error/ApiCallError'
|
||||||
|
|
||||||
|
import { AuthenticatorApiServiceInterface } from './AuthenticatorApiServiceInterface'
|
||||||
|
import { AuthenticatorApiOperations } from './AuthenticatorApiOperations'
|
||||||
|
import {
|
||||||
|
ListAuthenticatorsResponse,
|
||||||
|
DeleteAuthenticatorResponse,
|
||||||
|
GenerateAuthenticatorRegistrationOptionsResponse,
|
||||||
|
VerifyAuthenticatorRegistrationResponseResponse,
|
||||||
|
GenerateAuthenticatorAuthenticationOptionsResponse,
|
||||||
|
VerifyAuthenticatorAuthenticationResponseResponse,
|
||||||
|
} from '../../Response'
|
||||||
|
import { AuthenticatorServerInterface } from '../../Server/Authenticator/AuthenticatorServerInterface'
|
||||||
|
|
||||||
|
export class AuthenticatorApiService implements AuthenticatorApiServiceInterface {
|
||||||
|
private operationsInProgress: Map<AuthenticatorApiOperations, boolean>
|
||||||
|
|
||||||
|
constructor(private authenticatorServer: AuthenticatorServerInterface) {
|
||||||
|
this.operationsInProgress = new Map()
|
||||||
|
}
|
||||||
|
|
||||||
|
async list(): Promise<ListAuthenticatorsResponse> {
|
||||||
|
if (this.operationsInProgress.get(AuthenticatorApiOperations.List)) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericInProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.List, true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.authenticatorServer.list({})
|
||||||
|
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||||
|
} finally {
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.List, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(authenticatorId: string): Promise<DeleteAuthenticatorResponse> {
|
||||||
|
if (this.operationsInProgress.get(AuthenticatorApiOperations.Delete)) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericInProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.Delete, true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.authenticatorServer.delete({
|
||||||
|
authenticatorId,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||||
|
} finally {
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.Delete, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateRegistrationOptions(
|
||||||
|
userUuid: string,
|
||||||
|
username: string,
|
||||||
|
): Promise<GenerateAuthenticatorRegistrationOptionsResponse> {
|
||||||
|
if (this.operationsInProgress.get(AuthenticatorApiOperations.GenerateRegistrationOptions)) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericInProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateRegistrationOptions, true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.authenticatorServer.generateRegistrationOptions({
|
||||||
|
username,
|
||||||
|
userUuid,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||||
|
} finally {
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateRegistrationOptions, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async verifyRegistrationResponse(
|
||||||
|
userUuid: string,
|
||||||
|
name: string,
|
||||||
|
registrationCredential: Record<string, unknown>,
|
||||||
|
): Promise<VerifyAuthenticatorRegistrationResponseResponse> {
|
||||||
|
if (this.operationsInProgress.get(AuthenticatorApiOperations.VerifyRegistrationResponse)) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericInProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyRegistrationResponse, true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.authenticatorServer.verifyRegistrationResponse({
|
||||||
|
userUuid,
|
||||||
|
name,
|
||||||
|
registrationCredential,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||||
|
} finally {
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyRegistrationResponse, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateAuthenticationOptions(): 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,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||||
|
} finally {
|
||||||
|
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyAuthenticationResponse, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import {
|
||||||
|
ListAuthenticatorsResponse,
|
||||||
|
DeleteAuthenticatorResponse,
|
||||||
|
GenerateAuthenticatorRegistrationOptionsResponse,
|
||||||
|
VerifyAuthenticatorRegistrationResponseResponse,
|
||||||
|
GenerateAuthenticatorAuthenticationOptionsResponse,
|
||||||
|
VerifyAuthenticatorAuthenticationResponseResponse,
|
||||||
|
} from '../../Response'
|
||||||
|
|
||||||
|
export interface AuthenticatorApiServiceInterface {
|
||||||
|
list(): Promise<ListAuthenticatorsResponse>
|
||||||
|
delete(authenticatorId: string): Promise<DeleteAuthenticatorResponse>
|
||||||
|
generateRegistrationOptions(
|
||||||
|
userUuid: string,
|
||||||
|
username: string,
|
||||||
|
): Promise<GenerateAuthenticatorRegistrationOptionsResponse>
|
||||||
|
verifyRegistrationResponse(
|
||||||
|
userUuid: string,
|
||||||
|
name: string,
|
||||||
|
registrationCredential: Record<string, unknown>,
|
||||||
|
): Promise<VerifyAuthenticatorRegistrationResponseResponse>
|
||||||
|
generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
|
||||||
|
verifyAuthenticationResponse(
|
||||||
|
userUuid: string,
|
||||||
|
authenticationCredential: Record<string, unknown>,
|
||||||
|
): Promise<VerifyAuthenticatorAuthenticationResponseResponse>
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
export * from './Authenticator/AuthenticatorApiOperations'
|
||||||
|
export * from './Authenticator/AuthenticatorApiService'
|
||||||
|
export * from './Authenticator/AuthenticatorApiServiceInterface'
|
||||||
export * from './Subscription/SubscriptionApiOperations'
|
export * from './Subscription/SubscriptionApiOperations'
|
||||||
export * from './Subscription/SubscriptionApiService'
|
export * from './Subscription/SubscriptionApiService'
|
||||||
export * from './Subscription/SubscriptionApiServiceInterface'
|
export * from './Subscription/SubscriptionApiServiceInterface'
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface DeleteAuthenticatorRequestParams {
|
||||||
|
authenticatorId: string
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface GenerateAuthenticatorAuthenticationOptionsRequestParams {
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export interface GenerateAuthenticatorRegistrationOptionsRequestParams {
|
||||||
|
userUuid: string
|
||||||
|
username: string
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface ListAuthenticatorsRequestParams {
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export interface VerifyAuthenticatorAuthenticationResponseRequestParams {
|
||||||
|
userUuid: string
|
||||||
|
authenticationCredential: Record<string, unknown>
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface VerifyAuthenticatorRegistrationResponseRequestParams {
|
||||||
|
userUuid: string
|
||||||
|
name: string
|
||||||
|
registrationCredential: Record<string, unknown>
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
export * from './ApiEndpointParam'
|
export * from './ApiEndpointParam'
|
||||||
|
export * from './Authenticator/DeleteAuthenticatorRequestParams'
|
||||||
|
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsRequestParams'
|
||||||
|
export * from './Authenticator/GenerateAuthenticatorRegistrationOptionsRequestParams'
|
||||||
|
export * from './Authenticator/ListAuthenticatorsRequestParams'
|
||||||
|
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseRequestParams'
|
||||||
|
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseRequestParams'
|
||||||
export * from './Subscription/AppleIAPConfirmRequestParams'
|
export * from './Subscription/AppleIAPConfirmRequestParams'
|
||||||
export * from './Subscription/SubscriptionInviteAcceptRequestParams'
|
export * from './Subscription/SubscriptionInviteAcceptRequestParams'
|
||||||
export * from './Subscription/SubscriptionInviteCancelRequestParams'
|
export * from './Subscription/SubscriptionInviteCancelRequestParams'
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
|
||||||
|
import { DeleteAuthenticatorResponseBody } from './DeleteAuthenticatorResponseBody'
|
||||||
|
|
||||||
|
export interface DeleteAuthenticatorResponse extends HttpResponse {
|
||||||
|
data: Either<DeleteAuthenticatorResponseBody, HttpErrorResponseBody>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface DeleteAuthenticatorResponseBody {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
|
||||||
|
import { GenerateAuthenticatorAuthenticationOptionsResponseBody } from './GenerateAuthenticatorAuthenticationOptionsResponseBody'
|
||||||
|
|
||||||
|
export interface GenerateAuthenticatorAuthenticationOptionsResponse extends HttpResponse {
|
||||||
|
data: Either<GenerateAuthenticatorAuthenticationOptionsResponseBody, HttpErrorResponseBody>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface GenerateAuthenticatorAuthenticationOptionsResponseBody {
|
||||||
|
options: Record<string, unknown>
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
|
||||||
|
import { GenerateAuthenticatorRegistrationOptionsResponseBody } from './GenerateAuthenticatorRegistrationOptionsResponseBody'
|
||||||
|
|
||||||
|
export interface GenerateAuthenticatorRegistrationOptionsResponse extends HttpResponse {
|
||||||
|
data: Either<GenerateAuthenticatorRegistrationOptionsResponseBody, HttpErrorResponseBody>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface GenerateAuthenticatorRegistrationOptionsResponseBody {
|
||||||
|
options: Record<string, unknown>
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
|
||||||
|
import { ListAuthenticatorsResponseBody } from './ListAuthenticatorsResponseBody'
|
||||||
|
|
||||||
|
export interface ListAuthenticatorsResponse extends HttpResponse {
|
||||||
|
data: Either<ListAuthenticatorsResponseBody, HttpErrorResponseBody>
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface ListAuthenticatorsResponseBody {
|
||||||
|
authenticators: Array<{
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}>
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
|
||||||
|
import { VerifyAuthenticatorAuthenticationResponseResponseBody } from './VerifyAuthenticatorAuthenticationResponseResponseBody'
|
||||||
|
|
||||||
|
export interface VerifyAuthenticatorAuthenticationResponseResponse extends HttpResponse {
|
||||||
|
data: Either<VerifyAuthenticatorAuthenticationResponseResponseBody, HttpErrorResponseBody>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface VerifyAuthenticatorAuthenticationResponseResponseBody {
|
||||||
|
success: boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
|
||||||
|
import { VerifyAuthenticatorRegistrationResponseResponseBody } from './VerifyAuthenticatorRegistrationResponseResponseBody'
|
||||||
|
|
||||||
|
export interface VerifyAuthenticatorRegistrationResponseResponse extends HttpResponse {
|
||||||
|
data: Either<VerifyAuthenticatorRegistrationResponseResponseBody, HttpErrorResponseBody>
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface VerifyAuthenticatorRegistrationResponseResponseBody {
|
||||||
|
success: boolean
|
||||||
|
}
|
||||||
@@ -1,3 +1,17 @@
|
|||||||
|
export * from './Auth/SessionRefreshResponse'
|
||||||
|
export * from './Auth/SessionRefreshResponseBody'
|
||||||
|
export * from './Authenticator/DeleteAuthenticatorResponse'
|
||||||
|
export * from './Authenticator/DeleteAuthenticatorResponseBody'
|
||||||
|
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsResponse'
|
||||||
|
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsResponseBody'
|
||||||
|
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 './Subscription/AppleIAPConfirmResponse'
|
export * from './Subscription/AppleIAPConfirmResponse'
|
||||||
export * from './Subscription/AppleIAPConfirmResponseBody'
|
export * from './Subscription/AppleIAPConfirmResponseBody'
|
||||||
export * from './Subscription/SubscriptionInviteAcceptResponse'
|
export * from './Subscription/SubscriptionInviteAcceptResponse'
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
|
||||||
|
import {
|
||||||
|
ListAuthenticatorsRequestParams,
|
||||||
|
DeleteAuthenticatorRequestParams,
|
||||||
|
GenerateAuthenticatorRegistrationOptionsRequestParams,
|
||||||
|
VerifyAuthenticatorRegistrationResponseRequestParams,
|
||||||
|
GenerateAuthenticatorAuthenticationOptionsRequestParams,
|
||||||
|
VerifyAuthenticatorAuthenticationResponseRequestParams,
|
||||||
|
} from '../../Request'
|
||||||
|
import {
|
||||||
|
ListAuthenticatorsResponse,
|
||||||
|
DeleteAuthenticatorResponse,
|
||||||
|
GenerateAuthenticatorRegistrationOptionsResponse,
|
||||||
|
VerifyAuthenticatorRegistrationResponseResponse,
|
||||||
|
GenerateAuthenticatorAuthenticationOptionsResponse,
|
||||||
|
VerifyAuthenticatorAuthenticationResponseResponse,
|
||||||
|
} from '../../Response'
|
||||||
|
import { AuthenticatorServerInterface } from './AuthenticatorServerInterface'
|
||||||
|
import { Paths } from './Paths'
|
||||||
|
|
||||||
|
export class AuthenticatorServer implements AuthenticatorServerInterface {
|
||||||
|
constructor(private httpService: HttpServiceInterface) {}
|
||||||
|
|
||||||
|
async list(params: ListAuthenticatorsRequestParams): Promise<ListAuthenticatorsResponse> {
|
||||||
|
const response = await this.httpService.get(Paths.v1.listAuthenticators, params)
|
||||||
|
|
||||||
|
return response as ListAuthenticatorsResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(params: DeleteAuthenticatorRequestParams): Promise<DeleteAuthenticatorResponse> {
|
||||||
|
const response = await this.httpService.delete(Paths.v1.deleteAuthenticator(params.authenticatorId), params)
|
||||||
|
|
||||||
|
return response as DeleteAuthenticatorResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateRegistrationOptions(
|
||||||
|
params: GenerateAuthenticatorRegistrationOptionsRequestParams,
|
||||||
|
): Promise<GenerateAuthenticatorRegistrationOptionsResponse> {
|
||||||
|
const response = await this.httpService.get(Paths.v1.generateRegistrationOptions, params)
|
||||||
|
|
||||||
|
return response as GenerateAuthenticatorRegistrationOptionsResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async verifyRegistrationResponse(
|
||||||
|
params: VerifyAuthenticatorRegistrationResponseRequestParams,
|
||||||
|
): Promise<VerifyAuthenticatorRegistrationResponseResponse> {
|
||||||
|
const response = await this.httpService.post(Paths.v1.verifyRegistrationResponse, params)
|
||||||
|
|
||||||
|
return response as VerifyAuthenticatorRegistrationResponseResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateAuthenticationOptions(
|
||||||
|
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
|
||||||
|
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
|
||||||
|
const response = await this.httpService.get(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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import {
|
||||||
|
ListAuthenticatorsRequestParams,
|
||||||
|
DeleteAuthenticatorRequestParams,
|
||||||
|
GenerateAuthenticatorRegistrationOptionsRequestParams,
|
||||||
|
VerifyAuthenticatorRegistrationResponseRequestParams,
|
||||||
|
GenerateAuthenticatorAuthenticationOptionsRequestParams,
|
||||||
|
VerifyAuthenticatorAuthenticationResponseRequestParams,
|
||||||
|
} from '../../Request'
|
||||||
|
import {
|
||||||
|
ListAuthenticatorsResponse,
|
||||||
|
DeleteAuthenticatorResponse,
|
||||||
|
GenerateAuthenticatorRegistrationOptionsResponse,
|
||||||
|
VerifyAuthenticatorRegistrationResponseResponse,
|
||||||
|
GenerateAuthenticatorAuthenticationOptionsResponse,
|
||||||
|
VerifyAuthenticatorAuthenticationResponseResponse,
|
||||||
|
} from '../../Response'
|
||||||
|
|
||||||
|
export interface AuthenticatorServerInterface {
|
||||||
|
list(params: ListAuthenticatorsRequestParams): Promise<ListAuthenticatorsResponse>
|
||||||
|
delete(params: DeleteAuthenticatorRequestParams): Promise<DeleteAuthenticatorResponse>
|
||||||
|
generateRegistrationOptions(
|
||||||
|
params: GenerateAuthenticatorRegistrationOptionsRequestParams,
|
||||||
|
): Promise<GenerateAuthenticatorRegistrationOptionsResponse>
|
||||||
|
verifyRegistrationResponse(
|
||||||
|
params: VerifyAuthenticatorRegistrationResponseRequestParams,
|
||||||
|
): Promise<VerifyAuthenticatorRegistrationResponseResponse>
|
||||||
|
generateAuthenticationOptions(
|
||||||
|
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
|
||||||
|
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
|
||||||
|
verifyAuthenticationResponse(
|
||||||
|
params: VerifyAuthenticatorAuthenticationResponseRequestParams,
|
||||||
|
): Promise<VerifyAuthenticatorAuthenticationResponseResponse>
|
||||||
|
}
|
||||||
14
packages/api/src/Domain/Server/Authenticator/Paths.ts
Normal file
14
packages/api/src/Domain/Server/Authenticator/Paths.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const AuthenticatorPaths = {
|
||||||
|
listAuthenticators: '/v1/authenticators',
|
||||||
|
deleteAuthenticator: (authenticatorId: string) => `/v1/authenticators/${authenticatorId}`,
|
||||||
|
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 = {
|
||||||
|
v1: {
|
||||||
|
...AuthenticatorPaths,
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
export * from './Authenticator/AuthenticatorServer'
|
||||||
|
export * from './Authenticator/AuthenticatorServerInterface'
|
||||||
export * from './Subscription/SubscriptionServer'
|
export * from './Subscription/SubscriptionServer'
|
||||||
export * from './Subscription/SubscriptionServerInterface'
|
export * from './Subscription/SubscriptionServerInterface'
|
||||||
export * from './User/UserServer'
|
export * from './User/UserServer'
|
||||||
|
|||||||
@@ -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>
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ export * from './Application/ApplicationStage'
|
|||||||
export * from './Application/DeinitCallback'
|
export * from './Application/DeinitCallback'
|
||||||
export * from './Application/DeinitSource'
|
export * from './Application/DeinitSource'
|
||||||
export * from './Application/DeinitMode'
|
export * from './Application/DeinitMode'
|
||||||
|
export * from './Authenticator/AuthenticatorClientInterface'
|
||||||
|
export * from './Authenticator/AuthenticatorManager'
|
||||||
export * from './User/UserClientInterface'
|
export * from './User/UserClientInterface'
|
||||||
export * from './Application/WebApplicationInterface'
|
export * from './Application/WebApplicationInterface'
|
||||||
export * from './Backups/BackupService'
|
export * from './Backups/BackupService'
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
|
AuthenticatorApiService,
|
||||||
|
AuthenticatorApiServiceInterface,
|
||||||
|
AuthenticatorServer,
|
||||||
|
AuthenticatorServerInterface,
|
||||||
HttpService,
|
HttpService,
|
||||||
HttpServiceInterface,
|
HttpServiceInterface,
|
||||||
SubscriptionApiService,
|
SubscriptionApiService,
|
||||||
@@ -63,6 +67,8 @@ import {
|
|||||||
CredentialsChangeFunctionResponse,
|
CredentialsChangeFunctionResponse,
|
||||||
SessionStrings,
|
SessionStrings,
|
||||||
AccountEvent,
|
AccountEvent,
|
||||||
|
AuthenticatorClientInterface,
|
||||||
|
AuthenticatorManager,
|
||||||
} from '@standardnotes/services'
|
} from '@standardnotes/services'
|
||||||
import { BackupServiceInterface, FilesClientInterface } from '@standardnotes/files'
|
import { BackupServiceInterface, FilesClientInterface } from '@standardnotes/files'
|
||||||
import { ComputePrivateUsername } from '@standardnotes/encryption'
|
import { ComputePrivateUsername } from '@standardnotes/encryption'
|
||||||
@@ -159,6 +165,9 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
|||||||
private filesBackupService?: FilesBackupService
|
private filesBackupService?: FilesBackupService
|
||||||
private declare sessionStorageMapper: MapperInterface<Session, Record<string, unknown>>
|
private declare sessionStorageMapper: MapperInterface<Session, Record<string, unknown>>
|
||||||
private declare legacySessionStorageMapper: MapperInterface<LegacySession, Record<string, unknown>>
|
private declare legacySessionStorageMapper: MapperInterface<LegacySession, Record<string, unknown>>
|
||||||
|
private declare authenticatorApiService: AuthenticatorApiServiceInterface
|
||||||
|
private declare authenticatorServer: AuthenticatorServerInterface
|
||||||
|
private declare authenticatorManager: AuthenticatorClientInterface
|
||||||
|
|
||||||
private internalEventBus!: ExternalServices.InternalEventBusInterface
|
private internalEventBus!: ExternalServices.InternalEventBusInterface
|
||||||
|
|
||||||
@@ -1134,6 +1143,9 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
|||||||
this.createMutatorService()
|
this.createMutatorService()
|
||||||
this.createListedService()
|
this.createListedService()
|
||||||
this.createActionsManager()
|
this.createActionsManager()
|
||||||
|
this.createAuthenticatorServer()
|
||||||
|
this.createAuthenticatorApiService()
|
||||||
|
this.createAuthenticatorManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearServices() {
|
private clearServices() {
|
||||||
@@ -1181,6 +1193,9 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
|||||||
;(this.statusService as unknown) = undefined
|
;(this.statusService as unknown) = undefined
|
||||||
;(this.sessionStorageMapper as unknown) = undefined
|
;(this.sessionStorageMapper as unknown) = undefined
|
||||||
;(this.legacySessionStorageMapper as unknown) = undefined
|
;(this.legacySessionStorageMapper as unknown) = undefined
|
||||||
|
;(this.authenticatorApiService as unknown) = undefined
|
||||||
|
;(this.authenticatorServer as unknown) = undefined
|
||||||
|
;(this.authenticatorManager as unknown) = undefined
|
||||||
|
|
||||||
this.services = []
|
this.services = []
|
||||||
}
|
}
|
||||||
@@ -1705,4 +1720,16 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
|||||||
this.statusService = new ExternalServices.StatusService(this.internalEventBus)
|
this.statusService = new ExternalServices.StatusService(this.internalEventBus)
|
||||||
this.services.push(this.statusService)
|
this.services.push(this.statusService)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createAuthenticatorServer() {
|
||||||
|
this.authenticatorServer = new AuthenticatorServer(this.httpService)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createAuthenticatorApiService() {
|
||||||
|
this.authenticatorApiService = new AuthenticatorApiService(this.authenticatorServer)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createAuthenticatorManager() {
|
||||||
|
this.authenticatorManager = new AuthenticatorManager(this.authenticatorApiService, this.internalEventBus)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user