mirror of
https://github.com/bitwarden/jslib
synced 2025-12-15 07:43:45 +00:00
Split jslib into multiple modules (#363)
* Split jslib into multiple modules
This commit is contained in:
23
common/src/models/api/cardApi.ts
Normal file
23
common/src/models/api/cardApi.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
export class CardApi extends BaseResponse {
|
||||
cardholderName: string;
|
||||
brand: string;
|
||||
number: string;
|
||||
expMonth: string;
|
||||
expYear: string;
|
||||
code: string;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.cardholderName = this.getResponseProperty('CardholderName');
|
||||
this.brand = this.getResponseProperty('Brand');
|
||||
this.number = this.getResponseProperty('Number');
|
||||
this.expMonth = this.getResponseProperty('ExpMonth');
|
||||
this.expYear = this.getResponseProperty('ExpYear');
|
||||
this.code = this.getResponseProperty('Code');
|
||||
}
|
||||
}
|
||||
19
common/src/models/api/fieldApi.ts
Normal file
19
common/src/models/api/fieldApi.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
import { FieldType } from '../../enums/fieldType';
|
||||
|
||||
export class FieldApi extends BaseResponse {
|
||||
name: string;
|
||||
value: string;
|
||||
type: FieldType;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.type = this.getResponseProperty('Type');
|
||||
this.name = this.getResponseProperty('Name');
|
||||
this.value = this.getResponseProperty('Value');
|
||||
}
|
||||
}
|
||||
47
common/src/models/api/identityApi.ts
Normal file
47
common/src/models/api/identityApi.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
export class IdentityApi extends BaseResponse {
|
||||
title: string;
|
||||
firstName: string;
|
||||
middleName: string;
|
||||
lastName: string;
|
||||
address1: string;
|
||||
address2: string;
|
||||
address3: string;
|
||||
city: string;
|
||||
state: string;
|
||||
postalCode: string;
|
||||
country: string;
|
||||
company: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
ssn: string;
|
||||
username: string;
|
||||
passportNumber: string;
|
||||
licenseNumber: string;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.title = this.getResponseProperty('Title');
|
||||
this.firstName = this.getResponseProperty('FirstName');
|
||||
this.middleName = this.getResponseProperty('MiddleName');
|
||||
this.lastName = this.getResponseProperty('LastName');
|
||||
this.address1 = this.getResponseProperty('Address1');
|
||||
this.address2 = this.getResponseProperty('Address2');
|
||||
this.address3 = this.getResponseProperty('Address3');
|
||||
this.city = this.getResponseProperty('City');
|
||||
this.state = this.getResponseProperty('State');
|
||||
this.postalCode = this.getResponseProperty('PostalCode');
|
||||
this.country = this.getResponseProperty('Country');
|
||||
this.company = this.getResponseProperty('Company');
|
||||
this.email = this.getResponseProperty('Email');
|
||||
this.phone = this.getResponseProperty('Phone');
|
||||
this.ssn = this.getResponseProperty('SSN');
|
||||
this.username = this.getResponseProperty('Username');
|
||||
this.passportNumber = this.getResponseProperty('PassportNumber');
|
||||
this.licenseNumber = this.getResponseProperty('LicenseNumber');
|
||||
}
|
||||
}
|
||||
29
common/src/models/api/loginApi.ts
Normal file
29
common/src/models/api/loginApi.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
import { LoginUriApi } from './loginUriApi';
|
||||
|
||||
export class LoginApi extends BaseResponse {
|
||||
uris: LoginUriApi[];
|
||||
username: string;
|
||||
password: string;
|
||||
passwordRevisionDate: string;
|
||||
totp: string;
|
||||
autofillOnPageLoad: boolean;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.username = this.getResponseProperty('Username');
|
||||
this.password = this.getResponseProperty('Password');
|
||||
this.passwordRevisionDate = this.getResponseProperty('PasswordRevisionDate');
|
||||
this.totp = this.getResponseProperty('Totp');
|
||||
this.autofillOnPageLoad = this.getResponseProperty('AutofillOnPageLoad');
|
||||
|
||||
const uris = this.getResponseProperty('Uris');
|
||||
if (uris != null) {
|
||||
this.uris = uris.map((u: any) => new LoginUriApi(u));
|
||||
}
|
||||
}
|
||||
}
|
||||
18
common/src/models/api/loginUriApi.ts
Normal file
18
common/src/models/api/loginUriApi.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
import { UriMatchType } from '../../enums/uriMatchType';
|
||||
|
||||
export class LoginUriApi extends BaseResponse {
|
||||
uri: string;
|
||||
match: UriMatchType = null;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.uri = this.getResponseProperty('Uri');
|
||||
const match = this.getResponseProperty('Match');
|
||||
this.match = match != null ? match : null;
|
||||
}
|
||||
}
|
||||
35
common/src/models/api/permissionsApi.ts
Normal file
35
common/src/models/api/permissionsApi.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
export class PermissionsApi extends BaseResponse {
|
||||
accessBusinessPortal: boolean;
|
||||
accessEventLogs: boolean;
|
||||
accessImportExport: boolean;
|
||||
accessReports: boolean;
|
||||
manageAllCollections: boolean;
|
||||
manageAssignedCollections: boolean;
|
||||
manageCiphers: boolean;
|
||||
manageGroups: boolean;
|
||||
manageSso: boolean;
|
||||
managePolicies: boolean;
|
||||
manageUsers: boolean;
|
||||
manageResetPassword: boolean;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return this;
|
||||
}
|
||||
this.accessBusinessPortal = this.getResponseProperty('AccessBusinessPortal');
|
||||
this.accessEventLogs = this.getResponseProperty('AccessEventLogs');
|
||||
this.accessImportExport = this.getResponseProperty('AccessImportExport');
|
||||
this.accessReports = this.getResponseProperty('AccessReports');
|
||||
this.manageAllCollections = this.getResponseProperty('ManageAllCollections');
|
||||
this.manageAssignedCollections = this.getResponseProperty('ManageAssignedCollections');
|
||||
this.manageCiphers = this.getResponseProperty('ManageCiphers');
|
||||
this.manageGroups = this.getResponseProperty('ManageGroups');
|
||||
this.manageSso = this.getResponseProperty('ManageSso');
|
||||
this.managePolicies = this.getResponseProperty('ManagePolicies');
|
||||
this.manageUsers = this.getResponseProperty('ManageUsers');
|
||||
this.manageResetPassword = this.getResponseProperty('ManageResetPassword');
|
||||
}
|
||||
}
|
||||
15
common/src/models/api/secureNoteApi.ts
Normal file
15
common/src/models/api/secureNoteApi.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
import { SecureNoteType } from '../../enums/secureNoteType';
|
||||
|
||||
export class SecureNoteApi extends BaseResponse {
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.type = this.getResponseProperty('Type');
|
||||
}
|
||||
}
|
||||
21
common/src/models/api/sendFileApi.ts
Normal file
21
common/src/models/api/sendFileApi.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
export class SendFileApi extends BaseResponse {
|
||||
id: string;
|
||||
fileName: string;
|
||||
key: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.id = this.getResponseProperty('Id');
|
||||
this.fileName = this.getResponseProperty('FileName');
|
||||
this.key = this.getResponseProperty('Key');
|
||||
this.size = this.getResponseProperty('Size');
|
||||
this.sizeName = this.getResponseProperty('SizeName');
|
||||
}
|
||||
}
|
||||
15
common/src/models/api/sendTextApi.ts
Normal file
15
common/src/models/api/sendTextApi.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { BaseResponse } from '../response/baseResponse';
|
||||
|
||||
export class SendTextApi extends BaseResponse {
|
||||
text: string;
|
||||
hidden: boolean;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.text = this.getResponseProperty('Text');
|
||||
this.hidden = this.getResponseProperty('Hidden') || false;
|
||||
}
|
||||
}
|
||||
22
common/src/models/data/attachmentData.ts
Normal file
22
common/src/models/data/attachmentData.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { AttachmentResponse } from '../response/attachmentResponse';
|
||||
|
||||
export class AttachmentData {
|
||||
id: string;
|
||||
url: string;
|
||||
fileName: string;
|
||||
key: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
|
||||
constructor(response?: AttachmentResponse) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
this.id = response.id;
|
||||
this.url = response.url;
|
||||
this.fileName = response.fileName;
|
||||
this.key = response.key;
|
||||
this.size = response.size;
|
||||
this.sizeName = response.sizeName;
|
||||
}
|
||||
}
|
||||
23
common/src/models/data/cardData.ts
Normal file
23
common/src/models/data/cardData.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { CardApi } from '../api/cardApi';
|
||||
|
||||
export class CardData {
|
||||
cardholderName: string;
|
||||
brand: string;
|
||||
number: string;
|
||||
expMonth: string;
|
||||
expYear: string;
|
||||
code: string;
|
||||
|
||||
constructor(data?: CardApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cardholderName = data.cardholderName;
|
||||
this.brand = data.brand;
|
||||
this.number = data.number;
|
||||
this.expMonth = data.expMonth;
|
||||
this.expYear = data.expYear;
|
||||
this.code = data.code;
|
||||
}
|
||||
}
|
||||
87
common/src/models/data/cipherData.ts
Normal file
87
common/src/models/data/cipherData.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { CipherRepromptType } from '../../enums/cipherRepromptType';
|
||||
import { CipherType } from '../../enums/cipherType';
|
||||
|
||||
import { AttachmentData } from './attachmentData';
|
||||
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';
|
||||
|
||||
export class CipherData {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
folderId: string;
|
||||
userId: string;
|
||||
edit: boolean;
|
||||
viewPassword: boolean;
|
||||
organizationUseTotp: boolean;
|
||||
favorite: boolean;
|
||||
revisionDate: string;
|
||||
type: CipherType;
|
||||
sizeName: string;
|
||||
name: string;
|
||||
notes: string;
|
||||
login?: LoginData;
|
||||
secureNote?: SecureNoteData;
|
||||
card?: CardData;
|
||||
identity?: IdentityData;
|
||||
fields?: FieldData[];
|
||||
attachments?: AttachmentData[];
|
||||
passwordHistory?: PasswordHistoryData[];
|
||||
collectionIds?: string[];
|
||||
deletedDate: string;
|
||||
reprompt: CipherRepromptType;
|
||||
|
||||
constructor(response?: CipherResponse, userId?: string, collectionIds?: string[]) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = response.id;
|
||||
this.organizationId = response.organizationId;
|
||||
this.folderId = response.folderId;
|
||||
this.userId = userId;
|
||||
this.edit = response.edit;
|
||||
this.viewPassword = response.viewPassword;
|
||||
this.organizationUseTotp = response.organizationUseTotp;
|
||||
this.favorite = response.favorite;
|
||||
this.revisionDate = response.revisionDate;
|
||||
this.type = response.type;
|
||||
this.name = response.name;
|
||||
this.notes = response.notes;
|
||||
this.collectionIds = collectionIds != null ? collectionIds : response.collectionIds;
|
||||
this.deletedDate = response.deletedDate;
|
||||
this.reprompt = response.reprompt;
|
||||
|
||||
switch (this.type) {
|
||||
case CipherType.Login:
|
||||
this.login = new LoginData(response.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
this.secureNote = new SecureNoteData(response.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
this.card = new CardData(response.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
this.identity = new IdentityData(response.identity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (response.fields != null) {
|
||||
this.fields = response.fields.map(f => new FieldData(f));
|
||||
}
|
||||
if (response.attachments != null) {
|
||||
this.attachments = response.attachments.map(a => new AttachmentData(a));
|
||||
}
|
||||
if (response.passwordHistory != null) {
|
||||
this.passwordHistory = response.passwordHistory.map(ph => new PasswordHistoryData(ph));
|
||||
}
|
||||
}
|
||||
}
|
||||
17
common/src/models/data/collectionData.ts
Normal file
17
common/src/models/data/collectionData.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { CollectionDetailsResponse } from '../response/collectionResponse';
|
||||
|
||||
export class CollectionData {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
name: string;
|
||||
externalId: string;
|
||||
readOnly: boolean;
|
||||
|
||||
constructor(response: CollectionDetailsResponse) {
|
||||
this.id = response.id;
|
||||
this.organizationId = response.organizationId;
|
||||
this.name = response.name;
|
||||
this.externalId = response.externalId;
|
||||
this.readOnly = response.readOnly;
|
||||
}
|
||||
}
|
||||
7
common/src/models/data/eventData.ts
Normal file
7
common/src/models/data/eventData.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { EventType } from '../../enums/eventType';
|
||||
|
||||
export class EventData {
|
||||
type: EventType;
|
||||
cipherId: string;
|
||||
date: string;
|
||||
}
|
||||
18
common/src/models/data/fieldData.ts
Normal file
18
common/src/models/data/fieldData.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { FieldType } from '../../enums/fieldType';
|
||||
|
||||
import { FieldApi } from '../api/fieldApi';
|
||||
|
||||
export class FieldData {
|
||||
type: FieldType;
|
||||
name: string;
|
||||
value: string;
|
||||
|
||||
constructor(response?: FieldApi) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
this.type = response.type;
|
||||
this.name = response.name;
|
||||
this.value = response.value;
|
||||
}
|
||||
}
|
||||
15
common/src/models/data/folderData.ts
Normal file
15
common/src/models/data/folderData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { FolderResponse } from '../response/folderResponse';
|
||||
|
||||
export class FolderData {
|
||||
id: string;
|
||||
userId: string;
|
||||
name: string;
|
||||
revisionDate: string;
|
||||
|
||||
constructor(response: FolderResponse, userId: string) {
|
||||
this.userId = userId;
|
||||
this.name = response.name;
|
||||
this.id = response.id;
|
||||
this.revisionDate = response.revisionDate;
|
||||
}
|
||||
}
|
||||
47
common/src/models/data/identityData.ts
Normal file
47
common/src/models/data/identityData.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { IdentityApi } from '../api/identityApi';
|
||||
|
||||
export class IdentityData {
|
||||
title: string;
|
||||
firstName: string;
|
||||
middleName: string;
|
||||
lastName: string;
|
||||
address1: string;
|
||||
address2: string;
|
||||
address3: string;
|
||||
city: string;
|
||||
state: string;
|
||||
postalCode: string;
|
||||
country: string;
|
||||
company: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
ssn: string;
|
||||
username: string;
|
||||
passportNumber: string;
|
||||
licenseNumber: string;
|
||||
|
||||
constructor(data?: IdentityApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.title = data.title;
|
||||
this.firstName = data.firstName;
|
||||
this.middleName = data.middleName;
|
||||
this.lastName = data.lastName;
|
||||
this.address1 = data.address1;
|
||||
this.address2 = data.address2;
|
||||
this.address3 = data.address3;
|
||||
this.city = data.city;
|
||||
this.state = data.state;
|
||||
this.postalCode = data.postalCode;
|
||||
this.country = data.country;
|
||||
this.company = data.company;
|
||||
this.email = data.email;
|
||||
this.phone = data.phone;
|
||||
this.ssn = data.ssn;
|
||||
this.username = data.username;
|
||||
this.passportNumber = data.passportNumber;
|
||||
this.licenseNumber = data.licenseNumber;
|
||||
}
|
||||
}
|
||||
10
common/src/models/data/index.ts
Normal file
10
common/src/models/data/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export { AttachmentData } from './attachmentData';
|
||||
export { CardData } from './cardData';
|
||||
export { CipherData } from './cipherData';
|
||||
export { CollectionData } from './collectionData';
|
||||
export { FieldData } from './fieldData';
|
||||
export { FolderData } from './folderData';
|
||||
export { IdentityData } from './identityData';
|
||||
export { LoginData } from './loginData';
|
||||
export { LoginUriData } from './loginUriData';
|
||||
export { SecureNoteData } from './secureNoteData';
|
||||
28
common/src/models/data/loginData.ts
Normal file
28
common/src/models/data/loginData.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { LoginApi } from '../api/loginApi';
|
||||
|
||||
import { LoginUriData } from './loginUriData';
|
||||
|
||||
export class LoginData {
|
||||
uris: LoginUriData[];
|
||||
username: string;
|
||||
password: string;
|
||||
passwordRevisionDate: string;
|
||||
totp: string;
|
||||
autofillOnPageLoad: boolean;
|
||||
|
||||
constructor(data?: LoginApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.username = data.username;
|
||||
this.password = data.password;
|
||||
this.passwordRevisionDate = data.passwordRevisionDate;
|
||||
this.totp = data.totp;
|
||||
this.autofillOnPageLoad = data.autofillOnPageLoad;
|
||||
|
||||
if (data.uris) {
|
||||
this.uris = data.uris.map(u => new LoginUriData(u));
|
||||
}
|
||||
}
|
||||
}
|
||||
16
common/src/models/data/loginUriData.ts
Normal file
16
common/src/models/data/loginUriData.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { UriMatchType } from '../../enums/uriMatchType';
|
||||
|
||||
import { LoginUriApi } from '../api/loginUriApi';
|
||||
|
||||
export class LoginUriData {
|
||||
uri: string;
|
||||
match: UriMatchType = null;
|
||||
|
||||
constructor(data?: LoginUriApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.uri = data.uri;
|
||||
this.match = data.match;
|
||||
}
|
||||
}
|
||||
63
common/src/models/data/organizationData.ts
Normal file
63
common/src/models/data/organizationData.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { ProfileOrganizationResponse } from '../response/profileOrganizationResponse';
|
||||
|
||||
import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';
|
||||
import { OrganizationUserType } from '../../enums/organizationUserType';
|
||||
import { PermissionsApi } from '../api/permissionsApi';
|
||||
|
||||
export class OrganizationData {
|
||||
id: string;
|
||||
name: string;
|
||||
status: OrganizationUserStatusType;
|
||||
type: OrganizationUserType;
|
||||
enabled: boolean;
|
||||
usePolicies: boolean;
|
||||
useGroups: boolean;
|
||||
useDirectory: boolean;
|
||||
useEvents: boolean;
|
||||
useTotp: boolean;
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useBusinessPortal: boolean;
|
||||
useSso: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
seats: number;
|
||||
maxCollections: number;
|
||||
maxStorageGb?: number;
|
||||
ssoBound: boolean;
|
||||
identifier: string;
|
||||
permissions: PermissionsApi;
|
||||
resetPasswordEnrolled: boolean;
|
||||
userId: string;
|
||||
hasPublicAndPrivateKeys: boolean;
|
||||
|
||||
constructor(response: ProfileOrganizationResponse) {
|
||||
this.id = response.id;
|
||||
this.name = response.name;
|
||||
this.status = response.status;
|
||||
this.type = response.type;
|
||||
this.enabled = response.enabled;
|
||||
this.usePolicies = response.usePolicies;
|
||||
this.useGroups = response.useGroups;
|
||||
this.useDirectory = response.useDirectory;
|
||||
this.useEvents = response.useEvents;
|
||||
this.useTotp = response.useTotp;
|
||||
this.use2fa = response.use2fa;
|
||||
this.useApi = response.useApi;
|
||||
this.useBusinessPortal = response.useBusinessPortal;
|
||||
this.useSso = response.useSso;
|
||||
this.useResetPassword = response.useResetPassword;
|
||||
this.selfHost = response.selfHost;
|
||||
this.usersGetPremium = response.usersGetPremium;
|
||||
this.seats = response.seats;
|
||||
this.maxCollections = response.maxCollections;
|
||||
this.maxStorageGb = response.maxStorageGb;
|
||||
this.ssoBound = response.ssoBound;
|
||||
this.identifier = response.identifier;
|
||||
this.permissions = response.permissions;
|
||||
this.resetPasswordEnrolled = response.resetPasswordEnrolled;
|
||||
this.userId = response.userId;
|
||||
this.hasPublicAndPrivateKeys = response.hasPublicAndPrivateKeys;
|
||||
}
|
||||
}
|
||||
15
common/src/models/data/passwordHistoryData.ts
Normal file
15
common/src/models/data/passwordHistoryData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { PasswordHistoryResponse } from '../response/passwordHistoryResponse';
|
||||
|
||||
export class PasswordHistoryData {
|
||||
password: string;
|
||||
lastUsedDate: string;
|
||||
|
||||
constructor(response?: PasswordHistoryResponse) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.password = response.password;
|
||||
this.lastUsedDate = response.lastUsedDate;
|
||||
}
|
||||
}
|
||||
19
common/src/models/data/policyData.ts
Normal file
19
common/src/models/data/policyData.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { PolicyResponse } from '../response/policyResponse';
|
||||
|
||||
import { PolicyType } from '../../enums/policyType';
|
||||
|
||||
export class PolicyData {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
type: PolicyType;
|
||||
data: any;
|
||||
enabled: boolean;
|
||||
|
||||
constructor(response: PolicyResponse) {
|
||||
this.id = response.id;
|
||||
this.organizationId = response.organizationId;
|
||||
this.type = response.type;
|
||||
this.data = response.data;
|
||||
this.enabled = response.enabled;
|
||||
}
|
||||
}
|
||||
15
common/src/models/data/secureNoteData.ts
Normal file
15
common/src/models/data/secureNoteData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { SecureNoteType } from '../../enums/secureNoteType';
|
||||
|
||||
import { SecureNoteApi } from '../api/secureNoteApi';
|
||||
|
||||
export class SecureNoteData {
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(data?: SecureNoteApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = data.type;
|
||||
}
|
||||
}
|
||||
59
common/src/models/data/sendData.ts
Normal file
59
common/src/models/data/sendData.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { SendType } from '../../enums/sendType';
|
||||
|
||||
import { SendFileData } from './sendFileData';
|
||||
import { SendTextData } from './sendTextData';
|
||||
|
||||
import { SendResponse } from '../response/sendResponse';
|
||||
|
||||
export class SendData {
|
||||
id: string;
|
||||
accessId: string;
|
||||
userId: string;
|
||||
type: SendType;
|
||||
name: string;
|
||||
notes: string;
|
||||
file: SendFileData;
|
||||
text: SendTextData;
|
||||
key: string;
|
||||
maxAccessCount?: number;
|
||||
accessCount: number;
|
||||
revisionDate: string;
|
||||
expirationDate: string;
|
||||
deletionDate: string;
|
||||
password: string;
|
||||
disabled: boolean;
|
||||
hideEmail: boolean;
|
||||
|
||||
constructor(response?: SendResponse, userId?: string) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = response.id;
|
||||
this.accessId = response.accessId;
|
||||
this.userId = userId;
|
||||
this.type = response.type;
|
||||
this.name = response.name;
|
||||
this.notes = response.notes;
|
||||
this.key = response.key;
|
||||
this.maxAccessCount = response.maxAccessCount;
|
||||
this.accessCount = response.accessCount;
|
||||
this.revisionDate = response.revisionDate;
|
||||
this.expirationDate = response.expirationDate;
|
||||
this.deletionDate = response.deletionDate;
|
||||
this.password = response.password;
|
||||
this.disabled = response.disable;
|
||||
this.hideEmail = response.hideEmail;
|
||||
|
||||
switch (this.type) {
|
||||
case SendType.Text:
|
||||
this.text = new SendTextData(response.text);
|
||||
break;
|
||||
case SendType.File:
|
||||
this.file = new SendFileData(response.file);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
common/src/models/data/sendFileData.ts
Normal file
21
common/src/models/data/sendFileData.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { SendFileApi } from '../api/sendFileApi';
|
||||
|
||||
export class SendFileData {
|
||||
id: string;
|
||||
fileName: string;
|
||||
key: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
|
||||
constructor(data?: SendFileApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = data.id;
|
||||
this.fileName = data.fileName;
|
||||
this.key = data.key;
|
||||
this.size = data.size;
|
||||
this.sizeName = data.sizeName;
|
||||
}
|
||||
}
|
||||
15
common/src/models/data/sendTextData.ts
Normal file
15
common/src/models/data/sendTextData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { SendTextApi } from '../api/sendTextApi';
|
||||
|
||||
export class SendTextData {
|
||||
text: string;
|
||||
hidden: boolean;
|
||||
|
||||
constructor(data?: SendTextApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.text = data.text;
|
||||
this.hidden = data.hidden;
|
||||
}
|
||||
}
|
||||
75
common/src/models/domain/attachment.ts
Normal file
75
common/src/models/domain/attachment.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { AttachmentData } from '../data/attachmentData';
|
||||
|
||||
import { AttachmentView } from '../view/attachmentView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
import { CryptoService } from '../../abstractions/crypto.service';
|
||||
|
||||
import { Utils } from '../../misc/utils';
|
||||
|
||||
export class Attachment extends Domain {
|
||||
id: string;
|
||||
url: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
key: EncString;
|
||||
fileName: EncString;
|
||||
|
||||
constructor(obj?: AttachmentData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.size = obj.size;
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
url: null,
|
||||
sizeName: null,
|
||||
fileName: null,
|
||||
key: null,
|
||||
}, alreadyEncrypted, ['id', 'url', 'sizeName']);
|
||||
}
|
||||
|
||||
async decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<AttachmentView> {
|
||||
const view = await this.decryptObj(new AttachmentView(this), {
|
||||
fileName: null,
|
||||
}, orgId, encKey);
|
||||
|
||||
if (this.key != null) {
|
||||
let cryptoService: CryptoService;
|
||||
const containerService = (Utils.global as any).bitwardenContainerService;
|
||||
if (containerService) {
|
||||
cryptoService = containerService.getCryptoService();
|
||||
} else {
|
||||
throw new Error('global bitwardenContainerService not initialized.');
|
||||
}
|
||||
|
||||
try {
|
||||
const orgKey = await cryptoService.getOrgKey(orgId);
|
||||
const decValue = await cryptoService.decryptToBytes(this.key, orgKey ?? encKey);
|
||||
view.key = new SymmetricCryptoKey(decValue);
|
||||
} catch (e) {
|
||||
// TODO: error?
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
toAttachmentData(): AttachmentData {
|
||||
const a = new AttachmentData();
|
||||
a.size = this.size;
|
||||
this.buildDataModel(this, a, {
|
||||
id: null,
|
||||
url: null,
|
||||
sizeName: null,
|
||||
fileName: null,
|
||||
key: null,
|
||||
}, ['id', 'url', 'sizeName']);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
7
common/src/models/domain/authResult.ts
Normal file
7
common/src/models/domain/authResult.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { TwoFactorProviderType } from '../../enums/twoFactorProviderType';
|
||||
|
||||
export class AuthResult {
|
||||
twoFactor: boolean = false;
|
||||
resetMasterPassword: boolean = false;
|
||||
twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string; }> = null;
|
||||
}
|
||||
56
common/src/models/domain/card.ts
Normal file
56
common/src/models/domain/card.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { CardData } from '../data/cardData';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
|
||||
import { CardView } from '../view/cardView';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class Card extends Domain {
|
||||
cardholderName: EncString;
|
||||
brand: EncString;
|
||||
number: EncString;
|
||||
expMonth: EncString;
|
||||
expYear: EncString;
|
||||
code: EncString;
|
||||
|
||||
constructor(obj?: CardData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
cardholderName: null,
|
||||
brand: null,
|
||||
number: null,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
code: null,
|
||||
}, alreadyEncrypted, []);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<CardView> {
|
||||
return this.decryptObj(new CardView(this), {
|
||||
cardholderName: null,
|
||||
brand: null,
|
||||
number: null,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
code: null,
|
||||
}, orgId, encKey);
|
||||
}
|
||||
|
||||
toCardData(): CardData {
|
||||
const c = new CardData();
|
||||
this.buildDataModel(this, c, {
|
||||
cardholderName: null,
|
||||
brand: null,
|
||||
number: null,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
code: null,
|
||||
});
|
||||
return c;
|
||||
}
|
||||
}
|
||||
224
common/src/models/domain/cipher.ts
Normal file
224
common/src/models/domain/cipher.ts
Normal file
@@ -0,0 +1,224 @@
|
||||
import { CipherRepromptType } from '../../enums/cipherRepromptType';
|
||||
import { CipherType } from '../../enums/cipherType';
|
||||
|
||||
import { CipherData } from '../data/cipherData';
|
||||
|
||||
import { CipherView } from '../view/cipherView';
|
||||
|
||||
import { Attachment } from './attachment';
|
||||
import { Card } from './card';
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { Field } from './field';
|
||||
import { Identity } from './identity';
|
||||
import { Login } from './login';
|
||||
import { Password } from './password';
|
||||
import { SecureNote } from './secureNote';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class Cipher extends Domain {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
folderId: string;
|
||||
name: EncString;
|
||||
notes: EncString;
|
||||
type: CipherType;
|
||||
favorite: boolean;
|
||||
organizationUseTotp: boolean;
|
||||
edit: boolean;
|
||||
viewPassword: boolean;
|
||||
revisionDate: Date;
|
||||
localData: any;
|
||||
login: Login;
|
||||
identity: Identity;
|
||||
card: Card;
|
||||
secureNote: SecureNote;
|
||||
attachments: Attachment[];
|
||||
fields: Field[];
|
||||
passwordHistory: Password[];
|
||||
collectionIds: string[];
|
||||
deletedDate: Date;
|
||||
reprompt: CipherRepromptType;
|
||||
|
||||
constructor(obj?: CipherData, alreadyEncrypted: boolean = false, localData: any = null) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
userId: null,
|
||||
organizationId: null,
|
||||
folderId: null,
|
||||
name: null,
|
||||
notes: null,
|
||||
}, alreadyEncrypted, ['id', 'userId', 'organizationId', 'folderId']);
|
||||
|
||||
this.type = obj.type;
|
||||
this.favorite = obj.favorite;
|
||||
this.organizationUseTotp = obj.organizationUseTotp;
|
||||
this.edit = obj.edit;
|
||||
if (obj.viewPassword != null) {
|
||||
this.viewPassword = obj.viewPassword;
|
||||
} else {
|
||||
this.viewPassword = true; // Default for already synced Ciphers without viewPassword
|
||||
}
|
||||
this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
|
||||
this.collectionIds = obj.collectionIds;
|
||||
this.localData = localData;
|
||||
this.deletedDate = obj.deletedDate != null ? new Date(obj.deletedDate) : null;
|
||||
this.reprompt = obj.reprompt;
|
||||
|
||||
switch (this.type) {
|
||||
case CipherType.Login:
|
||||
this.login = new Login(obj.login, alreadyEncrypted);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
this.secureNote = new SecureNote(obj.secureNote, alreadyEncrypted);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
this.card = new Card(obj.card, alreadyEncrypted);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
this.identity = new Identity(obj.identity, alreadyEncrypted);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj.attachments != null) {
|
||||
this.attachments = obj.attachments.map(a => new Attachment(a, alreadyEncrypted));
|
||||
} else {
|
||||
this.attachments = null;
|
||||
}
|
||||
|
||||
if (obj.fields != null) {
|
||||
this.fields = obj.fields.map(f => new Field(f, alreadyEncrypted));
|
||||
} else {
|
||||
this.fields = null;
|
||||
}
|
||||
|
||||
if (obj.passwordHistory != null) {
|
||||
this.passwordHistory = obj.passwordHistory.map(ph => new Password(ph, alreadyEncrypted));
|
||||
} else {
|
||||
this.passwordHistory = null;
|
||||
}
|
||||
}
|
||||
|
||||
async decrypt(encKey?: SymmetricCryptoKey): Promise<CipherView> {
|
||||
const model = new CipherView(this);
|
||||
|
||||
await this.decryptObj(model, {
|
||||
name: null,
|
||||
notes: null,
|
||||
}, this.organizationId, encKey);
|
||||
|
||||
switch (this.type) {
|
||||
case CipherType.Login:
|
||||
model.login = await this.login.decrypt(this.organizationId, encKey);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
model.secureNote = await this.secureNote.decrypt(this.organizationId, encKey);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
model.card = await this.card.decrypt(this.organizationId, encKey);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
model.identity = await this.identity.decrypt(this.organizationId, encKey);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const orgId = this.organizationId;
|
||||
|
||||
if (this.attachments != null && this.attachments.length > 0) {
|
||||
const attachments: any[] = [];
|
||||
await this.attachments.reduce((promise, attachment) => {
|
||||
return promise.then(() => {
|
||||
return attachment.decrypt(orgId, encKey);
|
||||
}).then(decAttachment => {
|
||||
attachments.push(decAttachment);
|
||||
});
|
||||
}, Promise.resolve());
|
||||
model.attachments = attachments;
|
||||
}
|
||||
|
||||
if (this.fields != null && this.fields.length > 0) {
|
||||
const fields: any[] = [];
|
||||
await this.fields.reduce((promise, field) => {
|
||||
return promise.then(() => {
|
||||
return field.decrypt(orgId, encKey);
|
||||
}).then(decField => {
|
||||
fields.push(decField);
|
||||
});
|
||||
}, Promise.resolve());
|
||||
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, encKey);
|
||||
}).then(decPh => {
|
||||
passwordHistory.push(decPh);
|
||||
});
|
||||
}, Promise.resolve());
|
||||
model.passwordHistory = passwordHistory;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
toCipherData(userId: string): CipherData {
|
||||
const c = new CipherData();
|
||||
c.id = this.id;
|
||||
c.organizationId = this.organizationId;
|
||||
c.folderId = this.folderId;
|
||||
c.userId = this.organizationId != null ? userId : null;
|
||||
c.edit = this.edit;
|
||||
c.viewPassword = this.viewPassword;
|
||||
c.organizationUseTotp = this.organizationUseTotp;
|
||||
c.favorite = this.favorite;
|
||||
c.revisionDate = this.revisionDate != null ? this.revisionDate.toISOString() : null;
|
||||
c.type = this.type;
|
||||
c.collectionIds = this.collectionIds;
|
||||
c.deletedDate = this.deletedDate != null ? this.deletedDate.toISOString() : null;
|
||||
c.reprompt = this.reprompt;
|
||||
|
||||
this.buildDataModel(this, c, {
|
||||
name: null,
|
||||
notes: null,
|
||||
});
|
||||
|
||||
switch (c.type) {
|
||||
case CipherType.Login:
|
||||
c.login = this.login.toLoginData();
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
c.secureNote = this.secureNote.toSecureNoteData();
|
||||
break;
|
||||
case CipherType.Card:
|
||||
c.card = this.card.toCardData();
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
c.identity = this.identity.toIdentityData();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.fields != null) {
|
||||
c.fields = this.fields.map(f => f.toFieldData());
|
||||
}
|
||||
if (this.attachments != null) {
|
||||
c.attachments = this.attachments.map(a => a.toAttachmentData());
|
||||
}
|
||||
if (this.passwordHistory != null) {
|
||||
c.passwordHistory = this.passwordHistory.map(ph => ph.toPasswordHistoryData());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
37
common/src/models/domain/collection.ts
Normal file
37
common/src/models/domain/collection.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { CollectionData } from '../data/collectionData';
|
||||
|
||||
import { CollectionView } from '../view/collectionView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
|
||||
export class Collection extends Domain {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
name: EncString;
|
||||
externalId: string;
|
||||
readOnly: boolean;
|
||||
hidePasswords: boolean;
|
||||
|
||||
constructor(obj?: CollectionData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
organizationId: null,
|
||||
name: null,
|
||||
externalId: null,
|
||||
readOnly: null,
|
||||
hidePasswords: null,
|
||||
}, alreadyEncrypted, ['id', 'organizationId', 'externalId', 'readOnly', 'hidePasswords']);
|
||||
}
|
||||
|
||||
decrypt(): Promise<CollectionView> {
|
||||
return this.decryptObj(new CollectionView(this), {
|
||||
name: null,
|
||||
}, this.organizationId);
|
||||
}
|
||||
}
|
||||
8
common/src/models/domain/decryptParameters.ts
Normal file
8
common/src/models/domain/decryptParameters.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export class DecryptParameters<T> {
|
||||
encKey: T;
|
||||
data: T;
|
||||
iv: T;
|
||||
macKey: T;
|
||||
mac: T;
|
||||
macData: T;
|
||||
}
|
||||
66
common/src/models/domain/domainBase.ts
Normal file
66
common/src/models/domain/domainBase.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { EncString } from './encString';
|
||||
|
||||
import { View } from '../view/view';
|
||||
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export default class Domain {
|
||||
protected buildDomainModel<D extends Domain>(domain: D, dataObj: any, map: any,
|
||||
alreadyEncrypted: boolean, notEncList: any[] = []) {
|
||||
for (const prop in map) {
|
||||
if (!map.hasOwnProperty(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const objProp = dataObj[(map[prop] || prop)];
|
||||
if (alreadyEncrypted === true || notEncList.indexOf(prop) > -1) {
|
||||
(domain as any)[prop] = objProp ? objProp : null;
|
||||
} else {
|
||||
(domain as any)[prop] = objProp ? new EncString(objProp) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected buildDataModel<D extends Domain>(domain: D, dataObj: any, map: any, notEncStringList: any[] = []) {
|
||||
for (const prop in map) {
|
||||
if (!map.hasOwnProperty(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const objProp = (domain as any)[(map[prop] || prop)];
|
||||
if (notEncStringList.indexOf(prop) > -1) {
|
||||
(dataObj as any)[prop] = objProp != null ? objProp : null;
|
||||
} else {
|
||||
(dataObj as any)[prop] = objProp != null ? (objProp as EncString).encryptedString : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async decryptObj<T extends View>(viewModel: T, map: any, orgId: string,
|
||||
key: SymmetricCryptoKey = null): Promise<T> {
|
||||
const promises = [];
|
||||
const self: any = this;
|
||||
|
||||
for (const prop in map) {
|
||||
if (!map.hasOwnProperty(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line
|
||||
(function (theProp) {
|
||||
const p = Promise.resolve().then(() => {
|
||||
const mapProp = map[theProp] || theProp;
|
||||
if (self[mapProp]) {
|
||||
return self[mapProp].decrypt(orgId, key);
|
||||
}
|
||||
return null;
|
||||
}).then((val: any) => {
|
||||
(viewModel as any)[theProp] = val;
|
||||
});
|
||||
promises.push(p);
|
||||
})(prop);
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
3
common/src/models/domain/encArrayBuffer.ts
Normal file
3
common/src/models/domain/encArrayBuffer.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export class EncArrayBuffer {
|
||||
constructor(public buffer: ArrayBuffer) { }
|
||||
}
|
||||
117
common/src/models/domain/encString.ts
Normal file
117
common/src/models/domain/encString.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { EncryptionType } from '../../enums/encryptionType';
|
||||
|
||||
import { CryptoService } from '../../abstractions/crypto.service';
|
||||
|
||||
import { Utils } from '../../misc/utils';
|
||||
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class EncString {
|
||||
encryptedString?: string;
|
||||
encryptionType?: EncryptionType;
|
||||
decryptedValue?: string;
|
||||
data?: string;
|
||||
iv?: string;
|
||||
mac?: string;
|
||||
|
||||
constructor(encryptedStringOrType: string | EncryptionType, data?: string, iv?: string, mac?: string) {
|
||||
if (data != null) {
|
||||
// data and header
|
||||
const encType = encryptedStringOrType as EncryptionType;
|
||||
|
||||
if (iv != null) {
|
||||
this.encryptedString = encType + '.' + iv + '|' + data;
|
||||
} else {
|
||||
this.encryptedString = encType + '.' + data;
|
||||
}
|
||||
|
||||
// mac
|
||||
if (mac != null) {
|
||||
this.encryptedString += ('|' + mac);
|
||||
}
|
||||
|
||||
this.encryptionType = encType;
|
||||
this.data = data;
|
||||
this.iv = iv;
|
||||
this.mac = mac;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.encryptedString = encryptedStringOrType as string;
|
||||
if (!this.encryptedString) {
|
||||
return;
|
||||
}
|
||||
|
||||
const headerPieces = this.encryptedString.split('.');
|
||||
let encPieces: string[] = null;
|
||||
|
||||
if (headerPieces.length === 2) {
|
||||
try {
|
||||
this.encryptionType = parseInt(headerPieces[0], null);
|
||||
encPieces = headerPieces[1].split('|');
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
encPieces = this.encryptedString.split('|');
|
||||
this.encryptionType = encPieces.length === 3 ? EncryptionType.AesCbc128_HmacSha256_B64 :
|
||||
EncryptionType.AesCbc256_B64;
|
||||
}
|
||||
|
||||
switch (this.encryptionType) {
|
||||
case EncryptionType.AesCbc128_HmacSha256_B64:
|
||||
case EncryptionType.AesCbc256_HmacSha256_B64:
|
||||
if (encPieces.length !== 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iv = encPieces[0];
|
||||
this.data = encPieces[1];
|
||||
this.mac = encPieces[2];
|
||||
break;
|
||||
case EncryptionType.AesCbc256_B64:
|
||||
if (encPieces.length !== 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.iv = encPieces[0];
|
||||
this.data = encPieces[1];
|
||||
break;
|
||||
case EncryptionType.Rsa2048_OaepSha256_B64:
|
||||
case EncryptionType.Rsa2048_OaepSha1_B64:
|
||||
if (encPieces.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data = encPieces[0];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async decrypt(orgId: string, key: SymmetricCryptoKey = null): Promise<string> {
|
||||
if (this.decryptedValue != null) {
|
||||
return this.decryptedValue;
|
||||
}
|
||||
|
||||
let cryptoService: CryptoService;
|
||||
const containerService = (Utils.global as any).bitwardenContainerService;
|
||||
if (containerService) {
|
||||
cryptoService = containerService.getCryptoService();
|
||||
} else {
|
||||
throw new Error('global bitwardenContainerService not initialized.');
|
||||
}
|
||||
|
||||
try {
|
||||
if (key == null) {
|
||||
key = await cryptoService.getOrgKey(orgId);
|
||||
}
|
||||
this.decryptedValue = await cryptoService.decryptToUtf8(this, key);
|
||||
} catch (e) {
|
||||
this.decryptedValue = '[error: cannot decrypt]';
|
||||
}
|
||||
return this.decryptedValue;
|
||||
}
|
||||
}
|
||||
8
common/src/models/domain/encryptedObject.ts
Normal file
8
common/src/models/domain/encryptedObject.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class EncryptedObject {
|
||||
iv: ArrayBuffer;
|
||||
data: ArrayBuffer;
|
||||
mac: ArrayBuffer;
|
||||
key: SymmetricCryptoKey;
|
||||
}
|
||||
6
common/src/models/domain/environmentUrls.ts
Normal file
6
common/src/models/domain/environmentUrls.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export class EnvironmentUrls {
|
||||
base: string;
|
||||
api: string;
|
||||
identity: string;
|
||||
events: string;
|
||||
}
|
||||
45
common/src/models/domain/field.ts
Normal file
45
common/src/models/domain/field.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { FieldType } from '../../enums/fieldType';
|
||||
|
||||
import { FieldData } from '../data/fieldData';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
|
||||
import { FieldView } from '../view/fieldView';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class Field extends Domain {
|
||||
name: EncString;
|
||||
value: EncString;
|
||||
type: FieldType;
|
||||
|
||||
constructor(obj?: FieldData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = obj.type;
|
||||
this.buildDomainModel(this, obj, {
|
||||
name: null,
|
||||
value: null,
|
||||
}, alreadyEncrypted, []);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<FieldView> {
|
||||
return this.decryptObj(new FieldView(this), {
|
||||
name: null,
|
||||
value: null,
|
||||
}, orgId, encKey);
|
||||
}
|
||||
|
||||
toFieldData(): FieldData {
|
||||
const f = new FieldData();
|
||||
this.buildDataModel(this, f, {
|
||||
name: null,
|
||||
value: null,
|
||||
type: null,
|
||||
}, ['type']);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
32
common/src/models/domain/folder.ts
Normal file
32
common/src/models/domain/folder.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { FolderData } from '../data/folderData';
|
||||
|
||||
import { FolderView } from '../view/folderView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
|
||||
export class Folder extends Domain {
|
||||
id: string;
|
||||
name: EncString;
|
||||
revisionDate: Date;
|
||||
|
||||
constructor(obj?: FolderData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
name: null,
|
||||
}, alreadyEncrypted, ['id']);
|
||||
|
||||
this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
|
||||
}
|
||||
|
||||
decrypt(): Promise<FolderView> {
|
||||
return this.decryptObj(new FolderView(this), {
|
||||
name: null,
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
9
common/src/models/domain/generatedPasswordHistory.ts
Normal file
9
common/src/models/domain/generatedPasswordHistory.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class GeneratedPasswordHistory {
|
||||
password: string;
|
||||
date: number;
|
||||
|
||||
constructor(password: string, date: number) {
|
||||
this.password = password;
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
104
common/src/models/domain/identity.ts
Normal file
104
common/src/models/domain/identity.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { IdentityData } from '../data/identityData';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
import { IdentityView } from '../view/identityView';
|
||||
|
||||
export class Identity extends Domain {
|
||||
title: EncString;
|
||||
firstName: EncString;
|
||||
middleName: EncString;
|
||||
lastName: EncString;
|
||||
address1: EncString;
|
||||
address2: EncString;
|
||||
address3: EncString;
|
||||
city: EncString;
|
||||
state: EncString;
|
||||
postalCode: EncString;
|
||||
country: EncString;
|
||||
company: EncString;
|
||||
email: EncString;
|
||||
phone: EncString;
|
||||
ssn: EncString;
|
||||
username: EncString;
|
||||
passportNumber: EncString;
|
||||
licenseNumber: EncString;
|
||||
|
||||
constructor(obj?: IdentityData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
title: null,
|
||||
firstName: null,
|
||||
middleName: null,
|
||||
lastName: null,
|
||||
address1: null,
|
||||
address2: null,
|
||||
address3: null,
|
||||
city: null,
|
||||
state: null,
|
||||
postalCode: null,
|
||||
country: null,
|
||||
company: null,
|
||||
email: null,
|
||||
phone: null,
|
||||
ssn: null,
|
||||
username: null,
|
||||
passportNumber: null,
|
||||
licenseNumber: null,
|
||||
}, alreadyEncrypted, []);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<IdentityView> {
|
||||
return this.decryptObj(new IdentityView(this), {
|
||||
title: null,
|
||||
firstName: null,
|
||||
middleName: null,
|
||||
lastName: null,
|
||||
address1: null,
|
||||
address2: null,
|
||||
address3: null,
|
||||
city: null,
|
||||
state: null,
|
||||
postalCode: null,
|
||||
country: null,
|
||||
company: null,
|
||||
email: null,
|
||||
phone: null,
|
||||
ssn: null,
|
||||
username: null,
|
||||
passportNumber: null,
|
||||
licenseNumber: null,
|
||||
}, orgId, encKey);
|
||||
}
|
||||
|
||||
toIdentityData(): IdentityData {
|
||||
const i = new IdentityData();
|
||||
this.buildDataModel(this, i, {
|
||||
title: null,
|
||||
firstName: null,
|
||||
middleName: null,
|
||||
lastName: null,
|
||||
address1: null,
|
||||
address2: null,
|
||||
address3: null,
|
||||
city: null,
|
||||
state: null,
|
||||
postalCode: null,
|
||||
country: null,
|
||||
company: null,
|
||||
email: null,
|
||||
phone: null,
|
||||
ssn: null,
|
||||
username: null,
|
||||
passportNumber: null,
|
||||
licenseNumber: null,
|
||||
});
|
||||
return i;
|
||||
}
|
||||
}
|
||||
13
common/src/models/domain/importResult.ts
Normal file
13
common/src/models/domain/importResult.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { CipherView } from '../view/cipherView';
|
||||
import { CollectionView } from '../view/collectionView';
|
||||
import { FolderView } from '../view/folderView';
|
||||
|
||||
export class ImportResult {
|
||||
success = false;
|
||||
errorMessage: string;
|
||||
ciphers: CipherView[] = [];
|
||||
folders: FolderView[] = [];
|
||||
folderRelationships: [number, number][] = [];
|
||||
collections: CollectionView[] = [];
|
||||
collectionRelationships: [number, number][] = [];
|
||||
}
|
||||
16
common/src/models/domain/index.ts
Normal file
16
common/src/models/domain/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export { Attachment } from './attachment';
|
||||
export { AuthResult } from './authResult';
|
||||
export { Card } from './card';
|
||||
export { Cipher } from './cipher';
|
||||
export { EncString } from './encString';
|
||||
export { Collection } from './collection';
|
||||
export { EncryptedObject } from './encryptedObject';
|
||||
export { EnvironmentUrls } from './environmentUrls';
|
||||
export { Field } from './field';
|
||||
export { Folder } from './folder';
|
||||
export { Identity } from './identity';
|
||||
export { Login } from './login';
|
||||
export { LoginUri } from './loginUri';
|
||||
export { GeneratedPasswordHistory } from './generatedPasswordHistory';
|
||||
export { SecureNote } from './secureNote';
|
||||
export { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
78
common/src/models/domain/login.ts
Normal file
78
common/src/models/domain/login.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { LoginUri } from './loginUri';
|
||||
|
||||
import { LoginData } from '../data/loginData';
|
||||
|
||||
import { LoginView } from '../view/loginView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class Login extends Domain {
|
||||
uris: LoginUri[];
|
||||
username: EncString;
|
||||
password: EncString;
|
||||
passwordRevisionDate?: Date;
|
||||
totp: EncString;
|
||||
autofillOnPageLoad: boolean;
|
||||
|
||||
constructor(obj?: LoginData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.passwordRevisionDate = obj.passwordRevisionDate != null ? new Date(obj.passwordRevisionDate) : null;
|
||||
this.autofillOnPageLoad = obj.autofillOnPageLoad;
|
||||
this.buildDomainModel(this, obj, {
|
||||
username: null,
|
||||
password: null,
|
||||
totp: null,
|
||||
}, alreadyEncrypted, []);
|
||||
|
||||
if (obj.uris) {
|
||||
this.uris = [];
|
||||
obj.uris.forEach(u => {
|
||||
this.uris.push(new LoginUri(u, alreadyEncrypted));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<LoginView> {
|
||||
const view = await this.decryptObj(new LoginView(this), {
|
||||
username: null,
|
||||
password: null,
|
||||
totp: null,
|
||||
}, orgId, encKey);
|
||||
|
||||
if (this.uris != null) {
|
||||
view.uris = [];
|
||||
for (let i = 0; i < this.uris.length; i++) {
|
||||
const uri = await this.uris[i].decrypt(orgId, encKey);
|
||||
view.uris.push(uri);
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
toLoginData(): LoginData {
|
||||
const l = new LoginData();
|
||||
l.passwordRevisionDate = this.passwordRevisionDate != null ? this.passwordRevisionDate.toISOString() : null;
|
||||
l.autofillOnPageLoad = this.autofillOnPageLoad;
|
||||
this.buildDataModel(this, l, {
|
||||
username: null,
|
||||
password: null,
|
||||
totp: null,
|
||||
});
|
||||
|
||||
if (this.uris != null && this.uris.length > 0) {
|
||||
l.uris = [];
|
||||
this.uris.forEach(u => {
|
||||
l.uris.push(u.toLoginUriData());
|
||||
});
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
}
|
||||
40
common/src/models/domain/loginUri.ts
Normal file
40
common/src/models/domain/loginUri.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { UriMatchType } from '../../enums/uriMatchType';
|
||||
|
||||
import { LoginUriData } from '../data/loginUriData';
|
||||
|
||||
import { LoginUriView } from '../view/loginUriView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class LoginUri extends Domain {
|
||||
uri: EncString;
|
||||
match: UriMatchType;
|
||||
|
||||
constructor(obj?: LoginUriData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.match = obj.match;
|
||||
this.buildDomainModel(this, obj, {
|
||||
uri: null,
|
||||
}, alreadyEncrypted, []);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<LoginUriView> {
|
||||
return this.decryptObj(new LoginUriView(this), {
|
||||
uri: null,
|
||||
}, orgId, encKey);
|
||||
}
|
||||
|
||||
toLoginUriData(): LoginUriData {
|
||||
const u = new LoginUriData();
|
||||
this.buildDataModel(this, u, {
|
||||
uri: null,
|
||||
}, ['match']);
|
||||
return u;
|
||||
}
|
||||
}
|
||||
10
common/src/models/domain/masterPasswordPolicyOptions.ts
Normal file
10
common/src/models/domain/masterPasswordPolicyOptions.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import Domain from './domainBase';
|
||||
|
||||
export class MasterPasswordPolicyOptions extends Domain {
|
||||
minComplexity: number = 0;
|
||||
minLength: number = 0;
|
||||
requireUpper: boolean = false;
|
||||
requireLower: boolean = false;
|
||||
requireNumbers: boolean = false;
|
||||
requireSpecial: boolean = false;
|
||||
}
|
||||
132
common/src/models/domain/organization.ts
Normal file
132
common/src/models/domain/organization.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import { OrganizationData } from '../data/organizationData';
|
||||
|
||||
import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';
|
||||
import { OrganizationUserType } from '../../enums/organizationUserType';
|
||||
import { PermissionsApi } from '../api/permissionsApi';
|
||||
|
||||
|
||||
export class Organization {
|
||||
id: string;
|
||||
name: string;
|
||||
status: OrganizationUserStatusType;
|
||||
type: OrganizationUserType;
|
||||
enabled: boolean;
|
||||
usePolicies: boolean;
|
||||
useGroups: boolean;
|
||||
useDirectory: boolean;
|
||||
useEvents: boolean;
|
||||
useTotp: boolean;
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useBusinessPortal: boolean;
|
||||
useSso: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
seats: number;
|
||||
maxCollections: number;
|
||||
maxStorageGb?: number;
|
||||
ssoBound: boolean;
|
||||
identifier: string;
|
||||
permissions: PermissionsApi;
|
||||
resetPasswordEnrolled: boolean;
|
||||
userId: string;
|
||||
hasPublicAndPrivateKeys: boolean;
|
||||
|
||||
constructor(obj?: OrganizationData) {
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = obj.id;
|
||||
this.name = obj.name;
|
||||
this.status = obj.status;
|
||||
this.type = obj.type;
|
||||
this.enabled = obj.enabled;
|
||||
this.usePolicies = obj.usePolicies;
|
||||
this.useGroups = obj.useGroups;
|
||||
this.useDirectory = obj.useDirectory;
|
||||
this.useEvents = obj.useEvents;
|
||||
this.useTotp = obj.useTotp;
|
||||
this.use2fa = obj.use2fa;
|
||||
this.useApi = obj.useApi;
|
||||
this.useBusinessPortal = obj.useBusinessPortal;
|
||||
this.useSso = obj.useSso;
|
||||
this.useResetPassword = obj.useResetPassword;
|
||||
this.selfHost = obj.selfHost;
|
||||
this.usersGetPremium = obj.usersGetPremium;
|
||||
this.seats = obj.seats;
|
||||
this.maxCollections = obj.maxCollections;
|
||||
this.maxStorageGb = obj.maxStorageGb;
|
||||
this.ssoBound = obj.ssoBound;
|
||||
this.identifier = obj.identifier;
|
||||
this.permissions = obj.permissions;
|
||||
this.resetPasswordEnrolled = obj.resetPasswordEnrolled;
|
||||
this.userId = obj.userId;
|
||||
this.hasPublicAndPrivateKeys = obj.hasPublicAndPrivateKeys;
|
||||
}
|
||||
|
||||
get canAccess() {
|
||||
if (this.type === OrganizationUserType.Owner) {
|
||||
return true;
|
||||
}
|
||||
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
|
||||
}
|
||||
|
||||
get isManager() {
|
||||
return this.type === OrganizationUserType.Manager || this.type === OrganizationUserType.Owner ||
|
||||
this.type === OrganizationUserType.Admin;
|
||||
}
|
||||
|
||||
get isAdmin() {
|
||||
return this.type === OrganizationUserType.Owner || this.type === OrganizationUserType.Admin;
|
||||
}
|
||||
|
||||
get isOwner() {
|
||||
return this.type === OrganizationUserType.Owner;
|
||||
}
|
||||
|
||||
get canAccessBusinessPortal() {
|
||||
return this.isAdmin || this.permissions.accessBusinessPortal;
|
||||
}
|
||||
|
||||
get canAccessEventLogs() {
|
||||
return this.isAdmin || this.permissions.accessEventLogs;
|
||||
}
|
||||
|
||||
get canAccessImportExport() {
|
||||
return this.isAdmin || this.permissions.accessImportExport;
|
||||
}
|
||||
|
||||
get canAccessReports() {
|
||||
return this.isAdmin || this.permissions.accessReports;
|
||||
}
|
||||
|
||||
get canManageAllCollections() {
|
||||
return this.isAdmin || this.permissions.manageAllCollections;
|
||||
}
|
||||
|
||||
get canManageAssignedCollections() {
|
||||
return this.isManager || this.permissions.manageAssignedCollections;
|
||||
}
|
||||
|
||||
get canManageGroups() {
|
||||
return this.isAdmin || this.permissions.manageGroups;
|
||||
}
|
||||
|
||||
get canManageSso() {
|
||||
return this.isAdmin || this.permissions.manageSso;
|
||||
}
|
||||
|
||||
get canManagePolicies() {
|
||||
return this.isAdmin || this.permissions.managePolicies;
|
||||
}
|
||||
|
||||
get canManageUsers() {
|
||||
return this.isAdmin || this.permissions.manageUsers;
|
||||
}
|
||||
|
||||
get canManageUsersPassword() {
|
||||
return this.isAdmin || this.permissions.manageResetPassword;
|
||||
}
|
||||
}
|
||||
39
common/src/models/domain/password.ts
Normal file
39
common/src/models/domain/password.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { PasswordHistoryData } from '../data/passwordHistoryData';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
|
||||
import { PasswordHistoryView } from '../view/passwordHistoryView';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class Password extends Domain {
|
||||
password: EncString;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(obj?: PasswordHistoryData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
password: null,
|
||||
}, alreadyEncrypted);
|
||||
this.lastUsedDate = new Date(obj.lastUsedDate);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<PasswordHistoryView> {
|
||||
return this.decryptObj(new PasswordHistoryView(this), {
|
||||
password: null,
|
||||
}, orgId, encKey);
|
||||
}
|
||||
|
||||
toPasswordHistoryData(): PasswordHistoryData {
|
||||
const ph = new PasswordHistoryData();
|
||||
ph.lastUsedDate = this.lastUsedDate.toISOString();
|
||||
this.buildDataModel(this, ph, {
|
||||
password: null,
|
||||
});
|
||||
return ph;
|
||||
}
|
||||
}
|
||||
29
common/src/models/domain/passwordGeneratorPolicyOptions.ts
Normal file
29
common/src/models/domain/passwordGeneratorPolicyOptions.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import Domain from './domainBase';
|
||||
|
||||
export class PasswordGeneratorPolicyOptions extends Domain {
|
||||
defaultType: string = '';
|
||||
minLength: number = 0;
|
||||
useUppercase: boolean = false;
|
||||
useLowercase: boolean = false;
|
||||
useNumbers: boolean = false;
|
||||
numberCount: number = 0;
|
||||
useSpecial: boolean = false;
|
||||
specialCount: number = 0;
|
||||
minNumberWords: number = 0;
|
||||
capitalize: boolean = false;
|
||||
includeNumber: boolean = false;
|
||||
|
||||
inEffect() {
|
||||
return this.defaultType !== '' ||
|
||||
this.minLength > 0 ||
|
||||
this.numberCount > 0 ||
|
||||
this.specialCount > 0 ||
|
||||
this.useUppercase ||
|
||||
this.useLowercase ||
|
||||
this.useNumbers ||
|
||||
this.useSpecial ||
|
||||
this.minNumberWords > 0 ||
|
||||
this.capitalize ||
|
||||
this.includeNumber;
|
||||
}
|
||||
}
|
||||
26
common/src/models/domain/policy.ts
Normal file
26
common/src/models/domain/policy.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { PolicyData } from '../data/policyData';
|
||||
|
||||
import Domain from './domainBase';
|
||||
|
||||
import { PolicyType } from '../../enums/policyType';
|
||||
|
||||
export class Policy extends Domain {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
type: PolicyType;
|
||||
data: any;
|
||||
enabled: boolean;
|
||||
|
||||
constructor(obj?: PolicyData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = obj.id;
|
||||
this.organizationId = obj.organizationId;
|
||||
this.type = obj.type;
|
||||
this.data = obj.data;
|
||||
this.enabled = obj.enabled;
|
||||
}
|
||||
}
|
||||
5
common/src/models/domain/resetPasswordPolicyOptions.ts
Normal file
5
common/src/models/domain/resetPasswordPolicyOptions.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import Domain from './domainBase';
|
||||
|
||||
export class ResetPasswordPolicyOptions extends Domain {
|
||||
autoEnrollEnabled: boolean = false;
|
||||
}
|
||||
31
common/src/models/domain/secureNote.ts
Normal file
31
common/src/models/domain/secureNote.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { SecureNoteType } from '../../enums/secureNoteType';
|
||||
|
||||
import { SecureNoteData } from '../data/secureNoteData';
|
||||
|
||||
import Domain from './domainBase';
|
||||
|
||||
import { SecureNoteView } from '../view/secureNoteView';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class SecureNote extends Domain {
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(obj?: SecureNoteData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = obj.type;
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<SecureNoteView> {
|
||||
return Promise.resolve(new SecureNoteView(this));
|
||||
}
|
||||
|
||||
toSecureNoteData(): SecureNoteData {
|
||||
const n = new SecureNoteData();
|
||||
n.type = this.type;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
108
common/src/models/domain/send.ts
Normal file
108
common/src/models/domain/send.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { CryptoService } from '../../abstractions/crypto.service';
|
||||
|
||||
import { SendType } from '../../enums/sendType';
|
||||
|
||||
import { Utils } from '../../misc/utils';
|
||||
|
||||
import { SendData } from '../data/sendData';
|
||||
|
||||
import { SendView } from '../view/sendView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SendFile } from './sendFile';
|
||||
import { SendText } from './sendText';
|
||||
|
||||
export class Send extends Domain {
|
||||
id: string;
|
||||
accessId: string;
|
||||
userId: string;
|
||||
type: SendType;
|
||||
name: EncString;
|
||||
notes: EncString;
|
||||
file: SendFile;
|
||||
text: SendText;
|
||||
key: EncString;
|
||||
maxAccessCount?: number;
|
||||
accessCount: number;
|
||||
revisionDate: Date;
|
||||
expirationDate: Date;
|
||||
deletionDate: Date;
|
||||
password: string;
|
||||
disabled: boolean;
|
||||
hideEmail: boolean;
|
||||
|
||||
constructor(obj?: SendData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
accessId: null,
|
||||
userId: null,
|
||||
name: null,
|
||||
notes: null,
|
||||
key: null,
|
||||
}, alreadyEncrypted, ['id', 'accessId', 'userId']);
|
||||
|
||||
this.type = obj.type;
|
||||
this.maxAccessCount = obj.maxAccessCount;
|
||||
this.accessCount = obj.accessCount;
|
||||
this.password = obj.password;
|
||||
this.disabled = obj.disabled;
|
||||
this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
|
||||
this.deletionDate = obj.deletionDate != null ? new Date(obj.deletionDate) : null;
|
||||
this.expirationDate = obj.expirationDate != null ? new Date(obj.expirationDate) : null;
|
||||
this.hideEmail = obj.hideEmail;
|
||||
|
||||
switch (this.type) {
|
||||
case SendType.Text:
|
||||
this.text = new SendText(obj.text, alreadyEncrypted);
|
||||
break;
|
||||
case SendType.File:
|
||||
this.file = new SendFile(obj.file, alreadyEncrypted);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async decrypt(): Promise<SendView> {
|
||||
const model = new SendView(this);
|
||||
|
||||
let cryptoService: CryptoService;
|
||||
const containerService = (Utils.global as any).bitwardenContainerService;
|
||||
if (containerService) {
|
||||
cryptoService = containerService.getCryptoService();
|
||||
} else {
|
||||
throw new Error('global bitwardenContainerService not initialized.');
|
||||
}
|
||||
|
||||
try {
|
||||
model.key = await cryptoService.decryptToBytes(this.key, null);
|
||||
model.cryptoKey = await cryptoService.makeSendKey(model.key);
|
||||
} catch (e) {
|
||||
// TODO: error?
|
||||
}
|
||||
|
||||
await this.decryptObj(model, {
|
||||
name: null,
|
||||
notes: null,
|
||||
}, null, model.cryptoKey);
|
||||
|
||||
switch (this.type) {
|
||||
case SendType.File:
|
||||
model.file = await this.file.decrypt(model.cryptoKey);
|
||||
break;
|
||||
case SendType.Text:
|
||||
model.text = await this.text.decrypt(model.cryptoKey);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
69
common/src/models/domain/sendAccess.ts
Normal file
69
common/src/models/domain/sendAccess.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { SendType } from '../../enums/sendType';
|
||||
|
||||
import { SendAccessResponse } from '../response/sendAccessResponse';
|
||||
|
||||
import { SendAccessView } from '../view/sendAccessView';
|
||||
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SendFile } from './sendFile';
|
||||
import { SendText } from './sendText';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
export class SendAccess extends Domain {
|
||||
id: string;
|
||||
type: SendType;
|
||||
name: EncString;
|
||||
file: SendFile;
|
||||
text: SendText;
|
||||
expirationDate: Date;
|
||||
creatorIdentifier: string;
|
||||
|
||||
constructor(obj?: SendAccessResponse, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
name: null,
|
||||
expirationDate: null,
|
||||
creatorIdentifier: null,
|
||||
}, alreadyEncrypted, ['id', 'expirationDate', 'creatorIdentifier']);
|
||||
|
||||
this.type = obj.type;
|
||||
|
||||
switch (this.type) {
|
||||
case SendType.Text:
|
||||
this.text = new SendText(obj.text, alreadyEncrypted);
|
||||
break;
|
||||
case SendType.File:
|
||||
this.file = new SendFile(obj.file, alreadyEncrypted);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async decrypt(key: SymmetricCryptoKey): Promise<SendAccessView> {
|
||||
const model = new SendAccessView(this);
|
||||
|
||||
await this.decryptObj(model, {
|
||||
name: null,
|
||||
}, null, key);
|
||||
|
||||
switch (this.type) {
|
||||
case SendType.File:
|
||||
model.file = await this.file.decrypt(key);
|
||||
break;
|
||||
case SendType.Text:
|
||||
model.text = await this.text.decrypt(key);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
35
common/src/models/domain/sendFile.ts
Normal file
35
common/src/models/domain/sendFile.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
import { SendFileData } from '../data/sendFileData';
|
||||
|
||||
import { SendFileView } from '../view/sendFileView';
|
||||
|
||||
export class SendFile extends Domain {
|
||||
id: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
fileName: EncString;
|
||||
|
||||
constructor(obj?: SendFileData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.size = obj.size;
|
||||
this.buildDomainModel(this, obj, {
|
||||
id: null,
|
||||
sizeName: null,
|
||||
fileName: null,
|
||||
}, alreadyEncrypted, ['id', 'sizeName']);
|
||||
}
|
||||
|
||||
async decrypt(key: SymmetricCryptoKey): Promise<SendFileView> {
|
||||
const view = await this.decryptObj(new SendFileView(this), {
|
||||
fileName: null,
|
||||
}, null, key);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
30
common/src/models/domain/sendText.ts
Normal file
30
common/src/models/domain/sendText.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import Domain from './domainBase';
|
||||
import { EncString } from './encString';
|
||||
import { SymmetricCryptoKey } from './symmetricCryptoKey';
|
||||
|
||||
import { SendTextData } from '../data/sendTextData';
|
||||
|
||||
import { SendTextView } from '../view/sendTextView';
|
||||
|
||||
export class SendText extends Domain {
|
||||
text: EncString;
|
||||
hidden: boolean;
|
||||
|
||||
constructor(obj?: SendTextData, alreadyEncrypted: boolean = false) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hidden = obj.hidden;
|
||||
this.buildDomainModel(this, obj, {
|
||||
text: null,
|
||||
}, alreadyEncrypted, []);
|
||||
}
|
||||
|
||||
decrypt(key: SymmetricCryptoKey): Promise<SendTextView> {
|
||||
return this.decryptObj(new SendTextView(this), {
|
||||
text: null,
|
||||
}, null, key);
|
||||
}
|
||||
}
|
||||
82
common/src/models/domain/sortedCiphersCache.ts
Normal file
82
common/src/models/domain/sortedCiphersCache.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { CipherView } from '../view';
|
||||
|
||||
const CacheTTL = 3000;
|
||||
|
||||
export class SortedCiphersCache {
|
||||
private readonly sortedCiphersByUrl: Map<string, Ciphers> = new Map<string, Ciphers>();
|
||||
private readonly timeouts: Map<string, any> = new Map<string, any>();
|
||||
|
||||
constructor(private readonly comparator: (a: CipherView, b: CipherView) => number) { }
|
||||
|
||||
isCached(url: string) {
|
||||
return this.sortedCiphersByUrl.has(url);
|
||||
}
|
||||
|
||||
addCiphers(url: string, ciphers: CipherView[]) {
|
||||
ciphers.sort(this.comparator);
|
||||
this.sortedCiphersByUrl.set(url, new Ciphers(ciphers));
|
||||
this.resetTimer(url);
|
||||
}
|
||||
|
||||
getLastUsed(url: string) {
|
||||
this.resetTimer(url);
|
||||
return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getLastUsed() : null;
|
||||
}
|
||||
|
||||
getLastLaunched(url: string) {
|
||||
return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getLastLaunched() : null;
|
||||
}
|
||||
|
||||
getNext(url: string) {
|
||||
this.resetTimer(url);
|
||||
return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getNext() : null;
|
||||
}
|
||||
|
||||
updateLastUsedIndex(url: string) {
|
||||
if (this.isCached(url)) {
|
||||
this.sortedCiphersByUrl.get(url).updateLastUsedIndex();
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.sortedCiphersByUrl.clear();
|
||||
this.timeouts.clear();
|
||||
}
|
||||
|
||||
private resetTimer(url: string) {
|
||||
clearTimeout(this.timeouts.get(url));
|
||||
this.timeouts.set(url, setTimeout(() => {
|
||||
this.sortedCiphersByUrl.delete(url);
|
||||
this.timeouts.delete(url);
|
||||
}, CacheTTL));
|
||||
}
|
||||
}
|
||||
|
||||
class Ciphers {
|
||||
lastUsedIndex = -1;
|
||||
|
||||
constructor(private readonly ciphers: CipherView[]) { }
|
||||
|
||||
getLastUsed() {
|
||||
this.lastUsedIndex = Math.max(this.lastUsedIndex, 0);
|
||||
return this.ciphers[this.lastUsedIndex];
|
||||
}
|
||||
|
||||
getLastLaunched() {
|
||||
const usedCiphers = this.ciphers.filter(cipher => cipher.localData?.lastLaunched);
|
||||
const sortedCiphers = usedCiphers.sort((x, y) => y.localData.lastLaunched.valueOf() - x.localData.lastLaunched.valueOf());
|
||||
return sortedCiphers[0];
|
||||
}
|
||||
|
||||
getNextIndex() {
|
||||
return (this.lastUsedIndex + 1) % this.ciphers.length;
|
||||
}
|
||||
|
||||
getNext() {
|
||||
return this.ciphers[this.getNextIndex()];
|
||||
}
|
||||
|
||||
updateLastUsedIndex() {
|
||||
this.lastUsedIndex = this.getNextIndex();
|
||||
}
|
||||
}
|
||||
58
common/src/models/domain/symmetricCryptoKey.ts
Normal file
58
common/src/models/domain/symmetricCryptoKey.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { EncryptionType } from '../../enums/encryptionType';
|
||||
|
||||
import { Utils } from '../../misc/utils';
|
||||
|
||||
export class SymmetricCryptoKey {
|
||||
key: ArrayBuffer;
|
||||
encKey?: ArrayBuffer;
|
||||
macKey?: ArrayBuffer;
|
||||
encType: EncryptionType;
|
||||
|
||||
keyB64: string;
|
||||
encKeyB64: string;
|
||||
macKeyB64: string;
|
||||
|
||||
meta: any;
|
||||
|
||||
constructor(key: ArrayBuffer, encType?: EncryptionType) {
|
||||
if (key == null) {
|
||||
throw new Error('Must provide key');
|
||||
}
|
||||
|
||||
if (encType == null) {
|
||||
if (key.byteLength === 32) {
|
||||
encType = EncryptionType.AesCbc256_B64;
|
||||
} else if (key.byteLength === 64) {
|
||||
encType = EncryptionType.AesCbc256_HmacSha256_B64;
|
||||
} else {
|
||||
throw new Error('Unable to determine encType.');
|
||||
}
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.encType = encType;
|
||||
|
||||
if (encType === EncryptionType.AesCbc256_B64 && key.byteLength === 32) {
|
||||
this.encKey = key;
|
||||
this.macKey = null;
|
||||
} else if (encType === EncryptionType.AesCbc128_HmacSha256_B64 && key.byteLength === 32) {
|
||||
this.encKey = key.slice(0, 16);
|
||||
this.macKey = key.slice(16, 32);
|
||||
} else if (encType === EncryptionType.AesCbc256_HmacSha256_B64 && key.byteLength === 64) {
|
||||
this.encKey = key.slice(0, 32);
|
||||
this.macKey = key.slice(32, 64);
|
||||
} else {
|
||||
throw new Error('Unsupported encType/key length.');
|
||||
}
|
||||
|
||||
if (this.key != null) {
|
||||
this.keyB64 = Utils.fromBufferToB64(this.key);
|
||||
}
|
||||
if (this.encKey != null) {
|
||||
this.encKeyB64 = Utils.fromBufferToB64(this.encKey);
|
||||
}
|
||||
if (this.macKey != null) {
|
||||
this.macKeyB64 = Utils.fromBufferToB64(this.macKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
common/src/models/domain/treeNode.ts
Normal file
16
common/src/models/domain/treeNode.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export class TreeNode<T extends ITreeNodeObject> {
|
||||
parent: T;
|
||||
node: T;
|
||||
children: TreeNode<T>[] = [];
|
||||
|
||||
constructor(node: T, name: string, parent: T) {
|
||||
this.parent = parent;
|
||||
this.node = node;
|
||||
this.node.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITreeNodeObject {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
66
common/src/models/export/card.ts
Normal file
66
common/src/models/export/card.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { CardView } from '../view/cardView';
|
||||
|
||||
import { Card as CardDomain } from '../domain/card';
|
||||
import { EncString } from '../domain/encString';
|
||||
|
||||
export class Card {
|
||||
static template(): Card {
|
||||
const req = new Card();
|
||||
req.cardholderName = 'John Doe';
|
||||
req.brand = 'visa';
|
||||
req.number = '4242424242424242';
|
||||
req.expMonth = '04';
|
||||
req.expYear = '2023';
|
||||
req.code = '123';
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Card, view = new CardView()) {
|
||||
view.cardholderName = req.cardholderName;
|
||||
view.brand = req.brand;
|
||||
view.number = req.number;
|
||||
view.expMonth = req.expMonth;
|
||||
view.expYear = req.expYear;
|
||||
view.code = req.code;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Card, domain = new CardDomain()) {
|
||||
domain.cardholderName = req.cardholderName != null ? new EncString(req.cardholderName) : null;
|
||||
domain.brand = req.brand != null ? new EncString(req.brand) : null;
|
||||
domain.number = req.number != null ? new EncString(req.number) : null;
|
||||
domain.expMonth = req.expMonth != null ? new EncString(req.expMonth) : null;
|
||||
domain.expYear = req.expYear != null ? new EncString(req.expYear) : null;
|
||||
domain.code = req.code != null ? new EncString(req.code) : null;
|
||||
return domain;
|
||||
}
|
||||
|
||||
cardholderName: string;
|
||||
brand: string;
|
||||
number: string;
|
||||
expMonth: string;
|
||||
expYear: string;
|
||||
code: string;
|
||||
|
||||
constructor(o?: CardView | CardDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o instanceof CardView) {
|
||||
this.cardholderName = o.cardholderName;
|
||||
this.brand = o.brand;
|
||||
this.number = o.number;
|
||||
this.expMonth = o.expMonth;
|
||||
this.expYear = o.expYear;
|
||||
this.code = o.code;
|
||||
} else {
|
||||
this.cardholderName = o.cardholderName?.encryptedString;
|
||||
this.brand = o.brand?.encryptedString;
|
||||
this.number = o.number?.encryptedString;
|
||||
this.expMonth = o.expMonth?.encryptedString;
|
||||
this.expYear = o.expYear?.encryptedString;
|
||||
this.code = o.code?.encryptedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
158
common/src/models/export/cipher.ts
Normal file
158
common/src/models/export/cipher.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { CipherRepromptType } from '../../enums/cipherRepromptType';
|
||||
import { CipherType } from '../../enums/cipherType';
|
||||
|
||||
import { CipherView } from '../view/cipherView';
|
||||
|
||||
import { Cipher as CipherDomain } from '../domain/cipher';
|
||||
import { EncString } from '../domain/encString';
|
||||
|
||||
import { Card } from './card';
|
||||
import { Field } from './field';
|
||||
import { Identity } from './identity';
|
||||
import { Login } from './login';
|
||||
import { SecureNote } from './secureNote';
|
||||
|
||||
export class Cipher {
|
||||
static template(): Cipher {
|
||||
const req = new Cipher();
|
||||
req.organizationId = null;
|
||||
req.collectionIds = null;
|
||||
req.folderId = null;
|
||||
req.type = CipherType.Login;
|
||||
req.name = 'Item name';
|
||||
req.notes = 'Some notes about this item.';
|
||||
req.favorite = false;
|
||||
req.fields = [];
|
||||
req.login = null;
|
||||
req.secureNote = null;
|
||||
req.card = null;
|
||||
req.identity = null;
|
||||
req.reprompt = CipherRepromptType.None;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Cipher, view = new CipherView()) {
|
||||
view.type = req.type;
|
||||
view.folderId = req.folderId;
|
||||
if (view.organizationId == null) {
|
||||
view.organizationId = req.organizationId;
|
||||
}
|
||||
if (view.collectionIds || req.collectionIds) {
|
||||
const set = new Set((view.collectionIds ?? []).concat(req.collectionIds ?? []));
|
||||
view.collectionIds = Array.from(set.values());
|
||||
}
|
||||
view.name = req.name;
|
||||
view.notes = req.notes;
|
||||
view.favorite = req.favorite;
|
||||
view.reprompt = req.reprompt ?? CipherRepromptType.None;
|
||||
|
||||
if (req.fields != null) {
|
||||
view.fields = req.fields.map(f => Field.toView(f));
|
||||
}
|
||||
|
||||
switch (req.type) {
|
||||
case CipherType.Login:
|
||||
view.login = Login.toView(req.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
view.secureNote = SecureNote.toView(req.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
view.card = Card.toView(req.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
view.identity = Identity.toView(req.identity);
|
||||
break;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Cipher, domain = new CipherDomain()) {
|
||||
domain.type = req.type;
|
||||
domain.folderId = req.folderId;
|
||||
if (domain.organizationId == null) {
|
||||
domain.organizationId = req.organizationId;
|
||||
}
|
||||
domain.name = req.name != null ? new EncString(req.name) : null;
|
||||
domain.notes = req.notes != null ? new EncString(req.notes) : null;
|
||||
domain.favorite = req.favorite;
|
||||
domain.reprompt = req.reprompt ?? CipherRepromptType.None;
|
||||
|
||||
if (req.fields != null) {
|
||||
domain.fields = req.fields.map(f => Field.toDomain(f));
|
||||
}
|
||||
|
||||
switch (req.type) {
|
||||
case CipherType.Login:
|
||||
domain.login = Login.toDomain(req.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
domain.secureNote = SecureNote.toDomain(req.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
domain.card = Card.toDomain(req.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
domain.identity = Identity.toDomain(req.identity);
|
||||
break;
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
type: CipherType;
|
||||
folderId: string;
|
||||
organizationId: string;
|
||||
collectionIds: string[];
|
||||
name: string;
|
||||
notes: string;
|
||||
favorite: boolean;
|
||||
fields: Field[];
|
||||
login: Login;
|
||||
secureNote: SecureNote;
|
||||
card: Card;
|
||||
identity: Identity;
|
||||
reprompt: CipherRepromptType;
|
||||
|
||||
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
||||
build(o: CipherView | CipherDomain) {
|
||||
this.organizationId = o.organizationId;
|
||||
this.folderId = o.folderId;
|
||||
this.type = o.type;
|
||||
this.reprompt = o.reprompt;
|
||||
|
||||
if (o instanceof CipherView) {
|
||||
this.name = o.name;
|
||||
this.notes = o.notes;
|
||||
} else {
|
||||
this.name = o.name?.encryptedString;
|
||||
this.notes = o.notes?.encryptedString;
|
||||
}
|
||||
|
||||
this.favorite = o.favorite;
|
||||
|
||||
if (o.fields != null) {
|
||||
if (o instanceof CipherView) {
|
||||
this.fields = o.fields.map(f => new Field(f));
|
||||
} else {
|
||||
this.fields = o.fields.map(f => new Field(f));
|
||||
}
|
||||
}
|
||||
|
||||
switch (o.type) {
|
||||
case CipherType.Login:
|
||||
this.login = new Login(o.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
this.secureNote = new SecureNote(o.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
this.card = new Card(o.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
this.identity = new Identity(o.identity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
common/src/models/export/cipherWithIds.ts
Normal file
17
common/src/models/export/cipherWithIds.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Cipher } from './cipher';
|
||||
|
||||
import { CipherView } from '../view/cipherView';
|
||||
|
||||
import { Cipher as CipherDomain } from '../domain/cipher';
|
||||
|
||||
export class CipherWithIds extends Cipher {
|
||||
id: string;
|
||||
collectionIds: string[];
|
||||
|
||||
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
||||
build(o: CipherView | CipherDomain) {
|
||||
this.id = o.id;
|
||||
super.build(o);
|
||||
this.collectionIds = o.collectionIds;
|
||||
}
|
||||
}
|
||||
47
common/src/models/export/collection.ts
Normal file
47
common/src/models/export/collection.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { CollectionView } from '../view/collectionView';
|
||||
|
||||
import { Collection as CollectionDomain } from '../domain/collection';
|
||||
import { EncString } from '../domain/encString';
|
||||
|
||||
export class Collection {
|
||||
static template(): Collection {
|
||||
const req = new Collection();
|
||||
req.organizationId = '00000000-0000-0000-0000-000000000000';
|
||||
req.name = 'Collection name';
|
||||
req.externalId = null;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Collection, view = new CollectionView()) {
|
||||
view.name = req.name;
|
||||
view.externalId = req.externalId;
|
||||
if (view.organizationId == null) {
|
||||
view.organizationId = req.organizationId;
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Collection, domain = new CollectionDomain()) {
|
||||
domain.name = req.name != null ? new EncString(req.name) : null;
|
||||
domain.externalId = req.externalId;
|
||||
if (domain.organizationId == null) {
|
||||
domain.organizationId = req.organizationId;
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
organizationId: string;
|
||||
name: string;
|
||||
externalId: string;
|
||||
|
||||
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
||||
build(o: CollectionView | CollectionDomain) {
|
||||
this.organizationId = o.organizationId;
|
||||
if (o instanceof CollectionView) {
|
||||
this.name = o.name;
|
||||
} else {
|
||||
this.name = o.name?.encryptedString;
|
||||
}
|
||||
this.externalId = o.externalId;
|
||||
}
|
||||
}
|
||||
15
common/src/models/export/collectionWithId.ts
Normal file
15
common/src/models/export/collectionWithId.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Collection } from './collection';
|
||||
|
||||
import { CollectionView } from '../view/collectionView';
|
||||
|
||||
import { Collection as CollectionDomain } from '../domain/collection';
|
||||
|
||||
export class CollectionWithId extends Collection {
|
||||
id: string;
|
||||
|
||||
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
||||
build(o: CollectionView | CollectionDomain) {
|
||||
this.id = o.id;
|
||||
super.build(o);
|
||||
}
|
||||
}
|
||||
26
common/src/models/export/event.ts
Normal file
26
common/src/models/export/event.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { EventType } from '../../enums/eventType';
|
||||
import { EventView } from '../view/eventView';
|
||||
|
||||
export class Event {
|
||||
message: string;
|
||||
appIcon: string;
|
||||
appName: string;
|
||||
userId: string;
|
||||
userName: string;
|
||||
userEmail: string;
|
||||
date: string;
|
||||
ip: string;
|
||||
type: string;
|
||||
|
||||
constructor(event: EventView) {
|
||||
this.message = event.humanReadableMessage;
|
||||
this.appIcon = event.appIcon;
|
||||
this.appName = event.appName;
|
||||
this.userId = event.userId;
|
||||
this.userName = event.userName;
|
||||
this.userEmail = event.userEmail;
|
||||
this.date = event.date;
|
||||
this.ip = event.ip;
|
||||
this.type = EventType[event.type];
|
||||
}
|
||||
}
|
||||
49
common/src/models/export/field.ts
Normal file
49
common/src/models/export/field.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { FieldType } from '../../enums/fieldType';
|
||||
|
||||
import { FieldView } from '../view/fieldView';
|
||||
|
||||
import { EncString } from '../domain/encString';
|
||||
import { Field as FieldDomain } from '../domain/field';
|
||||
|
||||
export class Field {
|
||||
static template(): Field {
|
||||
const req = new Field();
|
||||
req.name = 'Field name';
|
||||
req.value = 'Some value';
|
||||
req.type = FieldType.Text;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Field, view = new FieldView()) {
|
||||
view.type = req.type;
|
||||
view.value = req.value;
|
||||
view.name = req.name;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Field, domain = new FieldDomain()) {
|
||||
domain.type = req.type;
|
||||
domain.value = req.value != null ? new EncString(req.value) : null;
|
||||
domain.name = req.name != null ? new EncString(req.name) : null;
|
||||
return domain;
|
||||
}
|
||||
|
||||
name: string;
|
||||
value: string;
|
||||
type: FieldType;
|
||||
|
||||
constructor(o?: FieldView | FieldDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o instanceof FieldView) {
|
||||
this.name = o.name;
|
||||
this.value = o.value;
|
||||
} else {
|
||||
this.name = o.name?.encryptedString;
|
||||
this.value = o.value?.encryptedString;
|
||||
}
|
||||
this.type = o.type;
|
||||
}
|
||||
}
|
||||
33
common/src/models/export/folder.ts
Normal file
33
common/src/models/export/folder.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { FolderView } from '../view/folderView';
|
||||
|
||||
import { EncString } from '../domain/encString';
|
||||
import { Folder as FolderDomain } from '../domain/folder';
|
||||
|
||||
export class Folder {
|
||||
static template(): Folder {
|
||||
const req = new Folder();
|
||||
req.name = 'Folder name';
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Folder, view = new FolderView()) {
|
||||
view.name = req.name;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Folder, domain = new FolderDomain()) {
|
||||
domain.name = req.name != null ? new EncString(req.name) : null;
|
||||
return domain;
|
||||
}
|
||||
|
||||
name: string;
|
||||
|
||||
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
||||
build(o: FolderView | FolderDomain) {
|
||||
if (o instanceof FolderView) {
|
||||
this.name = o.name;
|
||||
} else {
|
||||
this.name = o.name?.encryptedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
common/src/models/export/folderWithId.ts
Normal file
15
common/src/models/export/folderWithId.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Folder } from './folder';
|
||||
|
||||
import { FolderView } from '../view/folderView';
|
||||
|
||||
import { Folder as FolderDomain } from '../domain/folder';
|
||||
|
||||
export class FolderWithId extends Folder {
|
||||
id: string;
|
||||
|
||||
// Use build method instead of ctor so that we can control order of JSON stringify for pretty print
|
||||
build(o: FolderView | FolderDomain) {
|
||||
this.id = o.id;
|
||||
super.build(o);
|
||||
}
|
||||
}
|
||||
138
common/src/models/export/identity.ts
Normal file
138
common/src/models/export/identity.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
import { IdentityView } from '../view/identityView';
|
||||
|
||||
import { EncString } from '../domain/encString';
|
||||
import { Identity as IdentityDomain } from '../domain/identity';
|
||||
|
||||
export class Identity {
|
||||
static template(): Identity {
|
||||
const req = new Identity();
|
||||
req.title = 'Mr';
|
||||
req.firstName = 'John';
|
||||
req.middleName = 'William';
|
||||
req.lastName = 'Doe';
|
||||
req.address1 = '123 Any St';
|
||||
req.address2 = 'Apt #123';
|
||||
req.address3 = null;
|
||||
req.city = 'New York';
|
||||
req.state = 'NY';
|
||||
req.postalCode = '10001';
|
||||
req.country = 'US';
|
||||
req.company = 'Acme Inc.';
|
||||
req.email = 'john@company.com';
|
||||
req.phone = '5555551234';
|
||||
req.ssn = '000-123-4567';
|
||||
req.username = 'jdoe';
|
||||
req.passportNumber = 'US-123456789';
|
||||
req.licenseNumber = 'D123-12-123-12333';
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Identity, view = new IdentityView()) {
|
||||
view.title = req.title;
|
||||
view.firstName = req.firstName;
|
||||
view.middleName = req.middleName;
|
||||
view.lastName = req.lastName;
|
||||
view.address1 = req.address1;
|
||||
view.address2 = req.address2;
|
||||
view.address3 = req.address3;
|
||||
view.city = req.city;
|
||||
view.state = req.state;
|
||||
view.postalCode = req.postalCode;
|
||||
view.country = req.country;
|
||||
view.company = req.company;
|
||||
view.email = req.email;
|
||||
view.phone = req.phone;
|
||||
view.ssn = req.ssn;
|
||||
view.username = req.username;
|
||||
view.passportNumber = req.passportNumber;
|
||||
view.licenseNumber = req.licenseNumber;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Identity, domain = new IdentityDomain()) {
|
||||
domain.title = req.title != null ? new EncString(req.title) : null;
|
||||
domain.firstName = req.firstName != null ? new EncString(req.firstName) : null;
|
||||
domain.middleName = req.middleName != null ? new EncString(req.middleName) : null;
|
||||
domain.lastName = req.lastName != null ? new EncString(req.lastName) : null;
|
||||
domain.address1 = req.address1 != null ? new EncString(req.address1) : null;
|
||||
domain.address2 = req.address2 != null ? new EncString(req.address2) : null;
|
||||
domain.address3 = req.address3 != null ? new EncString(req.address3) : null;
|
||||
domain.city = req.city != null ? new EncString(req.city) : null;
|
||||
domain.state = req.state != null ? new EncString(req.state) : null;
|
||||
domain.postalCode = req.postalCode != null ? new EncString(req.postalCode) : null;
|
||||
domain.country = req.country != null ? new EncString(req.country) : null;
|
||||
domain.company = req.company != null ? new EncString(req.company) : null;
|
||||
domain.email = req.email != null ? new EncString(req.email) : null;
|
||||
domain.phone = req.phone != null ? new EncString(req.phone) : null;
|
||||
domain.ssn = req.ssn != null ? new EncString(req.ssn) : null;
|
||||
domain.username = req.username != null ? new EncString(req.username) : null;
|
||||
domain.passportNumber = req.passportNumber != null ? new EncString(req.passportNumber) : null;
|
||||
domain.licenseNumber = req.licenseNumber != null ? new EncString(req.licenseNumber) : null;
|
||||
return domain;
|
||||
}
|
||||
|
||||
title: string;
|
||||
firstName: string;
|
||||
middleName: string;
|
||||
lastName: string;
|
||||
address1: string;
|
||||
address2: string;
|
||||
address3: string;
|
||||
city: string;
|
||||
state: string;
|
||||
postalCode: string;
|
||||
country: string;
|
||||
company: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
ssn: string;
|
||||
username: string;
|
||||
passportNumber: string;
|
||||
licenseNumber: string;
|
||||
|
||||
constructor(o?: IdentityView | IdentityDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o instanceof IdentityView) {
|
||||
this.title = o.title;
|
||||
this.firstName = o.firstName;
|
||||
this.middleName = o.middleName;
|
||||
this.lastName = o.lastName;
|
||||
this.address1 = o.address1;
|
||||
this.address2 = o.address2;
|
||||
this.address3 = o.address3;
|
||||
this.city = o.city;
|
||||
this.state = o.state;
|
||||
this.postalCode = o.postalCode;
|
||||
this.country = o.country;
|
||||
this.company = o.company;
|
||||
this.email = o.email;
|
||||
this.phone = o.phone;
|
||||
this.ssn = o.ssn;
|
||||
this.username = o.username;
|
||||
this.passportNumber = o.passportNumber;
|
||||
this.licenseNumber = o.licenseNumber;
|
||||
} else {
|
||||
this.title = o.title?.encryptedString;
|
||||
this.firstName = o.firstName?.encryptedString;
|
||||
this.middleName = o.middleName?.encryptedString;
|
||||
this.lastName = o.lastName?.encryptedString;
|
||||
this.address1 = o.address1?.encryptedString;
|
||||
this.address2 = o.address2?.encryptedString;
|
||||
this.address3 = o.address3?.encryptedString;
|
||||
this.city = o.city?.encryptedString;
|
||||
this.state = o.state?.encryptedString;
|
||||
this.postalCode = o.postalCode?.encryptedString;
|
||||
this.country = o.country?.encryptedString;
|
||||
this.company = o.company?.encryptedString;
|
||||
this.email = o.email?.encryptedString;
|
||||
this.phone = o.phone?.encryptedString;
|
||||
this.ssn = o.ssn?.encryptedString;
|
||||
this.username = o.username?.encryptedString;
|
||||
this.passportNumber = o.passportNumber?.encryptedString;
|
||||
this.licenseNumber = o.licenseNumber?.encryptedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
common/src/models/export/login.ts
Normal file
66
common/src/models/export/login.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { LoginUri } from './loginUri';
|
||||
|
||||
import { LoginView } from '../view/loginView';
|
||||
|
||||
import { EncString } from '../domain/encString';
|
||||
import { Login as LoginDomain } from '../domain/login';
|
||||
|
||||
export class Login {
|
||||
static template(): Login {
|
||||
const req = new Login();
|
||||
req.uris = [];
|
||||
req.username = 'jdoe';
|
||||
req.password = 'myp@ssword123';
|
||||
req.totp = 'JBSWY3DPEHPK3PXP';
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: Login, view = new LoginView()) {
|
||||
if (req.uris != null) {
|
||||
view.uris = req.uris.map(u => LoginUri.toView(u));
|
||||
}
|
||||
view.username = req.username;
|
||||
view.password = req.password;
|
||||
view.totp = req.totp;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: Login, domain = new LoginDomain()) {
|
||||
if (req.uris != null) {
|
||||
domain.uris = req.uris.map(u => LoginUri.toDomain(u));
|
||||
}
|
||||
domain.username = req.username != null ? new EncString(req.username) : null;
|
||||
domain.password = req.password != null ? new EncString(req.password) : null;
|
||||
domain.totp = req.totp != null ? new EncString(req.totp) : null;
|
||||
return domain;
|
||||
}
|
||||
|
||||
uris: LoginUri[];
|
||||
username: string;
|
||||
password: string;
|
||||
totp: string;
|
||||
|
||||
constructor(o?: LoginView | LoginDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o.uris != null) {
|
||||
if (o instanceof LoginView) {
|
||||
this.uris = o.uris.map(u => new LoginUri(u));
|
||||
} else {
|
||||
this.uris = o.uris.map(u => new LoginUri(u));
|
||||
}
|
||||
}
|
||||
|
||||
if (o instanceof LoginView) {
|
||||
this.username = o.username;
|
||||
this.password = o.password;
|
||||
this.totp = o.totp;
|
||||
} else {
|
||||
this.username = o.username?.encryptedString;
|
||||
this.password = o.password?.encryptedString;
|
||||
this.totp = o.totp?.encryptedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
common/src/models/export/loginUri.ts
Normal file
43
common/src/models/export/loginUri.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { UriMatchType } from '../../enums/uriMatchType';
|
||||
|
||||
import { LoginUriView } from '../view/loginUriView';
|
||||
|
||||
import { EncString } from '../domain/encString';
|
||||
import { LoginUri as LoginUriDomain } from '../domain/loginUri';
|
||||
|
||||
export class LoginUri {
|
||||
static template(): LoginUri {
|
||||
const req = new LoginUri();
|
||||
req.uri = 'https://google.com';
|
||||
req.match = null;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: LoginUri, view = new LoginUriView()) {
|
||||
view.uri = req.uri;
|
||||
view.match = req.match;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: LoginUri, domain = new LoginUriDomain()) {
|
||||
domain.uri = req.uri != null ? new EncString(req.uri) : null;
|
||||
domain.match = req.match;
|
||||
return domain;
|
||||
}
|
||||
|
||||
uri: string;
|
||||
match: UriMatchType = null;
|
||||
|
||||
constructor(o?: LoginUriView | LoginUriDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o instanceof LoginUriView) {
|
||||
this.uri = o.uri;
|
||||
} else {
|
||||
this.uri = o.uri?.encryptedString;
|
||||
}
|
||||
this.match = o.match;
|
||||
}
|
||||
}
|
||||
33
common/src/models/export/secureNote.ts
Normal file
33
common/src/models/export/secureNote.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { SecureNoteType } from '../../enums/secureNoteType';
|
||||
|
||||
import { SecureNoteView } from '../view/secureNoteView';
|
||||
|
||||
import { SecureNote as SecureNoteDomain } from '../domain/secureNote';
|
||||
|
||||
export class SecureNote {
|
||||
static template(): SecureNote {
|
||||
const req = new SecureNote();
|
||||
req.type = SecureNoteType.Generic;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: SecureNote, view = new SecureNoteView()) {
|
||||
view.type = req.type;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: SecureNote, view = new SecureNoteDomain()) {
|
||||
view.type = req.type;
|
||||
return view;
|
||||
}
|
||||
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(o?: SecureNoteView | SecureNoteDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = o.type;
|
||||
}
|
||||
}
|
||||
6
common/src/models/request/attachmentRequest.ts
Normal file
6
common/src/models/request/attachmentRequest.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export class AttachmentRequest {
|
||||
fileName: string;
|
||||
key: string;
|
||||
fileSize: number;
|
||||
adminRequest: boolean;
|
||||
}
|
||||
9
common/src/models/request/bitPayInvoiceRequest.ts
Normal file
9
common/src/models/request/bitPayInvoiceRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class BitPayInvoiceRequest {
|
||||
userId: string;
|
||||
organizationId: string;
|
||||
credit: boolean;
|
||||
amount: number;
|
||||
returnUrl: string;
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
9
common/src/models/request/cipherBulkDeleteRequest.ts
Normal file
9
common/src/models/request/cipherBulkDeleteRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class CipherBulkDeleteRequest {
|
||||
ids: string[];
|
||||
organizationId: string;
|
||||
|
||||
constructor(ids: string[], organizationId?: string) {
|
||||
this.ids = ids == null ? [] : ids;
|
||||
this.organizationId = organizationId;
|
||||
}
|
||||
}
|
||||
9
common/src/models/request/cipherBulkMoveRequest.ts
Normal file
9
common/src/models/request/cipherBulkMoveRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class CipherBulkMoveRequest {
|
||||
ids: string[];
|
||||
folderId: string;
|
||||
|
||||
constructor(ids: string[], folderId: string) {
|
||||
this.ids = ids == null ? [] : ids;
|
||||
this.folderId = folderId;
|
||||
}
|
||||
}
|
||||
7
common/src/models/request/cipherBulkRestoreRequest.ts
Normal file
7
common/src/models/request/cipherBulkRestoreRequest.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class CipherBulkRestoreRequest {
|
||||
ids: string[];
|
||||
|
||||
constructor(ids: string[]) {
|
||||
this.ids = ids == null ? [] : ids;
|
||||
}
|
||||
}
|
||||
18
common/src/models/request/cipherBulkShareRequest.ts
Normal file
18
common/src/models/request/cipherBulkShareRequest.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { CipherWithIdRequest } from './cipherWithIdRequest';
|
||||
|
||||
import { Cipher } from '../domain/cipher';
|
||||
|
||||
export class CipherBulkShareRequest {
|
||||
ciphers: CipherWithIdRequest[];
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(ciphers: Cipher[], collectionIds: string[]) {
|
||||
if (ciphers != null) {
|
||||
this.ciphers = [];
|
||||
ciphers.forEach(c => {
|
||||
this.ciphers.push(new CipherWithIdRequest(c));
|
||||
});
|
||||
}
|
||||
this.collectionIds = collectionIds;
|
||||
}
|
||||
}
|
||||
7
common/src/models/request/cipherCollectionsRequest.ts
Normal file
7
common/src/models/request/cipherCollectionsRequest.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class CipherCollectionsRequest {
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(collectionIds: string[]) {
|
||||
this.collectionIds = collectionIds == null ? [] : collectionIds;
|
||||
}
|
||||
}
|
||||
13
common/src/models/request/cipherCreateRequest.ts
Normal file
13
common/src/models/request/cipherCreateRequest.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { CipherRequest } from './cipherRequest';
|
||||
|
||||
import { Cipher } from '../domain/cipher';
|
||||
|
||||
export class CipherCreateRequest {
|
||||
cipher: CipherRequest;
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
this.cipher = new CipherRequest(cipher);
|
||||
this.collectionIds = cipher.collectionIds;
|
||||
}
|
||||
}
|
||||
151
common/src/models/request/cipherRequest.ts
Normal file
151
common/src/models/request/cipherRequest.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
import { CipherRepromptType } from '../../enums/cipherRepromptType';
|
||||
import { CipherType } from '../../enums/cipherType';
|
||||
|
||||
import { Cipher } from '../domain/cipher';
|
||||
|
||||
import { CardApi } from '../api/cardApi';
|
||||
import { FieldApi } from '../api/fieldApi';
|
||||
import { IdentityApi } from '../api/identityApi';
|
||||
import { LoginApi } from '../api/loginApi';
|
||||
import { LoginUriApi } from '../api/loginUriApi';
|
||||
import { SecureNoteApi } from '../api/secureNoteApi';
|
||||
|
||||
import { AttachmentRequest } from './attachmentRequest';
|
||||
import { PasswordHistoryRequest } from './passwordHistoryRequest';
|
||||
|
||||
export class CipherRequest {
|
||||
type: CipherType;
|
||||
folderId: string;
|
||||
organizationId: string;
|
||||
name: string;
|
||||
notes: string;
|
||||
favorite: boolean;
|
||||
login: LoginApi;
|
||||
secureNote: SecureNoteApi;
|
||||
card: CardApi;
|
||||
identity: IdentityApi;
|
||||
fields: FieldApi[];
|
||||
passwordHistory: PasswordHistoryRequest[];
|
||||
// Deprecated, remove at some point and rename attachments2 to attachments
|
||||
attachments: { [id: string]: string; };
|
||||
attachments2: { [id: string]: AttachmentRequest; };
|
||||
lastKnownRevisionDate: Date;
|
||||
reprompt: CipherRepromptType;
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
this.type = cipher.type;
|
||||
this.folderId = cipher.folderId;
|
||||
this.organizationId = cipher.organizationId;
|
||||
this.name = cipher.name ? cipher.name.encryptedString : null;
|
||||
this.notes = cipher.notes ? cipher.notes.encryptedString : null;
|
||||
this.favorite = cipher.favorite;
|
||||
this.lastKnownRevisionDate = cipher.revisionDate;
|
||||
this.reprompt = cipher.reprompt;
|
||||
|
||||
switch (this.type) {
|
||||
case CipherType.Login:
|
||||
this.login = new LoginApi();
|
||||
this.login.uris = null;
|
||||
this.login.username = cipher.login.username ? cipher.login.username.encryptedString : null;
|
||||
this.login.password = cipher.login.password ? cipher.login.password.encryptedString : null;
|
||||
this.login.passwordRevisionDate = cipher.login.passwordRevisionDate != null ?
|
||||
cipher.login.passwordRevisionDate.toISOString() : null;
|
||||
this.login.totp = cipher.login.totp ? cipher.login.totp.encryptedString : null;
|
||||
this.login.autofillOnPageLoad = cipher.login.autofillOnPageLoad;
|
||||
|
||||
if (cipher.login.uris != null) {
|
||||
this.login.uris = cipher.login.uris.map(u => {
|
||||
const uri = new LoginUriApi();
|
||||
uri.uri = u.uri != null ? u.uri.encryptedString : null;
|
||||
uri.match = u.match != null ? u.match : null;
|
||||
return uri;
|
||||
});
|
||||
}
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
this.secureNote = new SecureNoteApi();
|
||||
this.secureNote.type = cipher.secureNote.type;
|
||||
break;
|
||||
case CipherType.Card:
|
||||
this.card = new CardApi();
|
||||
this.card.cardholderName = cipher.card.cardholderName != null ?
|
||||
cipher.card.cardholderName.encryptedString : null;
|
||||
this.card.brand = cipher.card.brand != null ? cipher.card.brand.encryptedString : null;
|
||||
this.card.number = cipher.card.number != null ? cipher.card.number.encryptedString : null;
|
||||
this.card.expMonth = cipher.card.expMonth != null ? cipher.card.expMonth.encryptedString : null;
|
||||
this.card.expYear = cipher.card.expYear != null ? cipher.card.expYear.encryptedString : null;
|
||||
this.card.code = cipher.card.code != null ? cipher.card.code.encryptedString : null;
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
this.identity = new IdentityApi();
|
||||
this.identity.title = cipher.identity.title != null ? cipher.identity.title.encryptedString : null;
|
||||
this.identity.firstName = cipher.identity.firstName != null ?
|
||||
cipher.identity.firstName.encryptedString : null;
|
||||
this.identity.middleName = cipher.identity.middleName != null ?
|
||||
cipher.identity.middleName.encryptedString : null;
|
||||
this.identity.lastName = cipher.identity.lastName != null ?
|
||||
cipher.identity.lastName.encryptedString : null;
|
||||
this.identity.address1 = cipher.identity.address1 != null ?
|
||||
cipher.identity.address1.encryptedString : null;
|
||||
this.identity.address2 = cipher.identity.address2 != null ?
|
||||
cipher.identity.address2.encryptedString : null;
|
||||
this.identity.address3 = cipher.identity.address3 != null ?
|
||||
cipher.identity.address3.encryptedString : null;
|
||||
this.identity.city = cipher.identity.city != null ? cipher.identity.city.encryptedString : null;
|
||||
this.identity.state = cipher.identity.state != null ? cipher.identity.state.encryptedString : null;
|
||||
this.identity.postalCode = cipher.identity.postalCode != null ?
|
||||
cipher.identity.postalCode.encryptedString : null;
|
||||
this.identity.country = cipher.identity.country != null ?
|
||||
cipher.identity.country.encryptedString : null;
|
||||
this.identity.company = cipher.identity.company != null ?
|
||||
cipher.identity.company.encryptedString : null;
|
||||
this.identity.email = cipher.identity.email != null ? cipher.identity.email.encryptedString : null;
|
||||
this.identity.phone = cipher.identity.phone != null ? cipher.identity.phone.encryptedString : null;
|
||||
this.identity.ssn = cipher.identity.ssn != null ? cipher.identity.ssn.encryptedString : null;
|
||||
this.identity.username = cipher.identity.username != null ?
|
||||
cipher.identity.username.encryptedString : null;
|
||||
this.identity.passportNumber = cipher.identity.passportNumber != null ?
|
||||
cipher.identity.passportNumber.encryptedString : null;
|
||||
this.identity.licenseNumber = cipher.identity.licenseNumber != null ?
|
||||
cipher.identity.licenseNumber.encryptedString : null;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cipher.fields != null) {
|
||||
this.fields = cipher.fields.map(f => {
|
||||
const field = new FieldApi();
|
||||
field.type = f.type;
|
||||
field.name = f.name ? f.name.encryptedString : null;
|
||||
field.value = f.value ? f.value.encryptedString : null;
|
||||
return field;
|
||||
});
|
||||
}
|
||||
|
||||
if (cipher.passwordHistory != null) {
|
||||
this.passwordHistory = [];
|
||||
cipher.passwordHistory.forEach(ph => {
|
||||
this.passwordHistory.push({
|
||||
lastUsedDate: ph.lastUsedDate,
|
||||
password: ph.password ? ph.password.encryptedString : null,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (cipher.attachments != null) {
|
||||
this.attachments = {};
|
||||
this.attachments2 = {};
|
||||
cipher.attachments.forEach(attachment => {
|
||||
const fileName = attachment.fileName ? attachment.fileName.encryptedString : null;
|
||||
this.attachments[attachment.id] = fileName;
|
||||
const attachmentRequest = new AttachmentRequest();
|
||||
attachmentRequest.fileName = fileName;
|
||||
if (attachment.key != null) {
|
||||
attachmentRequest.key = attachment.key.encryptedString;
|
||||
}
|
||||
this.attachments2[attachment.id] = attachmentRequest;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
13
common/src/models/request/cipherShareRequest.ts
Normal file
13
common/src/models/request/cipherShareRequest.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { CipherRequest } from './cipherRequest';
|
||||
|
||||
import { Cipher } from '../domain/cipher';
|
||||
|
||||
export class CipherShareRequest {
|
||||
cipher: CipherRequest;
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
this.cipher = new CipherRequest(cipher);
|
||||
this.collectionIds = cipher.collectionIds;
|
||||
}
|
||||
}
|
||||
12
common/src/models/request/cipherWithIdRequest.ts
Normal file
12
common/src/models/request/cipherWithIdRequest.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { CipherRequest } from './cipherRequest';
|
||||
|
||||
import { Cipher } from '../domain/cipher';
|
||||
|
||||
export class CipherWithIdRequest extends CipherRequest {
|
||||
id: string;
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
super(cipher);
|
||||
this.id = cipher.id;
|
||||
}
|
||||
}
|
||||
17
common/src/models/request/collectionRequest.ts
Normal file
17
common/src/models/request/collectionRequest.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Collection } from '../domain/collection';
|
||||
|
||||
import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest';
|
||||
|
||||
export class CollectionRequest {
|
||||
name: string;
|
||||
externalId: string;
|
||||
groups: SelectionReadOnlyRequest[] = [];
|
||||
|
||||
constructor(collection?: Collection) {
|
||||
if (collection == null) {
|
||||
return;
|
||||
}
|
||||
this.name = collection.name ? collection.name.encryptedString : null;
|
||||
this.externalId = collection.externalId;
|
||||
}
|
||||
}
|
||||
3
common/src/models/request/deleteRecoverRequest.ts
Normal file
3
common/src/models/request/deleteRecoverRequest.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export class DeleteRecoverRequest {
|
||||
email: string;
|
||||
}
|
||||
17
common/src/models/request/deviceRequest.ts
Normal file
17
common/src/models/request/deviceRequest.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { DeviceType } from '../../enums/deviceType';
|
||||
|
||||
import { PlatformUtilsService } from '../../abstractions/platformUtils.service';
|
||||
|
||||
export class DeviceRequest {
|
||||
type: DeviceType;
|
||||
name: string;
|
||||
identifier: string;
|
||||
pushToken?: string;
|
||||
|
||||
constructor(appId: string, platformUtilsService: PlatformUtilsService) {
|
||||
this.type = platformUtilsService.getDevice();
|
||||
this.name = platformUtilsService.getDeviceString();
|
||||
this.identifier = appId;
|
||||
this.pushToken = null;
|
||||
}
|
||||
}
|
||||
7
common/src/models/request/deviceTokenRequest.ts
Normal file
7
common/src/models/request/deviceTokenRequest.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class DeviceTokenRequest {
|
||||
pushToken: string;
|
||||
|
||||
constructor() {
|
||||
this.pushToken = null;
|
||||
}
|
||||
}
|
||||
7
common/src/models/request/emailRequest.ts
Normal file
7
common/src/models/request/emailRequest.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { EmailTokenRequest } from './emailTokenRequest';
|
||||
|
||||
export class EmailRequest extends EmailTokenRequest {
|
||||
newMasterPasswordHash: string;
|
||||
token: string;
|
||||
key: string;
|
||||
}
|
||||
6
common/src/models/request/emailTokenRequest.ts
Normal file
6
common/src/models/request/emailTokenRequest.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { PasswordVerificationRequest } from './passwordVerificationRequest';
|
||||
|
||||
export class EmailTokenRequest extends PasswordVerificationRequest {
|
||||
newEmail: string;
|
||||
masterPasswordHash: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export class EmergencyAccessAcceptRequest {
|
||||
token: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export class EmergencyAccessConfirmRequest {
|
||||
key: string;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { EmergencyAccessType } from '../../enums/emergencyAccessType';
|
||||
|
||||
export class EmergencyAccessInviteRequest {
|
||||
email: string;
|
||||
type: EmergencyAccessType;
|
||||
waitTimeDays: number;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export class EmergencyAccessPasswordRequest {
|
||||
newMasterPasswordHash: string;
|
||||
key: string;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { EmergencyAccessType } from '../../enums/emergencyAccessType';
|
||||
|
||||
export class EmergencyAccessUpdateRequest {
|
||||
type: EmergencyAccessType;
|
||||
waitTimeDays: number;
|
||||
keyEncrypted?: string;
|
||||
}
|
||||
7
common/src/models/request/eventRequest.ts
Normal file
7
common/src/models/request/eventRequest.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { EventType } from '../../enums/eventType';
|
||||
|
||||
export class EventRequest {
|
||||
type: EventType;
|
||||
cipherId: string;
|
||||
date: string;
|
||||
}
|
||||
9
common/src/models/request/folderRequest.ts
Normal file
9
common/src/models/request/folderRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Folder } from '../domain/folder';
|
||||
|
||||
export class FolderRequest {
|
||||
name: string;
|
||||
|
||||
constructor(folder: Folder) {
|
||||
this.name = folder.name ? folder.name.encryptedString : null;
|
||||
}
|
||||
}
|
||||
12
common/src/models/request/folderWithIdRequest.ts
Normal file
12
common/src/models/request/folderWithIdRequest.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { FolderRequest } from './folderRequest';
|
||||
|
||||
import { Folder } from '../domain/folder';
|
||||
|
||||
export class FolderWithIdRequest extends FolderRequest {
|
||||
id: string;
|
||||
|
||||
constructor(folder: Folder) {
|
||||
super(folder);
|
||||
this.id = folder.id;
|
||||
}
|
||||
}
|
||||
8
common/src/models/request/groupRequest.ts
Normal file
8
common/src/models/request/groupRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest';
|
||||
|
||||
export class GroupRequest {
|
||||
name: string;
|
||||
accessAll: boolean;
|
||||
externalId: string;
|
||||
collections: SelectionReadOnlyRequest[] = [];
|
||||
}
|
||||
5
common/src/models/request/iapCheckRequest.ts
Normal file
5
common/src/models/request/iapCheckRequest.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { PaymentMethodType } from '../../enums/paymentMethodType';
|
||||
|
||||
export class IapCheckRequest {
|
||||
paymentMethodType: PaymentMethodType;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user