From 2e486d5a7ce5422f705a398f23a78a46c9a9d42d Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 21 Jun 2018 17:15:43 -0400 Subject: [PATCH] more apis for account settings --- src/abstractions/api.service.ts | 4 ++ src/models/request/emailRequest.ts | 6 +- src/models/request/emailTokenRequest.ts | 4 +- src/models/request/passwordRequest.ts | 5 +- .../request/passwordVerificationRequest.ts | 3 + src/services/api.service.ts | 68 ++++++++++++++++++- 6 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/models/request/passwordVerificationRequest.ts diff --git a/src/abstractions/api.service.ts b/src/abstractions/api.service.ts index 150e4eee75..4267fbbdf2 100644 --- a/src/abstractions/api.service.ts +++ b/src/abstractions/api.service.ts @@ -12,6 +12,7 @@ import { FolderRequest } from '../models/request/folderRequest'; import { ImportDirectoryRequest } from '../models/request/importDirectoryRequest'; import { PasswordHintRequest } from '../models/request/passwordHintRequest'; import { PasswordRequest } from '../models/request/passwordRequest'; +import { PasswordVerificationRequest } from '../models/request/passwordVerificationRequest'; import { RegisterRequest } from '../models/request/registerRequest'; import { TokenRequest } from '../models/request/tokenRequest'; import { TwoFactorEmailRequest } from '../models/request/twoFactorEmailRequest'; @@ -38,6 +39,8 @@ export abstract class ApiService { postEmailToken: (request: EmailTokenRequest) => Promise; postEmail: (request: EmailRequest) => Promise; postPassword: (request: PasswordRequest) => Promise; + postSecurityStamp: (request: PasswordVerificationRequest) => Promise; + postDeleteAccount: (request: PasswordVerificationRequest) => Promise; getAccountRevisionDate: () => Promise; postPasswordHint: (request: PasswordHintRequest) => Promise; postRegister: (request: RegisterRequest) => Promise; @@ -52,6 +55,7 @@ export abstract class ApiService { putShareCipher: (id: string, request: CipherShareRequest) => Promise; putShareCiphers: (request: CipherBulkShareRequest) => Promise; putCipherCollections: (id: string, request: CipherCollectionsRequest) => Promise; + postPurgeCiphers: (request: PasswordVerificationRequest) => Promise; postCipherAttachment: (id: string, data: FormData) => Promise; deleteCipherAttachment: (id: string, attachmentId: string) => Promise; postShareCipherAttachment: (id: string, attachmentId: string, data: FormData, diff --git a/src/models/request/emailRequest.ts b/src/models/request/emailRequest.ts index da9e6f7829..a2172a1efa 100644 --- a/src/models/request/emailRequest.ts +++ b/src/models/request/emailRequest.ts @@ -1,6 +1,6 @@ -export class EmailRequest { - newEmail: string; - masterPasswordHash: string; +import { EmailTokenRequest } from './emailTokenRequest'; + +export class EmailRequest extends EmailTokenRequest { newMasterPasswordHash: string; token: string; key: string; diff --git a/src/models/request/emailTokenRequest.ts b/src/models/request/emailTokenRequest.ts index 98235680cf..3e74669d4c 100644 --- a/src/models/request/emailTokenRequest.ts +++ b/src/models/request/emailTokenRequest.ts @@ -1,4 +1,6 @@ -export class EmailTokenRequest { +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class EmailTokenRequest extends PasswordVerificationRequest { newEmail: string; masterPasswordHash: string; } diff --git a/src/models/request/passwordRequest.ts b/src/models/request/passwordRequest.ts index 5e79e83d14..4d877da6d4 100644 --- a/src/models/request/passwordRequest.ts +++ b/src/models/request/passwordRequest.ts @@ -1,5 +1,6 @@ -export class PasswordRequest { - masterPasswordHash: string; +import { PasswordVerificationRequest } from './passwordVerificationRequest'; + +export class PasswordRequest extends PasswordVerificationRequest { newMasterPasswordHash: string; key: string; } diff --git a/src/models/request/passwordVerificationRequest.ts b/src/models/request/passwordVerificationRequest.ts new file mode 100644 index 0000000000..f9a038ac15 --- /dev/null +++ b/src/models/request/passwordVerificationRequest.ts @@ -0,0 +1,3 @@ +export class PasswordVerificationRequest { + masterPasswordHash: string; +} diff --git a/src/services/api.service.ts b/src/services/api.service.ts index a52b00a3b2..409dc21317 100644 --- a/src/services/api.service.ts +++ b/src/services/api.service.ts @@ -18,6 +18,7 @@ import { FolderRequest } from '../models/request/folderRequest'; import { ImportDirectoryRequest } from '../models/request/importDirectoryRequest'; import { PasswordHintRequest } from '../models/request/passwordHintRequest'; import { PasswordRequest } from '../models/request/passwordRequest'; +import { PasswordVerificationRequest } from '../models/request/passwordVerificationRequest'; import { RegisterRequest } from '../models/request/registerRequest'; import { TokenRequest } from '../models/request/tokenRequest'; import { TwoFactorEmailRequest } from '../models/request/twoFactorEmailRequest'; @@ -82,8 +83,8 @@ export class ApiService implements ApiServiceAbstraction { // Production if (this.isWebClient) { - this.apiBaseUrl = 'https://vault.bitwarden.com/api'; - this.identityBaseUrl = 'https://vault.bitwarden.com/identity'; + this.apiBaseUrl = 'https://api.bitwarden.com'; + this.identityBaseUrl = 'https://identity.bitwarden.com'; } else { this.apiBaseUrl = 'https://api.bitwarden.com'; this.identityBaseUrl = 'https://identity.bitwarden.com'; @@ -263,6 +264,48 @@ export class ApiService implements ApiServiceAbstraction { } } + async postSecurityStamp(request: PasswordVerificationRequest): Promise { + const authHeader = await this.handleTokenState(); + const response = await fetch(new Request(this.apiBaseUrl + '/accounts/security-stamp', { + body: JSON.stringify(request), + cache: 'no-cache', + credentials: this.getCredentials(), + headers: new Headers({ + 'Accept': 'application/json', + 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': authHeader, + 'Device-Type': this.deviceType, + }), + method: 'POST', + })); + + if (response.status !== 200) { + const error = await this.handleError(response, false); + return Promise.reject(error); + } + } + + async postDeleteAccount(request: PasswordVerificationRequest): Promise { + const authHeader = await this.handleTokenState(); + const response = await fetch(new Request(this.apiBaseUrl + '/accounts/delete', { + body: JSON.stringify(request), + cache: 'no-cache', + credentials: this.getCredentials(), + headers: new Headers({ + 'Accept': 'application/json', + 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': authHeader, + 'Device-Type': this.deviceType, + }), + method: 'POST', + })); + + if (response.status !== 200) { + const error = await this.handleError(response, false); + return Promise.reject(error); + } + } + async getAccountRevisionDate(): Promise { const authHeader = await this.handleTokenState(); const response = await fetch(new Request(this.apiBaseUrl + '/accounts/revision-date', { @@ -560,6 +603,27 @@ export class ApiService implements ApiServiceAbstraction { } } + async postPurgeCiphers(request: PasswordVerificationRequest): Promise { + const authHeader = await this.handleTokenState(); + const response = await fetch(new Request(this.apiBaseUrl + '/ciphers/purge', { + body: JSON.stringify(request), + cache: 'no-cache', + credentials: this.getCredentials(), + headers: new Headers({ + 'Accept': 'application/json', + 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': authHeader, + 'Device-Type': this.deviceType, + }), + method: 'POST', + })); + + if (response.status !== 200) { + const error = await this.handleError(response, false); + return Promise.reject(error); + } + } + // Attachments APIs async postCipherAttachment(id: string, data: FormData): Promise {