mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
Move to libs
This commit is contained in:
13
libs/common/src/models/api/billingSyncConfigApi.ts
Normal file
13
libs/common/src/models/api/billingSyncConfigApi.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
export class BillingSyncConfigApi extends BaseResponse {
|
||||
billingSyncKey: string;
|
||||
|
||||
constructor(data: any) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.billingSyncKey = this.getResponseProperty("BillingSyncKey");
|
||||
}
|
||||
}
|
||||
23
libs/common/src/models/api/cardApi.ts
Normal file
23
libs/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");
|
||||
}
|
||||
}
|
||||
21
libs/common/src/models/api/fieldApi.ts
Normal file
21
libs/common/src/models/api/fieldApi.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { FieldType } from "../../enums/fieldType";
|
||||
import { LinkedIdType } from "../../enums/linkedIdType";
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
export class FieldApi extends BaseResponse {
|
||||
name: string;
|
||||
value: string;
|
||||
type: FieldType;
|
||||
linkedId: LinkedIdType;
|
||||
|
||||
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");
|
||||
this.linkedId = this.getResponseProperty("linkedId");
|
||||
}
|
||||
}
|
||||
47
libs/common/src/models/api/identityApi.ts
Normal file
47
libs/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
libs/common/src/models/api/loginApi.ts
Normal file
29
libs/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));
|
||||
}
|
||||
}
|
||||
}
|
||||
17
libs/common/src/models/api/loginUriApi.ts
Normal file
17
libs/common/src/models/api/loginUriApi.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { UriMatchType } from "../../enums/uriMatchType";
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
55
libs/common/src/models/api/permissionsApi.ts
Normal file
55
libs/common/src/models/api/permissionsApi.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
export class PermissionsApi extends BaseResponse {
|
||||
accessEventLogs: boolean;
|
||||
accessImportExport: boolean;
|
||||
accessReports: boolean;
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `createNewCollections`, `editAnyCollection`, and
|
||||
* `deleteAnyCollection`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
manageAllCollections: boolean;
|
||||
createNewCollections: boolean;
|
||||
editAnyCollection: boolean;
|
||||
deleteAnyCollection: boolean;
|
||||
/**
|
||||
* @deprecated Sep 29 2021: This permission has been split out to `editAssignedCollections` and
|
||||
* `deleteAssignedCollections`. It exists here for backwards compatibility with Server versions <= 1.43.0
|
||||
*/
|
||||
manageAssignedCollections: boolean;
|
||||
editAssignedCollections: boolean;
|
||||
deleteAssignedCollections: 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.accessEventLogs = this.getResponseProperty("AccessEventLogs");
|
||||
this.accessImportExport = this.getResponseProperty("AccessImportExport");
|
||||
this.accessReports = this.getResponseProperty("AccessReports");
|
||||
|
||||
// For backwards compatibility with Server <= 1.43.0
|
||||
this.manageAllCollections = this.getResponseProperty("ManageAllCollections");
|
||||
this.manageAssignedCollections = this.getResponseProperty("ManageAssignedCollections");
|
||||
|
||||
this.createNewCollections = this.getResponseProperty("CreateNewCollections");
|
||||
this.editAnyCollection = this.getResponseProperty("EditAnyCollection");
|
||||
this.deleteAnyCollection = this.getResponseProperty("DeleteAnyCollection");
|
||||
this.editAssignedCollections = this.getResponseProperty("EditAssignedCollections");
|
||||
this.deleteAssignedCollections = this.getResponseProperty("DeleteAssignedCollections");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
14
libs/common/src/models/api/secureNoteApi.ts
Normal file
14
libs/common/src/models/api/secureNoteApi.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { SecureNoteType } from "../../enums/secureNoteType";
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
export class SecureNoteApi extends BaseResponse {
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
this.type = this.getResponseProperty("Type");
|
||||
}
|
||||
}
|
||||
19
libs/common/src/models/api/sendFileApi.ts
Normal file
19
libs/common/src/models/api/sendFileApi.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
|
||||
export class SendFileApi extends BaseResponse {
|
||||
id: string;
|
||||
fileName: 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.size = this.getResponseProperty("Size");
|
||||
this.sizeName = this.getResponseProperty("SizeName");
|
||||
}
|
||||
}
|
||||
15
libs/common/src/models/api/sendTextApi.ts
Normal file
15
libs/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;
|
||||
}
|
||||
}
|
||||
136
libs/common/src/models/api/ssoConfigApi.ts
Normal file
136
libs/common/src/models/api/ssoConfigApi.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import {
|
||||
OpenIdConnectRedirectBehavior,
|
||||
Saml2BindingType,
|
||||
Saml2NameIdFormat,
|
||||
Saml2SigningBehavior,
|
||||
SsoType,
|
||||
} from "../../enums/ssoEnums";
|
||||
import { BaseResponse } from "../response/baseResponse";
|
||||
import { SsoConfigView } from "../view/ssoConfigView";
|
||||
|
||||
export class SsoConfigApi extends BaseResponse {
|
||||
static fromView(view: SsoConfigView, api = new SsoConfigApi()) {
|
||||
api.configType = view.configType;
|
||||
|
||||
api.keyConnectorEnabled = view.keyConnectorEnabled;
|
||||
api.keyConnectorUrl = view.keyConnectorUrl;
|
||||
|
||||
if (api.configType === SsoType.OpenIdConnect) {
|
||||
api.authority = view.openId.authority;
|
||||
api.clientId = view.openId.clientId;
|
||||
api.clientSecret = view.openId.clientSecret;
|
||||
api.metadataAddress = view.openId.metadataAddress;
|
||||
api.redirectBehavior = view.openId.redirectBehavior;
|
||||
api.getClaimsFromUserInfoEndpoint = view.openId.getClaimsFromUserInfoEndpoint;
|
||||
api.additionalScopes = view.openId.additionalScopes;
|
||||
api.additionalUserIdClaimTypes = view.openId.additionalUserIdClaimTypes;
|
||||
api.additionalEmailClaimTypes = view.openId.additionalEmailClaimTypes;
|
||||
api.additionalNameClaimTypes = view.openId.additionalNameClaimTypes;
|
||||
api.acrValues = view.openId.acrValues;
|
||||
api.expectedReturnAcrValue = view.openId.expectedReturnAcrValue;
|
||||
} else if (api.configType === SsoType.Saml2) {
|
||||
api.spNameIdFormat = view.saml.spNameIdFormat;
|
||||
api.spOutboundSigningAlgorithm = view.saml.spOutboundSigningAlgorithm;
|
||||
api.spSigningBehavior = view.saml.spSigningBehavior;
|
||||
api.spMinIncomingSigningAlgorithm = view.saml.spMinIncomingSigningAlgorithm;
|
||||
api.spWantAssertionsSigned = view.saml.spWantAssertionsSigned;
|
||||
api.spValidateCertificates = view.saml.spValidateCertificates;
|
||||
|
||||
api.idpEntityId = view.saml.idpEntityId;
|
||||
api.idpBindingType = view.saml.idpBindingType;
|
||||
api.idpSingleSignOnServiceUrl = view.saml.idpSingleSignOnServiceUrl;
|
||||
api.idpSingleLogoutServiceUrl = view.saml.idpSingleLogoutServiceUrl;
|
||||
api.idpX509PublicCert = view.saml.idpX509PublicCert;
|
||||
api.idpOutboundSigningAlgorithm = view.saml.idpOutboundSigningAlgorithm;
|
||||
api.idpAllowUnsolicitedAuthnResponse = view.saml.idpAllowUnsolicitedAuthnResponse;
|
||||
api.idpWantAuthnRequestsSigned = view.saml.idpWantAuthnRequestsSigned;
|
||||
|
||||
// Value is inverted in the api model (disable instead of allow)
|
||||
api.idpDisableOutboundLogoutRequests = !view.saml.idpAllowOutboundLogoutRequests;
|
||||
}
|
||||
|
||||
return api;
|
||||
}
|
||||
configType: SsoType;
|
||||
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
// OpenId
|
||||
authority: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
metadataAddress: string;
|
||||
redirectBehavior: OpenIdConnectRedirectBehavior;
|
||||
getClaimsFromUserInfoEndpoint: boolean;
|
||||
additionalScopes: string;
|
||||
additionalUserIdClaimTypes: string;
|
||||
additionalEmailClaimTypes: string;
|
||||
additionalNameClaimTypes: string;
|
||||
acrValues: string;
|
||||
expectedReturnAcrValue: string;
|
||||
|
||||
// SAML
|
||||
spNameIdFormat: Saml2NameIdFormat;
|
||||
spOutboundSigningAlgorithm: string;
|
||||
spSigningBehavior: Saml2SigningBehavior;
|
||||
spMinIncomingSigningAlgorithm: boolean;
|
||||
spWantAssertionsSigned: boolean;
|
||||
spValidateCertificates: boolean;
|
||||
|
||||
idpEntityId: string;
|
||||
idpBindingType: Saml2BindingType;
|
||||
idpSingleSignOnServiceUrl: string;
|
||||
idpSingleLogoutServiceUrl: string;
|
||||
idpX509PublicCert: string;
|
||||
idpOutboundSigningAlgorithm: string;
|
||||
idpAllowUnsolicitedAuthnResponse: boolean;
|
||||
idpDisableOutboundLogoutRequests: boolean;
|
||||
idpWantAuthnRequestsSigned: boolean;
|
||||
|
||||
constructor(data: any = null) {
|
||||
super(data);
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.configType = this.getResponseProperty("ConfigType");
|
||||
|
||||
this.keyConnectorEnabled = this.getResponseProperty("KeyConnectorEnabled");
|
||||
this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
|
||||
|
||||
this.authority = this.getResponseProperty("Authority");
|
||||
this.clientId = this.getResponseProperty("ClientId");
|
||||
this.clientSecret = this.getResponseProperty("ClientSecret");
|
||||
this.metadataAddress = this.getResponseProperty("MetadataAddress");
|
||||
this.redirectBehavior = this.getResponseProperty("RedirectBehavior");
|
||||
this.getClaimsFromUserInfoEndpoint = this.getResponseProperty("GetClaimsFromUserInfoEndpoint");
|
||||
this.additionalScopes = this.getResponseProperty("AdditionalScopes");
|
||||
this.additionalUserIdClaimTypes = this.getResponseProperty("AdditionalUserIdClaimTypes");
|
||||
this.additionalEmailClaimTypes = this.getResponseProperty("AdditionalEmailClaimTypes");
|
||||
this.additionalNameClaimTypes = this.getResponseProperty("AdditionalNameClaimTypes");
|
||||
this.acrValues = this.getResponseProperty("AcrValues");
|
||||
this.expectedReturnAcrValue = this.getResponseProperty("ExpectedReturnAcrValue");
|
||||
|
||||
this.spNameIdFormat = this.getResponseProperty("SpNameIdFormat");
|
||||
this.spOutboundSigningAlgorithm = this.getResponseProperty("SpOutboundSigningAlgorithm");
|
||||
this.spSigningBehavior = this.getResponseProperty("SpSigningBehavior");
|
||||
this.spMinIncomingSigningAlgorithm = this.getResponseProperty("SpMinIncomingSigningAlgorithm");
|
||||
this.spWantAssertionsSigned = this.getResponseProperty("SpWantAssertionsSigned");
|
||||
this.spValidateCertificates = this.getResponseProperty("SpValidateCertificates");
|
||||
|
||||
this.idpEntityId = this.getResponseProperty("IdpEntityId");
|
||||
this.idpBindingType = this.getResponseProperty("IdpBindingType");
|
||||
this.idpSingleSignOnServiceUrl = this.getResponseProperty("IdpSingleSignOnServiceUrl");
|
||||
this.idpSingleLogoutServiceUrl = this.getResponseProperty("IdpSingleLogoutServiceUrl");
|
||||
this.idpX509PublicCert = this.getResponseProperty("IdpX509PublicCert");
|
||||
this.idpOutboundSigningAlgorithm = this.getResponseProperty("IdpOutboundSigningAlgorithm");
|
||||
this.idpAllowUnsolicitedAuthnResponse = this.getResponseProperty(
|
||||
"IdpAllowUnsolicitedAuthnResponse"
|
||||
);
|
||||
this.idpDisableOutboundLogoutRequests = this.getResponseProperty(
|
||||
"IdpDisableOutboundLogoutRequests"
|
||||
);
|
||||
this.idpWantAuthnRequestsSigned = this.getResponseProperty("IdpWantAuthnRequestsSigned");
|
||||
}
|
||||
}
|
||||
22
libs/common/src/models/data/attachmentData.ts
Normal file
22
libs/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
libs/common/src/models/data/cardData.ts
Normal file
23
libs/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;
|
||||
}
|
||||
}
|
||||
83
libs/common/src/models/data/cipherData.ts
Normal file
83
libs/common/src/models/data/cipherData.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { CipherRepromptType } from "../../enums/cipherRepromptType";
|
||||
import { CipherType } from "../../enums/cipherType";
|
||||
import { CipherResponse } from "../response/cipherResponse";
|
||||
|
||||
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";
|
||||
|
||||
export class CipherData {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
folderId: string;
|
||||
edit: boolean;
|
||||
viewPassword: boolean;
|
||||
organizationUseTotp: boolean;
|
||||
favorite: boolean;
|
||||
revisionDate: string;
|
||||
type: CipherType;
|
||||
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, collectionIds?: string[]) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = response.id;
|
||||
this.organizationId = response.organizationId;
|
||||
this.folderId = response.folderId;
|
||||
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
libs/common/src/models/data/collectionData.ts
Normal file
17
libs/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
libs/common/src/models/data/eventData.ts
Normal file
7
libs/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;
|
||||
}
|
||||
20
libs/common/src/models/data/fieldData.ts
Normal file
20
libs/common/src/models/data/fieldData.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { FieldType } from "../../enums/fieldType";
|
||||
import { LinkedIdType } from "../../enums/linkedIdType";
|
||||
import { FieldApi } from "../api/fieldApi";
|
||||
|
||||
export class FieldData {
|
||||
type: FieldType;
|
||||
name: string;
|
||||
value: string;
|
||||
linkedId: LinkedIdType;
|
||||
|
||||
constructor(response?: FieldApi) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
this.type = response.type;
|
||||
this.name = response.name;
|
||||
this.value = response.value;
|
||||
this.linkedId = response.linkedId;
|
||||
}
|
||||
}
|
||||
13
libs/common/src/models/data/folderData.ts
Normal file
13
libs/common/src/models/data/folderData.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { FolderResponse } from "../response/folderResponse";
|
||||
|
||||
export class FolderData {
|
||||
id: string;
|
||||
name: string;
|
||||
revisionDate: string;
|
||||
|
||||
constructor(response: FolderResponse) {
|
||||
this.name = response.name;
|
||||
this.id = response.id;
|
||||
this.revisionDate = response.revisionDate;
|
||||
}
|
||||
}
|
||||
47
libs/common/src/models/data/identityData.ts
Normal file
47
libs/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;
|
||||
}
|
||||
}
|
||||
28
libs/common/src/models/data/loginData.ts
Normal file
28
libs/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));
|
||||
}
|
||||
}
|
||||
}
|
||||
15
libs/common/src/models/data/loginUriData.ts
Normal file
15
libs/common/src/models/data/loginUriData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
84
libs/common/src/models/data/organizationData.ts
Normal file
84
libs/common/src/models/data/organizationData.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
import { ProfileOrganizationResponse } from "../response/profileOrganizationResponse";
|
||||
|
||||
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;
|
||||
useSso: boolean;
|
||||
useKeyConnector: 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;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
isProviderUser: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
familySponsorshipLastSyncDate?: Date;
|
||||
familySponsorshipValidUntil?: Date;
|
||||
familySponsorshipToDelete?: 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.useSso = response.useSso;
|
||||
this.useKeyConnector = response.useKeyConnector;
|
||||
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;
|
||||
this.providerId = response.providerId;
|
||||
this.providerName = response.providerName;
|
||||
this.familySponsorshipFriendlyName = response.familySponsorshipFriendlyName;
|
||||
this.familySponsorshipAvailable = response.familySponsorshipAvailable;
|
||||
this.planProductType = response.planProductType;
|
||||
this.keyConnectorEnabled = response.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = response.keyConnectorUrl;
|
||||
this.familySponsorshipLastSyncDate = response.familySponsorshipLastSyncDate;
|
||||
this.familySponsorshipValidUntil = response.familySponsorshipValidUntil;
|
||||
this.familySponsorshipToDelete = response.familySponsorshipToDelete;
|
||||
}
|
||||
}
|
||||
15
libs/common/src/models/data/passwordHistoryData.ts
Normal file
15
libs/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;
|
||||
}
|
||||
}
|
||||
18
libs/common/src/models/data/policyData.ts
Normal file
18
libs/common/src/models/data/policyData.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { PolicyType } from "../../enums/policyType";
|
||||
import { PolicyResponse } from "../response/policyResponse";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
23
libs/common/src/models/data/providerData.ts
Normal file
23
libs/common/src/models/data/providerData.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ProviderUserStatusType } from "../../enums/providerUserStatusType";
|
||||
import { ProviderUserType } from "../../enums/providerUserType";
|
||||
import { ProfileProviderResponse } from "../response/profileProviderResponse";
|
||||
|
||||
export class ProviderData {
|
||||
id: string;
|
||||
name: string;
|
||||
status: ProviderUserStatusType;
|
||||
type: ProviderUserType;
|
||||
enabled: boolean;
|
||||
userId: string;
|
||||
useEvents: boolean;
|
||||
|
||||
constructor(response: ProfileProviderResponse) {
|
||||
this.id = response.id;
|
||||
this.name = response.name;
|
||||
this.status = response.status;
|
||||
this.type = response.type;
|
||||
this.enabled = response.enabled;
|
||||
this.userId = response.userId;
|
||||
this.useEvents = response.useEvents;
|
||||
}
|
||||
}
|
||||
14
libs/common/src/models/data/secureNoteData.ts
Normal file
14
libs/common/src/models/data/secureNoteData.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
56
libs/common/src/models/data/sendData.ts
Normal file
56
libs/common/src/models/data/sendData.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { SendType } from "../../enums/sendType";
|
||||
import { SendResponse } from "../response/sendResponse";
|
||||
|
||||
import { SendFileData } from "./sendFileData";
|
||||
import { SendTextData } from "./sendTextData";
|
||||
|
||||
export class SendData {
|
||||
id: string;
|
||||
accessId: 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) {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = response.id;
|
||||
this.accessId = response.accessId;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
libs/common/src/models/data/sendFileData.ts
Normal file
19
libs/common/src/models/data/sendFileData.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { SendFileApi } from "../api/sendFileApi";
|
||||
|
||||
export class SendFileData {
|
||||
id: string;
|
||||
fileName: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
|
||||
constructor(data?: SendFileApi) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.id = data.id;
|
||||
this.fileName = data.fileName;
|
||||
this.size = data.size;
|
||||
this.sizeName = data.sizeName;
|
||||
}
|
||||
}
|
||||
15
libs/common/src/models/data/sendTextData.ts
Normal file
15
libs/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;
|
||||
}
|
||||
}
|
||||
175
libs/common/src/models/domain/account.ts
Normal file
175
libs/common/src/models/domain/account.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
import { AuthenticationStatus } from "../../enums/authenticationStatus";
|
||||
import { KdfType } from "../../enums/kdfType";
|
||||
import { UriMatchType } from "../../enums/uriMatchType";
|
||||
import { CipherData } from "../data/cipherData";
|
||||
import { CollectionData } from "../data/collectionData";
|
||||
import { EventData } from "../data/eventData";
|
||||
import { FolderData } from "../data/folderData";
|
||||
import { OrganizationData } from "../data/organizationData";
|
||||
import { PolicyData } from "../data/policyData";
|
||||
import { ProviderData } from "../data/providerData";
|
||||
import { SendData } from "../data/sendData";
|
||||
import { CipherView } from "../view/cipherView";
|
||||
import { CollectionView } from "../view/collectionView";
|
||||
import { FolderView } from "../view/folderView";
|
||||
import { SendView } from "../view/sendView";
|
||||
|
||||
import { EncString } from "./encString";
|
||||
import { EnvironmentUrls } from "./environmentUrls";
|
||||
import { GeneratedPasswordHistory } from "./generatedPasswordHistory";
|
||||
import { Policy } from "./policy";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class EncryptionPair<TEncrypted, TDecrypted> {
|
||||
encrypted?: TEncrypted;
|
||||
decrypted?: TDecrypted;
|
||||
}
|
||||
|
||||
export class DataEncryptionPair<TEncrypted, TDecrypted> {
|
||||
encrypted?: { [id: string]: TEncrypted };
|
||||
decrypted?: TDecrypted[];
|
||||
}
|
||||
|
||||
export class AccountData {
|
||||
ciphers?: DataEncryptionPair<CipherData, CipherView> = new DataEncryptionPair<
|
||||
CipherData,
|
||||
CipherView
|
||||
>();
|
||||
folders?: DataEncryptionPair<FolderData, FolderView> = new DataEncryptionPair<
|
||||
FolderData,
|
||||
FolderView
|
||||
>();
|
||||
localData?: any;
|
||||
sends?: DataEncryptionPair<SendData, SendView> = new DataEncryptionPair<SendData, SendView>();
|
||||
collections?: DataEncryptionPair<CollectionData, CollectionView> = new DataEncryptionPair<
|
||||
CollectionData,
|
||||
CollectionView
|
||||
>();
|
||||
policies?: DataEncryptionPair<PolicyData, Policy> = new DataEncryptionPair<PolicyData, Policy>();
|
||||
passwordGenerationHistory?: EncryptionPair<
|
||||
GeneratedPasswordHistory[],
|
||||
GeneratedPasswordHistory[]
|
||||
> = new EncryptionPair<GeneratedPasswordHistory[], GeneratedPasswordHistory[]>();
|
||||
addEditCipherInfo?: any;
|
||||
eventCollection?: EventData[];
|
||||
organizations?: { [id: string]: OrganizationData };
|
||||
providers?: { [id: string]: ProviderData };
|
||||
}
|
||||
|
||||
export class AccountKeys {
|
||||
cryptoMasterKey?: SymmetricCryptoKey;
|
||||
cryptoMasterKeyAuto?: string;
|
||||
cryptoMasterKeyB64?: string;
|
||||
cryptoMasterKeyBiometric?: string;
|
||||
cryptoSymmetricKey?: EncryptionPair<string, SymmetricCryptoKey> = new EncryptionPair<
|
||||
string,
|
||||
SymmetricCryptoKey
|
||||
>();
|
||||
organizationKeys?: EncryptionPair<any, Map<string, SymmetricCryptoKey>> = new EncryptionPair<
|
||||
any,
|
||||
Map<string, SymmetricCryptoKey>
|
||||
>();
|
||||
providerKeys?: EncryptionPair<any, Map<string, SymmetricCryptoKey>> = new EncryptionPair<
|
||||
any,
|
||||
Map<string, SymmetricCryptoKey>
|
||||
>();
|
||||
privateKey?: EncryptionPair<string, ArrayBuffer> = new EncryptionPair<string, ArrayBuffer>();
|
||||
legacyEtmKey?: SymmetricCryptoKey;
|
||||
publicKey?: ArrayBuffer;
|
||||
apiKeyClientSecret?: string;
|
||||
}
|
||||
|
||||
export class AccountProfile {
|
||||
apiKeyClientId?: string;
|
||||
authenticationStatus?: AuthenticationStatus;
|
||||
convertAccountToKeyConnector?: boolean;
|
||||
email?: string;
|
||||
emailVerified?: boolean;
|
||||
entityId?: string;
|
||||
entityType?: string;
|
||||
everBeenUnlocked?: boolean;
|
||||
forcePasswordReset?: boolean;
|
||||
hasPremiumPersonally?: boolean;
|
||||
lastSync?: string;
|
||||
userId?: string;
|
||||
usesKeyConnector?: boolean;
|
||||
keyHash?: string;
|
||||
kdfIterations?: number;
|
||||
kdfType?: KdfType;
|
||||
}
|
||||
|
||||
export class AccountSettings {
|
||||
autoConfirmFingerPrints?: boolean;
|
||||
autoFillOnPageLoadDefault?: boolean;
|
||||
biometricLocked?: boolean;
|
||||
biometricUnlock?: boolean;
|
||||
clearClipboard?: number;
|
||||
collapsedGroupings?: string[];
|
||||
defaultUriMatch?: UriMatchType;
|
||||
disableAddLoginNotification?: boolean;
|
||||
disableAutoBiometricsPrompt?: boolean;
|
||||
disableAutoTotpCopy?: boolean;
|
||||
disableBadgeCounter?: boolean;
|
||||
disableChangedPasswordNotification?: boolean;
|
||||
disableContextMenuItem?: boolean;
|
||||
disableGa?: boolean;
|
||||
dontShowCardsCurrentTab?: boolean;
|
||||
dontShowIdentitiesCurrentTab?: boolean;
|
||||
enableAlwaysOnTop?: boolean;
|
||||
enableAutoFillOnPageLoad?: boolean;
|
||||
enableBiometric?: boolean;
|
||||
enableFullWidth?: boolean;
|
||||
enableGravitars?: boolean;
|
||||
environmentUrls: EnvironmentUrls = new EnvironmentUrls();
|
||||
equivalentDomains?: any;
|
||||
minimizeOnCopyToClipboard?: boolean;
|
||||
neverDomains?: { [id: string]: any };
|
||||
passwordGenerationOptions?: any;
|
||||
usernameGenerationOptions?: any;
|
||||
generatorOptions?: any;
|
||||
pinProtected?: EncryptionPair<string, EncString> = new EncryptionPair<string, EncString>();
|
||||
protectedPin?: string;
|
||||
settings?: any; // TODO: Merge whatever is going on here into the AccountSettings model properly
|
||||
vaultTimeout?: number;
|
||||
vaultTimeoutAction?: string = "lock";
|
||||
}
|
||||
|
||||
export class AccountTokens {
|
||||
accessToken?: string;
|
||||
decodedToken?: any;
|
||||
refreshToken?: string;
|
||||
securityStamp?: string;
|
||||
}
|
||||
|
||||
export class Account {
|
||||
data?: AccountData = new AccountData();
|
||||
keys?: AccountKeys = new AccountKeys();
|
||||
profile?: AccountProfile = new AccountProfile();
|
||||
settings?: AccountSettings = new AccountSettings();
|
||||
tokens?: AccountTokens = new AccountTokens();
|
||||
|
||||
constructor(init: Partial<Account>) {
|
||||
Object.assign(this, {
|
||||
data: {
|
||||
...new AccountData(),
|
||||
...init?.data,
|
||||
},
|
||||
keys: {
|
||||
...new AccountKeys(),
|
||||
...init?.keys,
|
||||
},
|
||||
profile: {
|
||||
...new AccountProfile(),
|
||||
...init?.profile,
|
||||
},
|
||||
settings: {
|
||||
...new AccountSettings(),
|
||||
...init?.settings,
|
||||
},
|
||||
tokens: {
|
||||
...new AccountTokens(),
|
||||
...init?.tokens,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
87
libs/common/src/models/domain/attachment.ts
Normal file
87
libs/common/src/models/domain/attachment.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { CryptoService } from "../../abstractions/crypto.service";
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { AttachmentData } from "../data/attachmentData";
|
||||
import { AttachmentView } from "../view/attachmentView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class Attachment extends Domain {
|
||||
id: string;
|
||||
url: string;
|
||||
size: string;
|
||||
sizeName: string; // Readable size, ex: "4.2 KB" or "1.43 GB"
|
||||
key: EncString;
|
||||
fileName: EncString;
|
||||
|
||||
constructor(obj?: AttachmentData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.size = obj.size;
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
url: null,
|
||||
sizeName: null,
|
||||
fileName: null,
|
||||
key: null,
|
||||
},
|
||||
["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;
|
||||
}
|
||||
}
|
||||
17
libs/common/src/models/domain/authResult.ts
Normal file
17
libs/common/src/models/domain/authResult.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { TwoFactorProviderType } from "../../enums/twoFactorProviderType";
|
||||
import { Utils } from "../../misc/utils";
|
||||
|
||||
export class AuthResult {
|
||||
captchaSiteKey = "";
|
||||
resetMasterPassword = false;
|
||||
forcePasswordReset = false;
|
||||
twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string }> = null;
|
||||
|
||||
get requiresCaptcha() {
|
||||
return !Utils.isNullOrWhitespace(this.captchaSiteKey);
|
||||
}
|
||||
|
||||
get requiresTwoFactor() {
|
||||
return this.twoFactorProviders != null;
|
||||
}
|
||||
}
|
||||
65
libs/common/src/models/domain/card.ts
Normal file
65
libs/common/src/models/domain/card.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { CardData } from "../data/cardData";
|
||||
import { CardView } from "../view/cardView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class Card extends Domain {
|
||||
cardholderName: EncString;
|
||||
brand: EncString;
|
||||
number: EncString;
|
||||
expMonth: EncString;
|
||||
expYear: EncString;
|
||||
code: EncString;
|
||||
|
||||
constructor(obj?: CardData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
cardholderName: null,
|
||||
brand: null,
|
||||
number: null,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
code: null,
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<CardView> {
|
||||
return this.decryptObj(
|
||||
new CardView(),
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
236
libs/common/src/models/domain/cipher.ts
Normal file
236
libs/common/src/models/domain/cipher.ts
Normal file
@@ -0,0 +1,236 @@
|
||||
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, localData: any = null) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
organizationId: null,
|
||||
folderId: null,
|
||||
name: null,
|
||||
notes: null,
|
||||
},
|
||||
["id", "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);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
this.secureNote = new SecureNote(obj.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
this.card = new Card(obj.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
this.identity = new Identity(obj.identity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj.attachments != null) {
|
||||
this.attachments = obj.attachments.map((a) => new Attachment(a));
|
||||
} else {
|
||||
this.attachments = null;
|
||||
}
|
||||
|
||||
if (obj.fields != null) {
|
||||
this.fields = obj.fields.map((f) => new Field(f));
|
||||
} else {
|
||||
this.fields = null;
|
||||
}
|
||||
|
||||
if (obj.passwordHistory != null) {
|
||||
this.passwordHistory = obj.passwordHistory.map((ph) => new Password(ph));
|
||||
} 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(): CipherData {
|
||||
const c = new CipherData();
|
||||
c.id = this.id;
|
||||
c.organizationId = this.organizationId;
|
||||
c.folderId = this.folderId;
|
||||
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;
|
||||
}
|
||||
}
|
||||
45
libs/common/src/models/domain/collection.ts
Normal file
45
libs/common/src/models/domain/collection.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
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) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
organizationId: null,
|
||||
name: null,
|
||||
externalId: null,
|
||||
readOnly: null,
|
||||
hidePasswords: null,
|
||||
},
|
||||
["id", "organizationId", "externalId", "readOnly", "hidePasswords"]
|
||||
);
|
||||
}
|
||||
|
||||
decrypt(): Promise<CollectionView> {
|
||||
return this.decryptObj(
|
||||
new CollectionView(this),
|
||||
{
|
||||
name: null,
|
||||
},
|
||||
this.organizationId
|
||||
);
|
||||
}
|
||||
}
|
||||
8
libs/common/src/models/domain/decryptParameters.ts
Normal file
8
libs/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;
|
||||
}
|
||||
82
libs/common/src/models/domain/domainBase.ts
Normal file
82
libs/common/src/models/domain/domainBase.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { View } from "../view/view";
|
||||
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export default class Domain {
|
||||
protected buildDomainModel<D extends Domain>(
|
||||
domain: D,
|
||||
dataObj: any,
|
||||
map: any,
|
||||
notEncList: any[] = []
|
||||
) {
|
||||
for (const prop in map) {
|
||||
// eslint-disable-next-line
|
||||
if (!map.hasOwnProperty(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const objProp = dataObj[map[prop] || prop];
|
||||
if (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) {
|
||||
// eslint-disable-next-line
|
||||
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) {
|
||||
// eslint-disable-next-line
|
||||
if (!map.hasOwnProperty(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(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
libs/common/src/models/domain/encArrayBuffer.ts
Normal file
3
libs/common/src/models/domain/encArrayBuffer.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export class EncArrayBuffer {
|
||||
constructor(public buffer: ArrayBuffer) {}
|
||||
}
|
||||
122
libs/common/src/models/domain/encString.ts
Normal file
122
libs/common/src/models/domain/encString.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { CryptoService } from "../../abstractions/crypto.service";
|
||||
import { EncryptionType } from "../../enums/encryptionType";
|
||||
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
libs/common/src/models/domain/encryptedObject.ts
Normal file
8
libs/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;
|
||||
}
|
||||
10
libs/common/src/models/domain/environmentUrls.ts
Normal file
10
libs/common/src/models/domain/environmentUrls.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export class EnvironmentUrls {
|
||||
base: string = null;
|
||||
api: string = null;
|
||||
identity: string = null;
|
||||
icons: string = null;
|
||||
notifications: string = null;
|
||||
events: string = null;
|
||||
webVault: string = null;
|
||||
keyConnector: string = null;
|
||||
}
|
||||
62
libs/common/src/models/domain/field.ts
Normal file
62
libs/common/src/models/domain/field.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { FieldType } from "../../enums/fieldType";
|
||||
import { LinkedIdType } from "../../enums/linkedIdType";
|
||||
import { FieldData } from "../data/fieldData";
|
||||
import { FieldView } from "../view/fieldView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class Field extends Domain {
|
||||
name: EncString;
|
||||
value: EncString;
|
||||
type: FieldType;
|
||||
linkedId: LinkedIdType;
|
||||
|
||||
constructor(obj?: FieldData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = obj.type;
|
||||
this.linkedId = obj.linkedId;
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
name: null,
|
||||
value: null,
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
linkedId: null,
|
||||
},
|
||||
["type", "linkedId"]
|
||||
);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
40
libs/common/src/models/domain/folder.ts
Normal file
40
libs/common/src/models/domain/folder.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
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) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
name: null,
|
||||
},
|
||||
["id"]
|
||||
);
|
||||
|
||||
this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
|
||||
}
|
||||
|
||||
decrypt(): Promise<FolderView> {
|
||||
return this.decryptObj(
|
||||
new FolderView(this),
|
||||
{
|
||||
name: null,
|
||||
},
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export class GeneratedPasswordHistory {
|
||||
password: string;
|
||||
date: number;
|
||||
|
||||
constructor(password: string, date: number) {
|
||||
this.password = password;
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
40
libs/common/src/models/domain/globalState.ts
Normal file
40
libs/common/src/models/domain/globalState.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { StateVersion } from "../../enums/stateVersion";
|
||||
import { ThemeType } from "../../enums/themeType";
|
||||
|
||||
import { EnvironmentUrls } from "./environmentUrls";
|
||||
import { WindowState } from "./windowState";
|
||||
|
||||
export class GlobalState {
|
||||
enableAlwaysOnTop?: boolean;
|
||||
installedVersion?: string;
|
||||
locale?: string;
|
||||
organizationInvitation?: any;
|
||||
ssoCodeVerifier?: string;
|
||||
ssoOrganizationIdentifier?: string;
|
||||
ssoState?: string;
|
||||
rememberedEmail?: string;
|
||||
theme?: ThemeType = ThemeType.System;
|
||||
window?: WindowState = new WindowState();
|
||||
twoFactorToken?: string;
|
||||
disableFavicon?: boolean;
|
||||
biometricAwaitingAcceptance?: boolean;
|
||||
biometricFingerprintValidated?: boolean;
|
||||
vaultTimeout?: number;
|
||||
vaultTimeoutAction?: string;
|
||||
loginRedirect?: any;
|
||||
mainWindowSize?: number;
|
||||
enableBiometrics?: boolean;
|
||||
biometricText?: string;
|
||||
noAutoPromptBiometrics?: boolean;
|
||||
noAutoPromptBiometricsText?: string;
|
||||
stateVersion: StateVersion = StateVersion.One;
|
||||
environmentUrls: EnvironmentUrls = new EnvironmentUrls();
|
||||
enableTray?: boolean;
|
||||
enableMinimizeToTray?: boolean;
|
||||
enableCloseToTray?: boolean;
|
||||
enableStartToTray?: boolean;
|
||||
openAtLogin?: boolean;
|
||||
alwaysShowDock?: boolean;
|
||||
enableBrowserIntegration?: boolean;
|
||||
enableBrowserIntegrationFingerprint?: boolean;
|
||||
}
|
||||
113
libs/common/src/models/domain/identity.ts
Normal file
113
libs/common/src/models/domain/identity.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { IdentityData } from "../data/identityData";
|
||||
import { IdentityView } from "../view/identityView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
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) {
|
||||
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,
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<IdentityView> {
|
||||
return this.decryptObj(
|
||||
new IdentityView(),
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
14
libs/common/src/models/domain/importResult.ts
Normal file
14
libs/common/src/models/domain/importResult.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { CipherView } from "../view/cipherView";
|
||||
import { CollectionView } from "../view/collectionView";
|
||||
import { FolderView } from "../view/folderView";
|
||||
|
||||
export class ImportResult {
|
||||
success = false;
|
||||
missingPassword = false;
|
||||
errorMessage: string;
|
||||
ciphers: CipherView[] = [];
|
||||
folders: FolderView[] = [];
|
||||
folderRelationships: [number, number][] = [];
|
||||
collections: CollectionView[] = [];
|
||||
collectionRelationships: [number, number][] = [];
|
||||
}
|
||||
31
libs/common/src/models/domain/logInCredentials.ts
Normal file
31
libs/common/src/models/domain/logInCredentials.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { AuthenticationType } from "../../enums/authenticationType";
|
||||
import { TokenRequestTwoFactor } from "../request/identityToken/tokenRequestTwoFactor";
|
||||
|
||||
export class PasswordLogInCredentials {
|
||||
readonly type = AuthenticationType.Password;
|
||||
|
||||
constructor(
|
||||
public email: string,
|
||||
public masterPassword: string,
|
||||
public captchaToken?: string,
|
||||
public twoFactor?: TokenRequestTwoFactor
|
||||
) {}
|
||||
}
|
||||
|
||||
export class SsoLogInCredentials {
|
||||
readonly type = AuthenticationType.Sso;
|
||||
|
||||
constructor(
|
||||
public code: string,
|
||||
public codeVerifier: string,
|
||||
public redirectUrl: string,
|
||||
public orgId: string,
|
||||
public twoFactor?: TokenRequestTwoFactor
|
||||
) {}
|
||||
}
|
||||
|
||||
export class ApiLogInCredentials {
|
||||
readonly type = AuthenticationType.Api;
|
||||
|
||||
constructor(public clientId: string, public clientSecret: string) {}
|
||||
}
|
||||
88
libs/common/src/models/domain/login.ts
Normal file
88
libs/common/src/models/domain/login.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { LoginData } from "../data/loginData";
|
||||
import { LoginView } from "../view/loginView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { LoginUri } from "./loginUri";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class Login extends Domain {
|
||||
uris: LoginUri[];
|
||||
username: EncString;
|
||||
password: EncString;
|
||||
passwordRevisionDate?: Date;
|
||||
totp: EncString;
|
||||
autofillOnPageLoad: boolean;
|
||||
|
||||
constructor(obj?: LoginData) {
|
||||
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,
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
if (obj.uris) {
|
||||
this.uris = [];
|
||||
obj.uris.forEach((u) => {
|
||||
this.uris.push(new LoginUri(u));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
54
libs/common/src/models/domain/loginUri.ts
Normal file
54
libs/common/src/models/domain/loginUri.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
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) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.match = obj.match;
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
uri: null,
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
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: null,
|
||||
},
|
||||
["match"]
|
||||
);
|
||||
return u;
|
||||
}
|
||||
}
|
||||
10
libs/common/src/models/domain/masterPasswordPolicyOptions.ts
Normal file
10
libs/common/src/models/domain/masterPasswordPolicyOptions.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import Domain from "./domainBase";
|
||||
|
||||
export class MasterPasswordPolicyOptions extends Domain {
|
||||
minComplexity = 0;
|
||||
minLength = 0;
|
||||
requireUpper = false;
|
||||
requireLower = false;
|
||||
requireNumbers = false;
|
||||
requireSpecial = false;
|
||||
}
|
||||
222
libs/common/src/models/domain/organization.ts
Normal file
222
libs/common/src/models/domain/organization.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
import { OrganizationUserStatusType } from "../../enums/organizationUserStatusType";
|
||||
import { OrganizationUserType } from "../../enums/organizationUserType";
|
||||
import { Permissions } from "../../enums/permissions";
|
||||
import { ProductType } from "../../enums/productType";
|
||||
import { PermissionsApi } from "../api/permissionsApi";
|
||||
import { OrganizationData } from "../data/organizationData";
|
||||
|
||||
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;
|
||||
useSso: boolean;
|
||||
useKeyConnector: 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;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
isProviderUser: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
familySponsorshipLastSyncDate?: Date;
|
||||
familySponsorshipValidUntil?: Date;
|
||||
familySponsorshipToDelete?: 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.useSso = obj.useSso;
|
||||
this.useKeyConnector = obj.useKeyConnector;
|
||||
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;
|
||||
this.providerId = obj.providerId;
|
||||
this.providerName = obj.providerName;
|
||||
this.isProviderUser = obj.isProviderUser;
|
||||
this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName;
|
||||
this.familySponsorshipAvailable = obj.familySponsorshipAvailable;
|
||||
this.planProductType = obj.planProductType;
|
||||
this.keyConnectorEnabled = obj.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = obj.keyConnectorUrl;
|
||||
this.familySponsorshipLastSyncDate = obj.familySponsorshipLastSyncDate;
|
||||
this.familySponsorshipValidUntil = obj.familySponsorshipValidUntil;
|
||||
this.familySponsorshipToDelete = obj.familySponsorshipToDelete;
|
||||
}
|
||||
|
||||
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 || this.isProviderUser;
|
||||
}
|
||||
|
||||
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 canCreateNewCollections() {
|
||||
return (
|
||||
this.isManager ||
|
||||
(this.permissions.createNewCollections ?? this.permissions.manageAllCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canEditAnyCollection() {
|
||||
return (
|
||||
this.isAdmin || (this.permissions.editAnyCollection ?? this.permissions.manageAllCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canDeleteAnyCollection() {
|
||||
return (
|
||||
this.isAdmin ||
|
||||
(this.permissions.deleteAnyCollection ?? this.permissions.manageAllCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canViewAllCollections() {
|
||||
return this.canCreateNewCollections || this.canEditAnyCollection || this.canDeleteAnyCollection;
|
||||
}
|
||||
|
||||
get canEditAssignedCollections() {
|
||||
return (
|
||||
this.isManager ||
|
||||
(this.permissions.editAssignedCollections ?? this.permissions.manageAssignedCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canDeleteAssignedCollections() {
|
||||
return (
|
||||
this.isManager ||
|
||||
(this.permissions.deleteAssignedCollections ?? this.permissions.manageAssignedCollections)
|
||||
);
|
||||
}
|
||||
|
||||
get canViewAssignedCollections() {
|
||||
return this.canDeleteAssignedCollections || this.canEditAssignedCollections;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
get isExemptFromPolicies() {
|
||||
return this.canManagePolicies;
|
||||
}
|
||||
|
||||
hasAnyPermission(permissions: Permissions[]) {
|
||||
const specifiedPermissions =
|
||||
(permissions.includes(Permissions.AccessEventLogs) && this.canAccessEventLogs) ||
|
||||
(permissions.includes(Permissions.AccessImportExport) && this.canAccessImportExport) ||
|
||||
(permissions.includes(Permissions.AccessReports) && this.canAccessReports) ||
|
||||
(permissions.includes(Permissions.CreateNewCollections) && this.canCreateNewCollections) ||
|
||||
(permissions.includes(Permissions.EditAnyCollection) && this.canEditAnyCollection) ||
|
||||
(permissions.includes(Permissions.DeleteAnyCollection) && this.canDeleteAnyCollection) ||
|
||||
(permissions.includes(Permissions.EditAssignedCollections) &&
|
||||
this.canEditAssignedCollections) ||
|
||||
(permissions.includes(Permissions.DeleteAssignedCollections) &&
|
||||
this.canDeleteAssignedCollections) ||
|
||||
(permissions.includes(Permissions.ManageGroups) && this.canManageGroups) ||
|
||||
(permissions.includes(Permissions.ManageOrganization) && this.isOwner) ||
|
||||
(permissions.includes(Permissions.ManagePolicies) && this.canManagePolicies) ||
|
||||
(permissions.includes(Permissions.ManageUsers) && this.canManageUsers) ||
|
||||
(permissions.includes(Permissions.ManageUsersPassword) && this.canManageUsersPassword) ||
|
||||
(permissions.includes(Permissions.ManageSso) && this.canManageSso) ||
|
||||
(permissions.includes(Permissions.ManageBilling) && this.canManageBilling);
|
||||
|
||||
return specifiedPermissions && (this.enabled || this.isOwner);
|
||||
}
|
||||
|
||||
get canManageBilling() {
|
||||
return this.isOwner && (this.isProviderUser || !this.hasProvider);
|
||||
}
|
||||
|
||||
get hasProvider() {
|
||||
return this.providerId != null || this.providerName != null;
|
||||
}
|
||||
}
|
||||
43
libs/common/src/models/domain/password.ts
Normal file
43
libs/common/src/models/domain/password.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { PasswordHistoryData } from "../data/passwordHistoryData";
|
||||
import { PasswordHistoryView } from "../view/passwordHistoryView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class Password extends Domain {
|
||||
password: EncString;
|
||||
lastUsedDate: Date;
|
||||
|
||||
constructor(obj?: PasswordHistoryData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(this, obj, {
|
||||
password: null,
|
||||
});
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import Domain from "./domainBase";
|
||||
|
||||
export class PasswordGeneratorPolicyOptions extends Domain {
|
||||
defaultType = "";
|
||||
minLength = 0;
|
||||
useUppercase = false;
|
||||
useLowercase = false;
|
||||
useNumbers = false;
|
||||
numberCount = 0;
|
||||
useSpecial = false;
|
||||
specialCount = 0;
|
||||
minNumberWords = 0;
|
||||
capitalize = false;
|
||||
includeNumber = 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
|
||||
);
|
||||
}
|
||||
}
|
||||
25
libs/common/src/models/domain/policy.ts
Normal file
25
libs/common/src/models/domain/policy.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { PolicyType } from "../../enums/policyType";
|
||||
import { PolicyData } from "../data/policyData";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
50
libs/common/src/models/domain/provider.ts
Normal file
50
libs/common/src/models/domain/provider.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { ProviderUserStatusType } from "../../enums/providerUserStatusType";
|
||||
import { ProviderUserType } from "../../enums/providerUserType";
|
||||
import { ProviderData } from "../data/providerData";
|
||||
|
||||
export class Provider {
|
||||
id: string;
|
||||
name: string;
|
||||
status: ProviderUserStatusType;
|
||||
type: ProviderUserType;
|
||||
enabled: boolean;
|
||||
userId: string;
|
||||
useEvents: boolean;
|
||||
|
||||
constructor(obj?: ProviderData) {
|
||||
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.userId = obj.userId;
|
||||
this.useEvents = obj.useEvents;
|
||||
}
|
||||
|
||||
get canAccess() {
|
||||
if (this.isProviderAdmin) {
|
||||
return true;
|
||||
}
|
||||
return this.enabled && this.status === ProviderUserStatusType.Confirmed;
|
||||
}
|
||||
|
||||
get canCreateOrganizations() {
|
||||
return this.enabled && this.isProviderAdmin;
|
||||
}
|
||||
|
||||
get canManageUsers() {
|
||||
return this.isProviderAdmin;
|
||||
}
|
||||
|
||||
get canAccessEventLogs() {
|
||||
return this.isProviderAdmin;
|
||||
}
|
||||
|
||||
get isProviderAdmin() {
|
||||
return this.type === ProviderUserType.ProviderAdmin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import Domain from "./domainBase";
|
||||
|
||||
export class ResetPasswordPolicyOptions extends Domain {
|
||||
autoEnrollEnabled = false;
|
||||
}
|
||||
29
libs/common/src/models/domain/secureNote.ts
Normal file
29
libs/common/src/models/domain/secureNote.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { SecureNoteType } from "../../enums/secureNoteType";
|
||||
import { SecureNoteData } from "../data/secureNoteData";
|
||||
import { SecureNoteView } from "../view/secureNoteView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class SecureNote extends Domain {
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(obj?: SecureNoteData) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
112
libs/common/src/models/domain/send.ts
Normal file
112
libs/common/src/models/domain/send.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
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;
|
||||
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) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
accessId: null,
|
||||
name: null,
|
||||
notes: null,
|
||||
key: null,
|
||||
},
|
||||
["id", "accessId"]
|
||||
);
|
||||
|
||||
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);
|
||||
break;
|
||||
case SendType.File:
|
||||
this.file = new SendFile(obj.file);
|
||||
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;
|
||||
}
|
||||
}
|
||||
77
libs/common/src/models/domain/sendAccess.ts
Normal file
77
libs/common/src/models/domain/sendAccess.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
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) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
name: null,
|
||||
expirationDate: null,
|
||||
creatorIdentifier: null,
|
||||
},
|
||||
["id", "expirationDate", "creatorIdentifier"]
|
||||
);
|
||||
|
||||
this.type = obj.type;
|
||||
|
||||
switch (this.type) {
|
||||
case SendType.Text:
|
||||
this.text = new SendText(obj.text);
|
||||
break;
|
||||
case SendType.File:
|
||||
this.file = new SendFile(obj.file);
|
||||
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;
|
||||
}
|
||||
}
|
||||
44
libs/common/src/models/domain/sendFile.ts
Normal file
44
libs/common/src/models/domain/sendFile.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { SendFileData } from "../data/sendFileData";
|
||||
import { SendFileView } from "../view/sendFileView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class SendFile extends Domain {
|
||||
id: string;
|
||||
size: string;
|
||||
sizeName: string;
|
||||
fileName: EncString;
|
||||
|
||||
constructor(obj?: SendFileData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.size = obj.size;
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
id: null,
|
||||
sizeName: null,
|
||||
fileName: null,
|
||||
},
|
||||
["id", "sizeName"]
|
||||
);
|
||||
}
|
||||
|
||||
async decrypt(key: SymmetricCryptoKey): Promise<SendFileView> {
|
||||
const view = await this.decryptObj(
|
||||
new SendFileView(this),
|
||||
{
|
||||
fileName: null,
|
||||
},
|
||||
null,
|
||||
key
|
||||
);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
39
libs/common/src/models/domain/sendText.ts
Normal file
39
libs/common/src/models/domain/sendText.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { SendTextData } from "../data/sendTextData";
|
||||
import { SendTextView } from "../view/sendTextView";
|
||||
|
||||
import Domain from "./domainBase";
|
||||
import { EncString } from "./encString";
|
||||
import { SymmetricCryptoKey } from "./symmetricCryptoKey";
|
||||
|
||||
export class SendText extends Domain {
|
||||
text: EncString;
|
||||
hidden: boolean;
|
||||
|
||||
constructor(obj?: SendTextData) {
|
||||
super();
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hidden = obj.hidden;
|
||||
this.buildDomainModel(
|
||||
this,
|
||||
obj,
|
||||
{
|
||||
text: null,
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
decrypt(key: SymmetricCryptoKey): Promise<SendTextView> {
|
||||
return this.decryptObj(
|
||||
new SendTextView(this),
|
||||
{
|
||||
text: null,
|
||||
},
|
||||
null,
|
||||
key
|
||||
);
|
||||
}
|
||||
}
|
||||
87
libs/common/src/models/domain/sortedCiphersCache.ts
Normal file
87
libs/common/src/models/domain/sortedCiphersCache.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { CipherView } from "../view/cipherView";
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
17
libs/common/src/models/domain/state.ts
Normal file
17
libs/common/src/models/domain/state.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Account } from "./account";
|
||||
import { GlobalState } from "./globalState";
|
||||
|
||||
export class State<
|
||||
TGlobalState extends GlobalState = GlobalState,
|
||||
TAccount extends Account = Account
|
||||
> {
|
||||
accounts: { [userId: string]: TAccount } = {};
|
||||
globals: TGlobalState;
|
||||
activeUserId: string;
|
||||
authenticatedAccounts: string[] = [];
|
||||
accountActivity: { [userId: string]: number } = {};
|
||||
|
||||
constructor(globals: TGlobalState) {
|
||||
this.globals = globals;
|
||||
}
|
||||
}
|
||||
10
libs/common/src/models/domain/storageOptions.ts
Normal file
10
libs/common/src/models/domain/storageOptions.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { HtmlStorageLocation } from "../../enums/htmlStorageLocation";
|
||||
import { StorageLocation } from "../../enums/storageLocation";
|
||||
|
||||
export type StorageOptions = {
|
||||
storageLocation?: StorageLocation;
|
||||
useSecureStorage?: boolean;
|
||||
userId?: string;
|
||||
htmlStorageLocation?: HtmlStorageLocation;
|
||||
keySuffix?: string;
|
||||
};
|
||||
57
libs/common/src/models/domain/symmetricCryptoKey.ts
Normal file
57
libs/common/src/models/domain/symmetricCryptoKey.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
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
libs/common/src/models/domain/treeNode.ts
Normal file
16
libs/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;
|
||||
}
|
||||
10
libs/common/src/models/domain/windowState.ts
Normal file
10
libs/common/src/models/domain/windowState.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export class WindowState {
|
||||
width?: number;
|
||||
height?: number;
|
||||
isMaximized?: boolean;
|
||||
// TODO: displayBounds is an Electron.Rectangle.
|
||||
// We need to establish some kind of client-specific global state, similiar to the way we already extend a base Account.
|
||||
displayBounds: any;
|
||||
x?: number;
|
||||
y?: number;
|
||||
}
|
||||
65
libs/common/src/models/export/cardExport.ts
Normal file
65
libs/common/src/models/export/cardExport.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Card as CardDomain } from "../domain/card";
|
||||
import { EncString } from "../domain/encString";
|
||||
import { CardView } from "../view/cardView";
|
||||
|
||||
export class CardExport {
|
||||
static template(): CardExport {
|
||||
const req = new CardExport();
|
||||
req.cardholderName = "John Doe";
|
||||
req.brand = "visa";
|
||||
req.number = "4242424242424242";
|
||||
req.expMonth = "04";
|
||||
req.expYear = "2023";
|
||||
req.code = "123";
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: CardExport, 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: CardExport, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
156
libs/common/src/models/export/cipherExport.ts
Normal file
156
libs/common/src/models/export/cipherExport.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { CipherRepromptType } from "../../enums/cipherRepromptType";
|
||||
import { CipherType } from "../../enums/cipherType";
|
||||
import { Cipher as CipherDomain } from "../domain/cipher";
|
||||
import { EncString } from "../domain/encString";
|
||||
import { CipherView } from "../view/cipherView";
|
||||
|
||||
import { CardExport } from "./cardExport";
|
||||
import { FieldExport } from "./fieldExport";
|
||||
import { IdentityExport } from "./identityExport";
|
||||
import { LoginExport } from "./loginExport";
|
||||
import { SecureNoteExport } from "./secureNoteExport";
|
||||
|
||||
export class CipherExport {
|
||||
static template(): CipherExport {
|
||||
const req = new CipherExport();
|
||||
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: CipherExport, 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) => FieldExport.toView(f));
|
||||
}
|
||||
|
||||
switch (req.type) {
|
||||
case CipherType.Login:
|
||||
view.login = LoginExport.toView(req.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
view.secureNote = SecureNoteExport.toView(req.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
view.card = CardExport.toView(req.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
view.identity = IdentityExport.toView(req.identity);
|
||||
break;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: CipherExport, 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) => FieldExport.toDomain(f));
|
||||
}
|
||||
|
||||
switch (req.type) {
|
||||
case CipherType.Login:
|
||||
domain.login = LoginExport.toDomain(req.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
domain.secureNote = SecureNoteExport.toDomain(req.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
domain.card = CardExport.toDomain(req.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
domain.identity = IdentityExport.toDomain(req.identity);
|
||||
break;
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
type: CipherType;
|
||||
folderId: string;
|
||||
organizationId: string;
|
||||
collectionIds: string[];
|
||||
name: string;
|
||||
notes: string;
|
||||
favorite: boolean;
|
||||
fields: FieldExport[];
|
||||
login: LoginExport;
|
||||
secureNote: SecureNoteExport;
|
||||
card: CardExport;
|
||||
identity: IdentityExport;
|
||||
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 FieldExport(f));
|
||||
} else {
|
||||
this.fields = o.fields.map((f) => new FieldExport(f));
|
||||
}
|
||||
}
|
||||
|
||||
switch (o.type) {
|
||||
case CipherType.Login:
|
||||
this.login = new LoginExport(o.login);
|
||||
break;
|
||||
case CipherType.SecureNote:
|
||||
this.secureNote = new SecureNoteExport(o.secureNote);
|
||||
break;
|
||||
case CipherType.Card:
|
||||
this.card = new CardExport(o.card);
|
||||
break;
|
||||
case CipherType.Identity:
|
||||
this.identity = new IdentityExport(o.identity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
libs/common/src/models/export/cipherWithIdsExport.ts
Normal file
16
libs/common/src/models/export/cipherWithIdsExport.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Cipher as CipherDomain } from "../domain/cipher";
|
||||
import { CipherView } from "../view/cipherView";
|
||||
|
||||
import { CipherExport } from "./cipherExport";
|
||||
|
||||
export class CipherWithIdExport extends CipherExport {
|
||||
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;
|
||||
}
|
||||
}
|
||||
46
libs/common/src/models/export/collectionExport.ts
Normal file
46
libs/common/src/models/export/collectionExport.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Collection as CollectionDomain } from "../domain/collection";
|
||||
import { EncString } from "../domain/encString";
|
||||
import { CollectionView } from "../view/collectionView";
|
||||
|
||||
export class CollectionExport {
|
||||
static template(): CollectionExport {
|
||||
const req = new CollectionExport();
|
||||
req.organizationId = "00000000-0000-0000-0000-000000000000";
|
||||
req.name = "Collection name";
|
||||
req.externalId = null;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: CollectionExport, view = new CollectionView()) {
|
||||
view.name = req.name;
|
||||
view.externalId = req.externalId;
|
||||
if (view.organizationId == null) {
|
||||
view.organizationId = req.organizationId;
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: CollectionExport, 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;
|
||||
}
|
||||
}
|
||||
14
libs/common/src/models/export/collectionWithIdExport.ts
Normal file
14
libs/common/src/models/export/collectionWithIdExport.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Collection as CollectionDomain } from "../domain/collection";
|
||||
import { CollectionView } from "../view/collectionView";
|
||||
|
||||
import { CollectionExport } from "./collectionExport";
|
||||
|
||||
export class CollectionWithIdExport extends CollectionExport {
|
||||
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);
|
||||
}
|
||||
}
|
||||
28
libs/common/src/models/export/eventExport.ts
Normal file
28
libs/common/src/models/export/eventExport.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { EventType } from "../../enums/eventType";
|
||||
import { EventView } from "../view/eventView";
|
||||
|
||||
export class EventExport {
|
||||
message: string;
|
||||
appIcon: string;
|
||||
appName: string;
|
||||
userId: string;
|
||||
userName: string;
|
||||
userEmail: string;
|
||||
date: string;
|
||||
ip: string;
|
||||
type: string;
|
||||
installationId: 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];
|
||||
this.installationId = event.installationId;
|
||||
}
|
||||
}
|
||||
52
libs/common/src/models/export/fieldExport.ts
Normal file
52
libs/common/src/models/export/fieldExport.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { FieldType } from "../../enums/fieldType";
|
||||
import { LinkedIdType } from "../../enums/linkedIdType";
|
||||
import { EncString } from "../domain/encString";
|
||||
import { Field as FieldDomain } from "../domain/field";
|
||||
import { FieldView } from "../view/fieldView";
|
||||
|
||||
export class FieldExport {
|
||||
static template(): FieldExport {
|
||||
const req = new FieldExport();
|
||||
req.name = "Field name";
|
||||
req.value = "Some value";
|
||||
req.type = FieldType.Text;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: FieldExport, view = new FieldView()) {
|
||||
view.type = req.type;
|
||||
view.value = req.value;
|
||||
view.name = req.name;
|
||||
view.linkedId = req.linkedId;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: FieldExport, 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;
|
||||
domain.linkedId = req.linkedId;
|
||||
return domain;
|
||||
}
|
||||
|
||||
name: string;
|
||||
value: string;
|
||||
type: FieldType;
|
||||
linkedId: LinkedIdType;
|
||||
|
||||
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;
|
||||
this.linkedId = o.linkedId;
|
||||
}
|
||||
}
|
||||
32
libs/common/src/models/export/folderExport.ts
Normal file
32
libs/common/src/models/export/folderExport.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { EncString } from "../domain/encString";
|
||||
import { Folder as FolderDomain } from "../domain/folder";
|
||||
import { FolderView } from "../view/folderView";
|
||||
|
||||
export class FolderExport {
|
||||
static template(): FolderExport {
|
||||
const req = new FolderExport();
|
||||
req.name = "Folder name";
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: FolderExport, view = new FolderView()) {
|
||||
view.name = req.name;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: FolderExport, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
libs/common/src/models/export/folderWithIdExport.ts
Normal file
14
libs/common/src/models/export/folderWithIdExport.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Folder as FolderDomain } from "../domain/folder";
|
||||
import { FolderView } from "../view/folderView";
|
||||
|
||||
import { FolderExport } from "./folderExport";
|
||||
|
||||
export class FolderWithIdExport extends FolderExport {
|
||||
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);
|
||||
}
|
||||
}
|
||||
137
libs/common/src/models/export/identityExport.ts
Normal file
137
libs/common/src/models/export/identityExport.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import { EncString } from "../domain/encString";
|
||||
import { Identity as IdentityDomain } from "../domain/identity";
|
||||
import { IdentityView } from "../view/identityView";
|
||||
|
||||
export class IdentityExport {
|
||||
static template(): IdentityExport {
|
||||
const req = new IdentityExport();
|
||||
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: IdentityExport, 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: IdentityExport, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
65
libs/common/src/models/export/loginExport.ts
Normal file
65
libs/common/src/models/export/loginExport.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { EncString } from "../domain/encString";
|
||||
import { Login as LoginDomain } from "../domain/login";
|
||||
import { LoginView } from "../view/loginView";
|
||||
|
||||
import { LoginUriExport } from "./loginUriExport";
|
||||
|
||||
export class LoginExport {
|
||||
static template(): LoginExport {
|
||||
const req = new LoginExport();
|
||||
req.uris = [];
|
||||
req.username = "jdoe";
|
||||
req.password = "myp@ssword123";
|
||||
req.totp = "JBSWY3DPEHPK3PXP";
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: LoginExport, view = new LoginView()) {
|
||||
if (req.uris != null) {
|
||||
view.uris = req.uris.map((u) => LoginUriExport.toView(u));
|
||||
}
|
||||
view.username = req.username;
|
||||
view.password = req.password;
|
||||
view.totp = req.totp;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: LoginExport, domain = new LoginDomain()) {
|
||||
if (req.uris != null) {
|
||||
domain.uris = req.uris.map((u) => LoginUriExport.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: LoginUriExport[];
|
||||
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 LoginUriExport(u));
|
||||
} else {
|
||||
this.uris = o.uris.map((u) => new LoginUriExport(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
libs/common/src/models/export/loginUriExport.ts
Normal file
41
libs/common/src/models/export/loginUriExport.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { UriMatchType } from "../../enums/uriMatchType";
|
||||
import { EncString } from "../domain/encString";
|
||||
import { LoginUri as LoginUriDomain } from "../domain/loginUri";
|
||||
import { LoginUriView } from "../view/loginUriView";
|
||||
|
||||
export class LoginUriExport {
|
||||
static template(): LoginUriExport {
|
||||
const req = new LoginUriExport();
|
||||
req.uri = "https://google.com";
|
||||
req.match = null;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: LoginUriExport, view = new LoginUriView()) {
|
||||
view.uri = req.uri;
|
||||
view.match = req.match;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: LoginUriExport, 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;
|
||||
}
|
||||
}
|
||||
31
libs/common/src/models/export/secureNoteExport.ts
Normal file
31
libs/common/src/models/export/secureNoteExport.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { SecureNoteType } from "../../enums/secureNoteType";
|
||||
import { SecureNote as SecureNoteDomain } from "../domain/secureNote";
|
||||
import { SecureNoteView } from "../view/secureNoteView";
|
||||
|
||||
export class SecureNoteExport {
|
||||
static template(): SecureNoteExport {
|
||||
const req = new SecureNoteExport();
|
||||
req.type = SecureNoteType.Generic;
|
||||
return req;
|
||||
}
|
||||
|
||||
static toView(req: SecureNoteExport, view = new SecureNoteView()) {
|
||||
view.type = req.type;
|
||||
return view;
|
||||
}
|
||||
|
||||
static toDomain(req: SecureNoteExport, view = new SecureNoteDomain()) {
|
||||
view.type = req.type;
|
||||
return view;
|
||||
}
|
||||
|
||||
type: SecureNoteType;
|
||||
|
||||
constructor(o?: SecureNoteView | SecureNoteDomain) {
|
||||
if (o == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = o.type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { KdfType } from "../../../enums/kdfType";
|
||||
import { KeysRequest } from "../keysRequest";
|
||||
|
||||
export class SetKeyConnectorKeyRequest {
|
||||
key: string;
|
||||
keys: KeysRequest;
|
||||
kdf: KdfType;
|
||||
kdfIterations: number;
|
||||
orgIdentifier: string;
|
||||
|
||||
constructor(
|
||||
key: string,
|
||||
kdf: KdfType,
|
||||
kdfIterations: number,
|
||||
orgIdentifier: string,
|
||||
keys: KeysRequest
|
||||
) {
|
||||
this.key = key;
|
||||
this.kdf = kdf;
|
||||
this.kdfIterations = kdfIterations;
|
||||
this.orgIdentifier = orgIdentifier;
|
||||
this.keys = keys;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export class VerifyOTPRequest {
|
||||
OTP: string;
|
||||
|
||||
constructor(OTP: string) {
|
||||
this.OTP = OTP;
|
||||
}
|
||||
}
|
||||
6
libs/common/src/models/request/attachmentRequest.ts
Normal file
6
libs/common/src/models/request/attachmentRequest.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export class AttachmentRequest {
|
||||
fileName: string;
|
||||
key: string;
|
||||
fileSize: number;
|
||||
adminRequest: boolean;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export class BillingSyncConfigRequest {
|
||||
constructor(private billingSyncKey: string) {}
|
||||
}
|
||||
9
libs/common/src/models/request/bitPayInvoiceRequest.ts
Normal file
9
libs/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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export abstract class CaptchaProtectedRequest {
|
||||
captchaResponse: string = null;
|
||||
}
|
||||
@@ -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
libs/common/src/models/request/cipherBulkMoveRequest.ts
Normal file
9
libs/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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export class CipherBulkRestoreRequest {
|
||||
ids: string[];
|
||||
|
||||
constructor(ids: string[]) {
|
||||
this.ids = ids == null ? [] : ids;
|
||||
}
|
||||
}
|
||||
18
libs/common/src/models/request/cipherBulkShareRequest.ts
Normal file
18
libs/common/src/models/request/cipherBulkShareRequest.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Cipher } from "../domain/cipher";
|
||||
|
||||
import { CipherWithIdRequest } from "./cipherWithIdRequest";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export class CipherCollectionsRequest {
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(collectionIds: string[]) {
|
||||
this.collectionIds = collectionIds == null ? [] : collectionIds;
|
||||
}
|
||||
}
|
||||
13
libs/common/src/models/request/cipherCreateRequest.ts
Normal file
13
libs/common/src/models/request/cipherCreateRequest.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Cipher } from "../domain/cipher";
|
||||
|
||||
import { CipherRequest } from "./cipherRequest";
|
||||
|
||||
export class CipherCreateRequest {
|
||||
cipher: CipherRequest;
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
this.cipher = new CipherRequest(cipher);
|
||||
this.collectionIds = cipher.collectionIds;
|
||||
}
|
||||
}
|
||||
164
libs/common/src/models/request/cipherRequest.ts
Normal file
164
libs/common/src/models/request/cipherRequest.ts
Normal file
@@ -0,0 +1,164 @@
|
||||
import { CipherRepromptType } from "../../enums/cipherRepromptType";
|
||||
import { CipherType } from "../../enums/cipherType";
|
||||
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 { Cipher } from "../domain/cipher";
|
||||
|
||||
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;
|
||||
field.linkedId = f.linkedId;
|
||||
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
libs/common/src/models/request/cipherShareRequest.ts
Normal file
13
libs/common/src/models/request/cipherShareRequest.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Cipher } from "../domain/cipher";
|
||||
|
||||
import { CipherRequest } from "./cipherRequest";
|
||||
|
||||
export class CipherShareRequest {
|
||||
cipher: CipherRequest;
|
||||
collectionIds: string[];
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
this.cipher = new CipherRequest(cipher);
|
||||
this.collectionIds = cipher.collectionIds;
|
||||
}
|
||||
}
|
||||
12
libs/common/src/models/request/cipherWithIdRequest.ts
Normal file
12
libs/common/src/models/request/cipherWithIdRequest.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Cipher } from "../domain/cipher";
|
||||
|
||||
import { CipherRequest } from "./cipherRequest";
|
||||
|
||||
export class CipherWithIdRequest extends CipherRequest {
|
||||
id: string;
|
||||
|
||||
constructor(cipher: Cipher) {
|
||||
super(cipher);
|
||||
this.id = cipher.id;
|
||||
}
|
||||
}
|
||||
17
libs/common/src/models/request/collectionRequest.ts
Normal file
17
libs/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
libs/common/src/models/request/deleteRecoverRequest.ts
Normal file
3
libs/common/src/models/request/deleteRecoverRequest.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export class DeleteRecoverRequest {
|
||||
email: string;
|
||||
}
|
||||
16
libs/common/src/models/request/deviceRequest.ts
Normal file
16
libs/common/src/models/request/deviceRequest.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { PlatformUtilsService } from "../../abstractions/platformUtils.service";
|
||||
import { DeviceType } from "../../enums/deviceType";
|
||||
|
||||
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
libs/common/src/models/request/deviceTokenRequest.ts
Normal file
7
libs/common/src/models/request/deviceTokenRequest.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class DeviceTokenRequest {
|
||||
pushToken: string;
|
||||
|
||||
constructor() {
|
||||
this.pushToken = null;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user