mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
send password history to server
This commit is contained in:
@@ -5,6 +5,7 @@ import { CardData } from './cardData';
|
||||
import { FieldData } from './fieldData';
|
||||
import { IdentityData } from './identityData';
|
||||
import { LoginData } from './loginData';
|
||||
import { PasswordHistoryData } from './passwordHistoryData';
|
||||
import { SecureNoteData } from './secureNoteData';
|
||||
|
||||
import { CipherResponse } from '../response/cipherResponse';
|
||||
@@ -28,6 +29,7 @@ export class CipherData {
|
||||
identity?: IdentityData;
|
||||
fields?: FieldData[];
|
||||
attachments?: AttachmentData[];
|
||||
passwordHistory?: PasswordHistoryData[];
|
||||
collectionIds?: string[];
|
||||
|
||||
constructor(response?: CipherResponse, userId?: string, collectionIds?: string[]) {
|
||||
@@ -83,5 +85,12 @@ export class CipherData {
|
||||
this.attachments.push(new AttachmentData(attachment));
|
||||
});
|
||||
}
|
||||
|
||||
if (response.passwordHistory != null) {
|
||||
this.passwordHistory = [];
|
||||
response.passwordHistory.forEach((ph) => {
|
||||
this.passwordHistory.push(new PasswordHistoryData(ph));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
src/models/data/passwordHistoryData.ts
Normal file
15
src/models/data/passwordHistoryData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { PasswordHistoryResponse } from '../response/passwordHistoryResponse';
|
||||
|
||||
export class PasswordHistoryData {
|
||||
password: string;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(response?: PasswordHistoryResponse) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.password = response.password;
|
||||
this.lastUsedDate = response.lastUsedDate;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import Domain from './domain';
|
||||
import { Field } from './field';
|
||||
import { Identity } from './identity';
|
||||
import { Login } from './login';
|
||||
import { Password } from './password';
|
||||
import { SecureNote } from './secureNote';
|
||||
|
||||
export class Cipher extends Domain {
|
||||
@@ -31,6 +32,7 @@ export class Cipher extends Domain {
|
||||
secureNote: SecureNote;
|
||||
attachments: Attachment[];
|
||||
fields: Field[];
|
||||
passwordHistory: Password[];
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(obj?: CipherData, alreadyEncrypted: boolean = false, localData: any = null) {
|
||||
@@ -90,6 +92,15 @@ export class Cipher extends Domain {
|
||||
} else {
|
||||
this.fields = null;
|
||||
}
|
||||
|
||||
if (obj.passwordHistory != null) {
|
||||
this.passwordHistory = [];
|
||||
obj.passwordHistory.forEach((ph) => {
|
||||
this.passwordHistory.push(new Password(ph, alreadyEncrypted));
|
||||
});
|
||||
} else {
|
||||
this.passwordHistory = null;
|
||||
}
|
||||
}
|
||||
|
||||
async decrypt(): Promise<CipherView> {
|
||||
@@ -143,6 +154,18 @@ export class Cipher extends Domain {
|
||||
model.fields = fields;
|
||||
}
|
||||
|
||||
if (this.passwordHistory != null && this.passwordHistory.length > 0) {
|
||||
const passwordHistory: any[] = [];
|
||||
await this.passwordHistory.reduce((promise, ph) => {
|
||||
return promise.then(() => {
|
||||
return ph.decrypt(orgId);
|
||||
}).then((decPh) => {
|
||||
passwordHistory.push(decPh);
|
||||
});
|
||||
}, Promise.resolve());
|
||||
model.passwordHistory = passwordHistory;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -194,6 +217,13 @@ export class Cipher extends Domain {
|
||||
c.attachments.push(attachment.toAttachmentData());
|
||||
});
|
||||
}
|
||||
|
||||
if (this.passwordHistory != null) {
|
||||
c.passwordHistory = [];
|
||||
this.passwordHistory.forEach((ph) => {
|
||||
c.passwordHistory.push(ph.toPasswordHistoryData());
|
||||
});
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export class PasswordHistory {
|
||||
export class GeneratedPasswordHistory {
|
||||
password: string;
|
||||
date: number;
|
||||
|
||||
@@ -11,6 +11,6 @@ export { Folder } from './folder';
|
||||
export { Identity } from './identity';
|
||||
export { Login } from './login';
|
||||
export { LoginUri } from './loginUri';
|
||||
export { PasswordHistory } from './passwordHistory';
|
||||
export { GeneratedPasswordHistory } from './generatedPasswordHistory';
|
||||
export { SecureNote } from './secureNote';
|
||||
export { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
39
src/models/domain/password.ts
Normal file
39
src/models/domain/password.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { PasswordHistoryData } from '../data/passwordHistoryData';
|
||||
|
||||
import { CipherString } from './cipherString';
|
||||
import Domain from './domain';
|
||||
|
||||
import { PasswordHistoryView } from '../view/passwordHistoryView';
|
||||
|
||||
export class Password extends Domain {
|
||||
password: CipherString;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(obj?: PasswordHistoryData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
password: null,
|
||||
lastUsedDate: null,
|
||||
}, alreadyEncrypted, ['lastUsedDate']);
|
||||
}
|
||||
|
||||
async decrypt(orgId: string): Promise<PasswordHistoryView> {
|
||||
const view = await this.decryptObj(new PasswordHistoryView(this), {
|
||||
password: null,
|
||||
}, orgId);
|
||||
return view;
|
||||
}
|
||||
|
||||
toPasswordHistoryData(): PasswordHistoryData {
|
||||
const ph = new PasswordHistoryData();
|
||||
ph.lastUsedDate = this.lastUsedDate;
|
||||
this.buildDataModel(this, ph, {
|
||||
password: null,
|
||||
});
|
||||
return ph;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import { IdentityApi } from '../api/identityApi';
|
||||
import { LoginApi } from '../api/loginApi';
|
||||
import { SecureNoteApi } from '../api/secureNoteApi';
|
||||
|
||||
import { PasswordHistoryRequest } from './passwordHistoryRequest';
|
||||
|
||||
export class CipherRequest {
|
||||
type: CipherType;
|
||||
folderId: string;
|
||||
@@ -20,6 +22,7 @@ export class CipherRequest {
|
||||
card: CardApi;
|
||||
identity: IdentityApi;
|
||||
fields: FieldApi[];
|
||||
passwordHistory: PasswordHistoryRequest[];
|
||||
attachments: { [id: string]: string; };
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
@@ -102,6 +105,16 @@ export class CipherRequest {
|
||||
});
|
||||
}
|
||||
|
||||
if (cipher.passwordHistory) {
|
||||
this.passwordHistory = [];
|
||||
cipher.passwordHistory.forEach((ph) => {
|
||||
this.passwordHistory.push({
|
||||
lastUsedDate: ph.lastUsedDate,
|
||||
password: ph.password ? ph.password.encryptedString : null,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (cipher.attachments) {
|
||||
this.attachments = {};
|
||||
cipher.attachments.forEach((attachment) => {
|
||||
|
||||
9
src/models/request/passwordHistoryRequest.ts
Normal file
9
src/models/request/passwordHistoryRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class PasswordHistoryRequest {
|
||||
password: string;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(response: any) {
|
||||
this.password = response.Password;
|
||||
this.lastUsedDate = response.LastUsedDate;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AttachmentResponse } from './attachmentResponse';
|
||||
import { PasswordHistoryResponse } from './passwordHistoryResponse';
|
||||
|
||||
import { CardApi } from '../api/cardApi';
|
||||
import { FieldApi } from '../api/fieldApi';
|
||||
@@ -23,6 +24,7 @@ export class CipherResponse {
|
||||
organizationUseTotp: boolean;
|
||||
revisionDate: Date;
|
||||
attachments: AttachmentResponse[];
|
||||
passwordHistory: PasswordHistoryResponse[];
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(response: any) {
|
||||
@@ -67,6 +69,13 @@ export class CipherResponse {
|
||||
});
|
||||
}
|
||||
|
||||
if (response.PasswordHistory != null) {
|
||||
this.passwordHistory = [];
|
||||
response.PasswordHistory.forEach((ph: any) => {
|
||||
this.passwordHistory.push(new PasswordHistoryResponse(ph));
|
||||
});
|
||||
}
|
||||
|
||||
if (response.CollectionIds) {
|
||||
this.collectionIds = [];
|
||||
response.CollectionIds.forEach((id: string) => {
|
||||
|
||||
9
src/models/response/passwordHistoryResponse.ts
Normal file
9
src/models/response/passwordHistoryResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class PasswordHistoryResponse {
|
||||
password: string;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(response: any) {
|
||||
this.password = response.Password;
|
||||
this.lastUsedDate = response.LastUsedDate;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { CardView } from './cardView';
|
||||
import { FieldView } from './fieldView';
|
||||
import { IdentityView } from './identityView';
|
||||
import { LoginView } from './loginView';
|
||||
import { PasswordHistoryView } from './passwordHistoryView';
|
||||
import { SecureNoteView } from './secureNoteView';
|
||||
import { View } from './view';
|
||||
|
||||
@@ -27,6 +28,7 @@ export class CipherView implements View {
|
||||
secureNote: SecureNoteView;
|
||||
attachments: AttachmentView[];
|
||||
fields: FieldView[];
|
||||
passwordHistory: PasswordHistoryView[];
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(c?: Cipher) {
|
||||
@@ -62,6 +64,10 @@ export class CipherView implements View {
|
||||
return null;
|
||||
}
|
||||
|
||||
get hasPasswordHistory(): boolean {
|
||||
return this.passwordHistory && this.passwordHistory.length > 0;
|
||||
}
|
||||
|
||||
get hasAttachments(): boolean {
|
||||
return this.attachments && this.attachments.length > 0;
|
||||
}
|
||||
|
||||
16
src/models/view/passwordHistoryView.ts
Normal file
16
src/models/view/passwordHistoryView.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { View } from './view';
|
||||
|
||||
import { Password } from '../domain/password';
|
||||
|
||||
export class PasswordHistoryView implements View {
|
||||
password: string;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(ph?: Password) {
|
||||
if (!ph) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastUsedDate = ph.lastUsedDate;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user