From c3b6baf72670dda16f6edefaee36893023c3dced Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 26 Jun 2018 15:17:14 -0400 Subject: [PATCH] add two factor apis --- src/abstractions/api.service.ts | 30 +++++++ src/models/request/twoFactorEmailRequest.ts | 8 +- .../request/twoFactorProviderRequest.ts | 7 ++ .../request/twoFactorRecoveryRequest.ts | 6 ++ .../updateTwoFactorAuthenticatorRequest.ts | 6 ++ .../request/updateTwoFactorDuoRequest.ts | 7 ++ .../request/updateTwoFactorEmailRequest.ts | 6 ++ .../request/updateTwoFactorU2fRequest.ts | 5 ++ .../request/updateTwoFactorYubioOtpRequest.ts | 10 +++ src/models/response/listResponse.ts | 10 ++- .../twoFactorAuthenticatorResponse.ts | 9 ++ src/models/response/twoFactorDuoResponse.ts | 13 +++ src/models/response/twoFactorEmailResponse.ts | 9 ++ .../response/twoFactorProviderResponse.ts | 11 +++ .../response/twoFactorRescoverResponse.ts | 7 ++ src/models/response/twoFactorU2fResponse.ts | 23 +++++ .../response/twoFactorYubiKeyResponse.ts | 19 ++++ src/services/api.service.ts | 87 +++++++++++++++++++ tslint.json | 3 +- 19 files changed, 268 insertions(+), 8 deletions(-) create mode 100644 src/models/request/twoFactorProviderRequest.ts create mode 100644 src/models/request/twoFactorRecoveryRequest.ts create mode 100644 src/models/request/updateTwoFactorAuthenticatorRequest.ts create mode 100644 src/models/request/updateTwoFactorDuoRequest.ts create mode 100644 src/models/request/updateTwoFactorEmailRequest.ts create mode 100644 src/models/request/updateTwoFactorU2fRequest.ts create mode 100644 src/models/request/updateTwoFactorYubioOtpRequest.ts create mode 100644 src/models/response/twoFactorAuthenticatorResponse.ts create mode 100644 src/models/response/twoFactorDuoResponse.ts create mode 100644 src/models/response/twoFactorEmailResponse.ts create mode 100644 src/models/response/twoFactorProviderResponse.ts create mode 100644 src/models/response/twoFactorRescoverResponse.ts create mode 100644 src/models/response/twoFactorU2fResponse.ts create mode 100644 src/models/response/twoFactorYubiKeyResponse.ts diff --git a/src/abstractions/api.service.ts b/src/abstractions/api.service.ts index 6db188686b..d6f9447b35 100644 --- a/src/abstractions/api.service.ts +++ b/src/abstractions/api.service.ts @@ -18,16 +18,31 @@ import { PasswordVerificationRequest } from '../models/request/passwordVerificat import { RegisterRequest } from '../models/request/registerRequest'; import { TokenRequest } from '../models/request/tokenRequest'; import { TwoFactorEmailRequest } from '../models/request/twoFactorEmailRequest'; +import { TwoFactorProviderRequest } from '../models/request/twoFactorProviderRequest'; +import { TwoFactorRecoveryRequest } from '../models/request/twoFactorRecoveryRequest'; import { UpdateDomainsRequest } from '../models/request/updateDomainsRequest'; import { UpdateProfileRequest } from '../models/request/updateProfileRequest'; +import { UpdateTwoFactorAuthenticatorRequest } from '../models/request/updateTwoFactorAuthenticatorRequest'; +import { UpdateTwoFactorDuoRequest } from '../models/request/updateTwoFactorDuoRequest'; +import { UpdateTwoFactorEmailRequest } from '../models/request/updateTwoFactorEmailRequest'; +import { UpdateTwoFactorU2fRequest } from '../models/request/updateTwoFactorU2fRequest'; +import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFactorYubioOtpRequest'; import { CipherResponse } from '../models/response/cipherResponse'; import { DomainsResponse } from '../models/response/domainsResponse'; import { FolderResponse } from '../models/response/folderResponse'; import { IdentityTokenResponse } from '../models/response/identityTokenResponse'; import { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse'; +import { ListResponse } from '../models/response/listResponse'; import { ProfileResponse } from '../models/response/profileResponse'; import { SyncResponse } from '../models/response/syncResponse'; +import { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse'; +import { TwoFactorDuoResponse } from '../models/response/twoFactorDuoResponse'; +import { TwoFactorEmailResponse } from '../models/response/twoFactorEmailResponse'; +import { TwoFactorProviderResponse } from '../models/response/twoFactorProviderResponse'; +import { TwoFactorRecoverResponse } from '../models/response/twoFactorRescoverResponse'; +import { TwoFactorU2fResponse } from '../models/response/twoFactorU2fResponse'; +import { TwoFactorYubiKeyResponse } from '../models/response/twoFactorYubiKeyResponse'; export abstract class ApiService { urlsSet: boolean; @@ -70,4 +85,19 @@ export abstract class ApiService { postImportDirectory: (organizationId: string, request: ImportDirectoryRequest) => Promise; getSettingsDomains: () => Promise; putSettingsDomains: (request: UpdateDomainsRequest) => Promise; + getTwoFactorProviders: () => Promise>; + getTwoFactorAuthenticator: (request: PasswordVerificationRequest) => Promise; + getTwoFactorEmail: (request: PasswordVerificationRequest) => Promise; + getTwoFactorDuo: (request: PasswordVerificationRequest) => Promise; + getTwoFactorYubiKey: (request: PasswordVerificationRequest) => Promise; + getTwoFactorU2f: (request: PasswordVerificationRequest) => Promise; + getTwoFactorRecover: (request: PasswordVerificationRequest) => Promise; + putTwoFactorAuthenticator: ( + request: UpdateTwoFactorAuthenticatorRequest) => Promise; + putTwoFactorEmail: (request: UpdateTwoFactorEmailRequest) => Promise; + putTwoFactorDuo: (request: UpdateTwoFactorDuoRequest) => Promise; + putTwoFactorYubiKey: (request: UpdateTwoFactorYubioOtpRequest) => Promise; + putTwoFactorU2f: (request: UpdateTwoFactorU2fRequest) => Promise; + putTwoFactorDisable: (request: TwoFactorProviderRequest) => Promise; + postTwoFactorRecover: (request: TwoFactorRecoveryRequest) => Promise; } diff --git a/src/models/request/twoFactorEmailRequest.ts b/src/models/request/twoFactorEmailRequest.ts index b506ccfa43..ced9288ffd 100644 --- a/src/models/request/twoFactorEmailRequest.ts +++ b/src/models/request/twoFactorEmailRequest.ts @@ -1,9 +1,11 @@ -export class TwoFactorEmailRequest { +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class TwoFactorEmailRequest extends PasswordVerificationRequest { email: string; - masterPasswordHash: string; constructor(email: string, masterPasswordHash: string) { - this.email = email; + super(); this.masterPasswordHash = masterPasswordHash; + this.email = email; } } diff --git a/src/models/request/twoFactorProviderRequest.ts b/src/models/request/twoFactorProviderRequest.ts new file mode 100644 index 0000000000..23a47f9e0e --- /dev/null +++ b/src/models/request/twoFactorProviderRequest.ts @@ -0,0 +1,7 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +import { TwoFactorProviderType } from '../../enums/twoFactorProviderType'; + +export class TwoFactorProviderRequest extends PasswordVerificationRequest { + type: TwoFactorProviderType; +} diff --git a/src/models/request/twoFactorRecoveryRequest.ts b/src/models/request/twoFactorRecoveryRequest.ts new file mode 100644 index 0000000000..ddd7c59ad7 --- /dev/null +++ b/src/models/request/twoFactorRecoveryRequest.ts @@ -0,0 +1,6 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class TwoFactorRecoveryRequest extends PasswordVerificationRequest { + recoveryCode: string; + email: string; +} diff --git a/src/models/request/updateTwoFactorAuthenticatorRequest.ts b/src/models/request/updateTwoFactorAuthenticatorRequest.ts new file mode 100644 index 0000000000..2dd6a96ac9 --- /dev/null +++ b/src/models/request/updateTwoFactorAuthenticatorRequest.ts @@ -0,0 +1,6 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class UpdateTwoFactorAuthenticatorRequest extends PasswordVerificationRequest { + token: string; + key: string; +} diff --git a/src/models/request/updateTwoFactorDuoRequest.ts b/src/models/request/updateTwoFactorDuoRequest.ts new file mode 100644 index 0000000000..1777f39ae8 --- /dev/null +++ b/src/models/request/updateTwoFactorDuoRequest.ts @@ -0,0 +1,7 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class UpdateTwoFactorDuoRequest extends PasswordVerificationRequest { + integrationKey: string; + secretKey: string; + host: string; +} diff --git a/src/models/request/updateTwoFactorEmailRequest.ts b/src/models/request/updateTwoFactorEmailRequest.ts new file mode 100644 index 0000000000..dabeb7d9d3 --- /dev/null +++ b/src/models/request/updateTwoFactorEmailRequest.ts @@ -0,0 +1,6 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class UpdateTwoFactorEmailRequest extends PasswordVerificationRequest { + token: string; + email: string; +} diff --git a/src/models/request/updateTwoFactorU2fRequest.ts b/src/models/request/updateTwoFactorU2fRequest.ts new file mode 100644 index 0000000000..a0e959bd18 --- /dev/null +++ b/src/models/request/updateTwoFactorU2fRequest.ts @@ -0,0 +1,5 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class UpdateTwoFactorU2fRequest extends PasswordVerificationRequest { + deviceResponse: string; +} diff --git a/src/models/request/updateTwoFactorYubioOtpRequest.ts b/src/models/request/updateTwoFactorYubioOtpRequest.ts new file mode 100644 index 0000000000..4ad0696f0c --- /dev/null +++ b/src/models/request/updateTwoFactorYubioOtpRequest.ts @@ -0,0 +1,10 @@ +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class UpdateTwoFactorYubioOtpRequest extends PasswordVerificationRequest { + key1: string; + key2: string; + key3: string; + key4: string; + key5: string; + nfc: boolean; +} diff --git a/src/models/response/listResponse.ts b/src/models/response/listResponse.ts index 4a9715c39c..84c2c11632 100644 --- a/src/models/response/listResponse.ts +++ b/src/models/response/listResponse.ts @@ -1,7 +1,9 @@ -export class ListResponse { - data: any; +export class ListResponse { + data: T[]; + continuationToken: string; - constructor(data: any) { - this.data = data; + constructor(response: any, t: new (dataResponse: any) => T) { + this.data = response.Data.map((dr) => new t(dr)); + this.continuationToken = response.ContinuationToken; } } diff --git a/src/models/response/twoFactorAuthenticatorResponse.ts b/src/models/response/twoFactorAuthenticatorResponse.ts new file mode 100644 index 0000000000..f84509bd93 --- /dev/null +++ b/src/models/response/twoFactorAuthenticatorResponse.ts @@ -0,0 +1,9 @@ +export class TwoFactorAuthenticatorResponse { + enabled: boolean; + key: string; + + constructor(response: any) { + this.enabled = response.Enabled; + this.key = response.Key; + } +} diff --git a/src/models/response/twoFactorDuoResponse.ts b/src/models/response/twoFactorDuoResponse.ts new file mode 100644 index 0000000000..a72b32b364 --- /dev/null +++ b/src/models/response/twoFactorDuoResponse.ts @@ -0,0 +1,13 @@ +export class TwoFactorDuoResponse { + enabled: boolean; + host: string; + secretKey: string; + integrationKey: string; + + constructor(response: any) { + this.enabled = response.Enabled; + this.host = response.Host; + this.secretKey = response.SecretKey; + this.integrationKey = response.IntegrationKey; + } +} diff --git a/src/models/response/twoFactorEmailResponse.ts b/src/models/response/twoFactorEmailResponse.ts new file mode 100644 index 0000000000..eb8840a6ec --- /dev/null +++ b/src/models/response/twoFactorEmailResponse.ts @@ -0,0 +1,9 @@ +export class TwoFactorEmailResponse { + enabled: boolean; + email: string; + + constructor(response: any) { + this.enabled = response.Enabled; + this.email = response.Email; + } +} diff --git a/src/models/response/twoFactorProviderResponse.ts b/src/models/response/twoFactorProviderResponse.ts new file mode 100644 index 0000000000..ff834f9a25 --- /dev/null +++ b/src/models/response/twoFactorProviderResponse.ts @@ -0,0 +1,11 @@ +import { TwoFactorProviderType } from '../../enums/twoFactorProviderType'; + +export class TwoFactorProviderResponse { + enabled: boolean; + type: TwoFactorProviderType; + + constructor(response: any) { + this.enabled = response.Enabled; + this.type = response.Type; + } +} diff --git a/src/models/response/twoFactorRescoverResponse.ts b/src/models/response/twoFactorRescoverResponse.ts new file mode 100644 index 0000000000..0f73778083 --- /dev/null +++ b/src/models/response/twoFactorRescoverResponse.ts @@ -0,0 +1,7 @@ +export class TwoFactorRecoverResponse { + code: string; + + constructor(response: any) { + this.code = response.Code; + } +} diff --git a/src/models/response/twoFactorU2fResponse.ts b/src/models/response/twoFactorU2fResponse.ts new file mode 100644 index 0000000000..2c98c48fa8 --- /dev/null +++ b/src/models/response/twoFactorU2fResponse.ts @@ -0,0 +1,23 @@ +export class TwoFactorU2fResponse { + enabled: boolean; + challenge: Challenge; + + constructor(response: any) { + this.enabled = response.Enabled; + this.challenge = new Challenge(response.Challenge); + } +} + +class Challenge { + userId: string; + appId: string; + challenge: string; + version: string; + + constructor(response: any) { + this.userId = response.UserId; + this.appId = response.AppId; + this.challenge = response.Challenge; + this.version = response.Version; + } +} diff --git a/src/models/response/twoFactorYubiKeyResponse.ts b/src/models/response/twoFactorYubiKeyResponse.ts new file mode 100644 index 0000000000..454d4b9919 --- /dev/null +++ b/src/models/response/twoFactorYubiKeyResponse.ts @@ -0,0 +1,19 @@ +export class TwoFactorYubiKeyResponse { + enabled: boolean; + key1: string; + key2: string; + key3: string; + key4: string; + key5: string; + nfc: boolean; + + constructor(response: any) { + this.enabled = response.Enabled; + this.key1 = response.Key1; + this.key2 = response.Key2; + this.key3 = response.Key3; + this.key4 = response.Key4; + this.key5 = response.Key5; + this.nfc = response.Nfc; + } +} diff --git a/src/services/api.service.ts b/src/services/api.service.ts index cf8fafe11a..75b23c9ca7 100644 --- a/src/services/api.service.ts +++ b/src/services/api.service.ts @@ -24,8 +24,15 @@ import { PasswordVerificationRequest } from '../models/request/passwordVerificat import { RegisterRequest } from '../models/request/registerRequest'; import { TokenRequest } from '../models/request/tokenRequest'; import { TwoFactorEmailRequest } from '../models/request/twoFactorEmailRequest'; +import { TwoFactorProviderRequest } from '../models/request/twoFactorProviderRequest'; +import { TwoFactorRecoveryRequest } from '../models/request/twoFactorRecoveryRequest'; import { UpdateDomainsRequest } from '../models/request/updateDomainsRequest'; import { UpdateProfileRequest } from '../models/request/updateProfileRequest'; +import { UpdateTwoFactorAuthenticatorRequest } from '../models/request/updateTwoFactorAuthenticatorRequest'; +import { UpdateTwoFactorDuoRequest } from '../models/request/updateTwoFactorDuoRequest'; +import { UpdateTwoFactorEmailRequest } from '../models/request/updateTwoFactorEmailRequest'; +import { UpdateTwoFactorU2fRequest } from '../models/request/updateTwoFactorU2fRequest'; +import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFactorYubioOtpRequest'; import { CipherResponse } from '../models/response/cipherResponse'; import { DomainsResponse } from '../models/response/domainsResponse'; @@ -33,8 +40,16 @@ import { ErrorResponse } from '../models/response/errorResponse'; import { FolderResponse } from '../models/response/folderResponse'; import { IdentityTokenResponse } from '../models/response/identityTokenResponse'; import { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse'; +import { ListResponse } from '../models/response/listResponse'; import { ProfileResponse } from '../models/response/profileResponse'; import { SyncResponse } from '../models/response/syncResponse'; +import { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse'; +import { TwoFactorDuoResponse } from '../models/response/twoFactorDuoResponse'; +import { TwoFactorEmailResponse } from '../models/response/twoFactorEmailResponse'; +import { TwoFactorProviderResponse } from '../models/response/twoFactorProviderResponse'; +import { TwoFactorRecoverResponse } from '../models/response/twoFactorRescoverResponse'; +import { TwoFactorU2fResponse } from '../models/response/twoFactorU2fResponse'; +import { TwoFactorYubiKeyResponse } from '../models/response/twoFactorYubiKeyResponse'; export class ApiService implements ApiServiceAbstraction { urlsSet: boolean = false; @@ -280,6 +295,78 @@ export class ApiService implements ApiServiceAbstraction { return new DomainsResponse(r); } + // Two-factor + + async getTwoFactorProviders(): Promise> { + const r = await this.send('GET', '/two-factor', null, true, true); + return new ListResponse(r, TwoFactorProviderResponse); + } + + async getTwoFactorAuthenticator(request: PasswordVerificationRequest): Promise { + const r = await this.send('POST', '/two-factor/get-authenticator', request, true, true); + return new TwoFactorAuthenticatorResponse(r); + } + + async getTwoFactorEmail(request: PasswordVerificationRequest): Promise { + const r = await this.send('POST', '/two-factor/get-email', request, true, true); + return new TwoFactorEmailResponse(r); + } + + async getTwoFactorDuo(request: PasswordVerificationRequest): Promise { + const r = await this.send('POST', '/two-factor/get-duo', request, true, true); + return new TwoFactorDuoResponse(r); + } + + async getTwoFactorYubiKey(request: PasswordVerificationRequest): Promise { + const r = await this.send('POST', '/two-factor/get-yubikey', request, true, true); + return new TwoFactorYubiKeyResponse(r); + } + + async getTwoFactorU2f(request: PasswordVerificationRequest): Promise { + const r = await this.send('POST', '/two-factor/get-u2f', request, true, true); + return new TwoFactorU2fResponse(r); + } + + async getTwoFactorRecover(request: PasswordVerificationRequest): Promise { + const r = await this.send('POST', '/two-factor/get-recover', request, true, true); + return new TwoFactorRecoverResponse(r); + } + + async putTwoFactorAuthenticator( + request: UpdateTwoFactorAuthenticatorRequest): Promise { + const r = await this.send('PUT', '/two-factor/authenticator', request, true, true); + return new TwoFactorAuthenticatorResponse(r); + } + + async putTwoFactorEmail(request: UpdateTwoFactorEmailRequest): Promise { + const r = await this.send('PUT', '/two-factor/email', request, true, true); + return new TwoFactorEmailResponse(r); + } + + async putTwoFactorDuo(request: UpdateTwoFactorDuoRequest): Promise { + const r = await this.send('PUT', '/two-factor/duo', request, true, true); + return new TwoFactorDuoResponse(r); + } + + async putTwoFactorYubiKey(request: UpdateTwoFactorYubioOtpRequest): Promise { + const r = await this.send('PUT', '/two-factor/yubikey', request, true, true); + return new TwoFactorYubiKeyResponse(r); + } + + async putTwoFactorU2f(request: UpdateTwoFactorU2fRequest): Promise { + const r = await this.send('PUT', '/two-factor/u2f', request, true, true); + return new TwoFactorU2fResponse(r); + } + + async putTwoFactorDisable(request: TwoFactorProviderRequest): Promise { + const r = await this.send('PUT', '/two-factor/disable', request, true, true); + return new TwoFactorProviderResponse(r); + } + + postTwoFactorRecover(request: TwoFactorRecoveryRequest): Promise { + return this.send('POST', '/two-factor/recover', request, false, false); + } + // Helpers private async send(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body: any, diff --git a/tslint.json b/tslint.json index b6d5571669..7e4320f723 100644 --- a/tslint.json +++ b/tslint.json @@ -48,6 +48,7 @@ "check-preblock", "check-separator", "check-type" - ] + ], + "max-classes-per-file": false } }