mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-15 07:43:27 +00:00
Delete PolicyService
This commit is contained in:
@@ -18,7 +18,6 @@ import { OrganizationService as OrganizationServiceAbstraction } from "@/jslib/c
|
|||||||
import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "@/jslib/common/src/abstractions/passwordGeneration.service";
|
import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "@/jslib/common/src/abstractions/passwordGeneration.service";
|
||||||
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@/jslib/common/src/abstractions/passwordReprompt.service";
|
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@/jslib/common/src/abstractions/passwordReprompt.service";
|
||||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@/jslib/common/src/abstractions/platformUtils.service";
|
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@/jslib/common/src/abstractions/platformUtils.service";
|
||||||
import { PolicyService as PolicyServiceAbstraction } from "@/jslib/common/src/abstractions/policy.service";
|
|
||||||
import { SearchService as SearchServiceAbstraction } from "@/jslib/common/src/abstractions/search.service";
|
import { SearchService as SearchServiceAbstraction } from "@/jslib/common/src/abstractions/search.service";
|
||||||
import { SettingsService as SettingsServiceAbstraction } from "@/jslib/common/src/abstractions/settings.service";
|
import { SettingsService as SettingsServiceAbstraction } from "@/jslib/common/src/abstractions/settings.service";
|
||||||
import { StateService as StateServiceAbstraction } from "@/jslib/common/src/abstractions/state.service";
|
import { StateService as StateServiceAbstraction } from "@/jslib/common/src/abstractions/state.service";
|
||||||
@@ -43,7 +42,6 @@ import { KeyConnectorService } from "@/jslib/common/src/services/keyConnector.se
|
|||||||
import { NotificationsService } from "@/jslib/common/src/services/notifications.service";
|
import { NotificationsService } from "@/jslib/common/src/services/notifications.service";
|
||||||
import { OrganizationService } from "@/jslib/common/src/services/organization.service";
|
import { OrganizationService } from "@/jslib/common/src/services/organization.service";
|
||||||
import { PasswordGenerationService } from "@/jslib/common/src/services/passwordGeneration.service";
|
import { PasswordGenerationService } from "@/jslib/common/src/services/passwordGeneration.service";
|
||||||
import { PolicyService } from "@/jslib/common/src/services/policy.service";
|
|
||||||
import { SearchService } from "@/jslib/common/src/services/search.service";
|
import { SearchService } from "@/jslib/common/src/services/search.service";
|
||||||
import { SettingsService } from "@/jslib/common/src/services/settings.service";
|
import { SettingsService } from "@/jslib/common/src/services/settings.service";
|
||||||
import { StateService } from "@/jslib/common/src/services/state.service";
|
import { StateService } from "@/jslib/common/src/services/state.service";
|
||||||
@@ -118,7 +116,7 @@ import { ValidationService } from "./validation.service";
|
|||||||
{
|
{
|
||||||
provide: PasswordGenerationServiceAbstraction,
|
provide: PasswordGenerationServiceAbstraction,
|
||||||
useClass: PasswordGenerationService,
|
useClass: PasswordGenerationService,
|
||||||
deps: [CryptoServiceAbstraction, PolicyServiceAbstraction, StateServiceAbstraction],
|
deps: [CryptoServiceAbstraction, StateServiceAbstraction],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: ApiServiceAbstraction,
|
provide: ApiServiceAbstraction,
|
||||||
@@ -156,7 +154,6 @@ import { ValidationService } from "./validation.service";
|
|||||||
settingsService: SettingsServiceAbstraction,
|
settingsService: SettingsServiceAbstraction,
|
||||||
cryptoService: CryptoServiceAbstraction,
|
cryptoService: CryptoServiceAbstraction,
|
||||||
messagingService: MessagingServiceAbstraction,
|
messagingService: MessagingServiceAbstraction,
|
||||||
policyService: PolicyServiceAbstraction,
|
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
keyConnectorService: KeyConnectorServiceAbstraction,
|
keyConnectorService: KeyConnectorServiceAbstraction,
|
||||||
stateService: StateServiceAbstraction,
|
stateService: StateServiceAbstraction,
|
||||||
@@ -167,7 +164,6 @@ import { ValidationService } from "./validation.service";
|
|||||||
settingsService,
|
settingsService,
|
||||||
cryptoService,
|
cryptoService,
|
||||||
messagingService,
|
messagingService,
|
||||||
policyService,
|
|
||||||
logService,
|
logService,
|
||||||
keyConnectorService,
|
keyConnectorService,
|
||||||
stateService,
|
stateService,
|
||||||
@@ -179,7 +175,6 @@ import { ValidationService } from "./validation.service";
|
|||||||
SettingsServiceAbstraction,
|
SettingsServiceAbstraction,
|
||||||
CryptoServiceAbstraction,
|
CryptoServiceAbstraction,
|
||||||
MessagingServiceAbstraction,
|
MessagingServiceAbstraction,
|
||||||
PolicyServiceAbstraction,
|
|
||||||
LogService,
|
LogService,
|
||||||
KeyConnectorServiceAbstraction,
|
KeyConnectorServiceAbstraction,
|
||||||
StateServiceAbstraction,
|
StateServiceAbstraction,
|
||||||
@@ -272,11 +267,6 @@ import { ValidationService } from "./validation.service";
|
|||||||
OrganizationServiceAbstraction,
|
OrganizationServiceAbstraction,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
provide: PolicyServiceAbstraction,
|
|
||||||
useClass: PolicyService,
|
|
||||||
deps: [StateServiceAbstraction, OrganizationServiceAbstraction, ApiServiceAbstraction],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
provide: KeyConnectorServiceAbstraction,
|
provide: KeyConnectorServiceAbstraction,
|
||||||
useClass: KeyConnectorService,
|
useClass: KeyConnectorService,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ export abstract class PasswordGenerationService {
|
|||||||
enforcePasswordGeneratorPoliciesOnOptions: (
|
enforcePasswordGeneratorPoliciesOnOptions: (
|
||||||
options: any,
|
options: any,
|
||||||
) => Promise<[any, PasswordGeneratorPolicyOptions]>;
|
) => Promise<[any, PasswordGeneratorPolicyOptions]>;
|
||||||
getPasswordGeneratorPolicyOptions: () => Promise<PasswordGeneratorPolicyOptions>;
|
|
||||||
saveOptions: (options: any) => Promise<any>;
|
saveOptions: (options: any) => Promise<any>;
|
||||||
getHistory: () => Promise<GeneratedPasswordHistory[]>;
|
getHistory: () => Promise<GeneratedPasswordHistory[]>;
|
||||||
addHistory: (password: string) => Promise<any>;
|
addHistory: (password: string) => Promise<any>;
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
import { PolicyType } from "../enums/policyType";
|
|
||||||
import { PolicyData } from "../models/data/policyData";
|
|
||||||
import { MasterPasswordPolicyOptions } from "../models/domain/masterPasswordPolicyOptions";
|
|
||||||
import { Policy } from "../models/domain/policy";
|
|
||||||
import { ResetPasswordPolicyOptions } from "../models/domain/resetPasswordPolicyOptions";
|
|
||||||
import { ListResponse } from "../models/response/listResponse";
|
|
||||||
import { PolicyResponse } from "../models/response/policyResponse";
|
|
||||||
|
|
||||||
export abstract class PolicyService {
|
|
||||||
clearCache: () => void;
|
|
||||||
getAll: (type?: PolicyType, userId?: string) => Promise<Policy[]>;
|
|
||||||
getPolicyForOrganization: (policyType: PolicyType, organizationId: string) => Promise<Policy>;
|
|
||||||
replace: (policies: { [id: string]: PolicyData }) => Promise<any>;
|
|
||||||
clear: (userId?: string) => Promise<any>;
|
|
||||||
getMasterPasswordPoliciesForInvitedUsers: (orgId: string) => Promise<MasterPasswordPolicyOptions>;
|
|
||||||
getMasterPasswordPolicyOptions: (policies?: Policy[]) => Promise<MasterPasswordPolicyOptions>;
|
|
||||||
evaluateMasterPassword: (
|
|
||||||
passwordStrength: number,
|
|
||||||
newPassword: string,
|
|
||||||
enforcedPolicyOptions?: MasterPasswordPolicyOptions,
|
|
||||||
) => boolean;
|
|
||||||
getResetPasswordPolicyOptions: (
|
|
||||||
policies: Policy[],
|
|
||||||
orgId: string,
|
|
||||||
) => [ResetPasswordPolicyOptions, boolean];
|
|
||||||
mapPoliciesFromToken: (policiesResponse: ListResponse<PolicyResponse>) => Policy[];
|
|
||||||
policyAppliesToUser: (
|
|
||||||
policyType: PolicyType,
|
|
||||||
policyFilter?: (policy: Policy) => boolean,
|
|
||||||
userId?: string,
|
|
||||||
) => Promise<boolean>;
|
|
||||||
}
|
|
||||||
@@ -2,14 +2,11 @@ import * as zxcvbn from "zxcvbn";
|
|||||||
|
|
||||||
import { CryptoService } from "../abstractions/crypto.service";
|
import { CryptoService } from "../abstractions/crypto.service";
|
||||||
import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "../abstractions/passwordGeneration.service";
|
import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "../abstractions/passwordGeneration.service";
|
||||||
import { PolicyService } from "../abstractions/policy.service";
|
|
||||||
import { StateService } from "../abstractions/state.service";
|
import { StateService } from "../abstractions/state.service";
|
||||||
import { PolicyType } from "../enums/policyType";
|
|
||||||
import { EEFLongWordList } from "../misc/wordlist";
|
import { EEFLongWordList } from "../misc/wordlist";
|
||||||
import { EncString } from "../models/domain/encString";
|
import { EncString } from "../models/domain/encString";
|
||||||
import { GeneratedPasswordHistory } from "../models/domain/generatedPasswordHistory";
|
import { GeneratedPasswordHistory } from "../models/domain/generatedPasswordHistory";
|
||||||
import { PasswordGeneratorPolicyOptions } from "../models/domain/passwordGeneratorPolicyOptions";
|
import { PasswordGeneratorPolicyOptions } from "../models/domain/passwordGeneratorPolicyOptions";
|
||||||
import { Policy } from "../models/domain/policy";
|
|
||||||
|
|
||||||
const DefaultOptions = {
|
const DefaultOptions = {
|
||||||
length: 14,
|
length: 14,
|
||||||
@@ -34,7 +31,6 @@ const MaxPasswordsInHistory = 100;
|
|||||||
export class PasswordGenerationService implements PasswordGenerationServiceAbstraction {
|
export class PasswordGenerationService implements PasswordGenerationServiceAbstraction {
|
||||||
constructor(
|
constructor(
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private policyService: PolicyService,
|
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -193,146 +189,7 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
|||||||
async enforcePasswordGeneratorPoliciesOnOptions(
|
async enforcePasswordGeneratorPoliciesOnOptions(
|
||||||
options: any,
|
options: any,
|
||||||
): Promise<[any, PasswordGeneratorPolicyOptions]> {
|
): Promise<[any, PasswordGeneratorPolicyOptions]> {
|
||||||
let enforcedPolicyOptions = await this.getPasswordGeneratorPolicyOptions();
|
return [options, new PasswordGeneratorPolicyOptions()];
|
||||||
if (enforcedPolicyOptions != null) {
|
|
||||||
if (options.length < enforcedPolicyOptions.minLength) {
|
|
||||||
options.length = enforcedPolicyOptions.minLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.useUppercase) {
|
|
||||||
options.uppercase = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.useLowercase) {
|
|
||||||
options.lowercase = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.useNumbers) {
|
|
||||||
options.number = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.minNumber < enforcedPolicyOptions.numberCount) {
|
|
||||||
options.minNumber = enforcedPolicyOptions.numberCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.useSpecial) {
|
|
||||||
options.special = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.minSpecial < enforcedPolicyOptions.specialCount) {
|
|
||||||
options.minSpecial = enforcedPolicyOptions.specialCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must normalize these fields because the receiving call expects all options to pass the current rules
|
|
||||||
if (options.minSpecial + options.minNumber > options.length) {
|
|
||||||
options.minSpecial = options.length - options.minNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.numWords < enforcedPolicyOptions.minNumberWords) {
|
|
||||||
options.numWords = enforcedPolicyOptions.minNumberWords;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.capitalize) {
|
|
||||||
options.capitalize = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.includeNumber) {
|
|
||||||
options.includeNumber = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force default type if password/passphrase selected via policy
|
|
||||||
if (
|
|
||||||
enforcedPolicyOptions.defaultType === "password" ||
|
|
||||||
enforcedPolicyOptions.defaultType === "passphrase"
|
|
||||||
) {
|
|
||||||
options.type = enforcedPolicyOptions.defaultType;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// UI layer expects an instantiated object to prevent more explicit null checks
|
|
||||||
enforcedPolicyOptions = new PasswordGeneratorPolicyOptions();
|
|
||||||
}
|
|
||||||
return [options, enforcedPolicyOptions];
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPasswordGeneratorPolicyOptions(): Promise<PasswordGeneratorPolicyOptions> {
|
|
||||||
const policies: Policy[] =
|
|
||||||
this.policyService == null
|
|
||||||
? null
|
|
||||||
: await this.policyService.getAll(PolicyType.PasswordGenerator);
|
|
||||||
let enforcedOptions: PasswordGeneratorPolicyOptions = null;
|
|
||||||
|
|
||||||
if (policies == null || policies.length === 0) {
|
|
||||||
return enforcedOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
policies.forEach((currentPolicy) => {
|
|
||||||
if (!currentPolicy.enabled || currentPolicy.data == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedOptions == null) {
|
|
||||||
enforcedOptions = new PasswordGeneratorPolicyOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Password wins in multi-org collisions
|
|
||||||
if (currentPolicy.data.defaultType != null && enforcedOptions.defaultType !== "password") {
|
|
||||||
enforcedOptions.defaultType = currentPolicy.data.defaultType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPolicy.data.minLength != null &&
|
|
||||||
currentPolicy.data.minLength > enforcedOptions.minLength
|
|
||||||
) {
|
|
||||||
enforcedOptions.minLength = currentPolicy.data.minLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.useUpper) {
|
|
||||||
enforcedOptions.useUppercase = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.useLower) {
|
|
||||||
enforcedOptions.useLowercase = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.useNumbers) {
|
|
||||||
enforcedOptions.useNumbers = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPolicy.data.minNumbers != null &&
|
|
||||||
currentPolicy.data.minNumbers > enforcedOptions.numberCount
|
|
||||||
) {
|
|
||||||
enforcedOptions.numberCount = currentPolicy.data.minNumbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.useSpecial) {
|
|
||||||
enforcedOptions.useSpecial = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPolicy.data.minSpecial != null &&
|
|
||||||
currentPolicy.data.minSpecial > enforcedOptions.specialCount
|
|
||||||
) {
|
|
||||||
enforcedOptions.specialCount = currentPolicy.data.minSpecial;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPolicy.data.minNumberWords != null &&
|
|
||||||
currentPolicy.data.minNumberWords > enforcedOptions.minNumberWords
|
|
||||||
) {
|
|
||||||
enforcedOptions.minNumberWords = currentPolicy.data.minNumberWords;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.capitalize) {
|
|
||||||
enforcedOptions.capitalize = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.includeNumber) {
|
|
||||||
enforcedOptions.includeNumber = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return enforcedOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveOptions(options: any) {
|
async saveOptions(options: any) {
|
||||||
|
|||||||
@@ -1,247 +0,0 @@
|
|||||||
import { ApiService } from "../abstractions/api.service";
|
|
||||||
import { OrganizationService } from "../abstractions/organization.service";
|
|
||||||
import { PolicyService as PolicyServiceAbstraction } from "../abstractions/policy.service";
|
|
||||||
import { StateService } from "../abstractions/state.service";
|
|
||||||
import { OrganizationUserStatusType } from "../enums/organizationUserStatusType";
|
|
||||||
import { OrganizationUserType } from "../enums/organizationUserType";
|
|
||||||
import { PolicyType } from "../enums/policyType";
|
|
||||||
import { PolicyData } from "../models/data/policyData";
|
|
||||||
import { MasterPasswordPolicyOptions } from "../models/domain/masterPasswordPolicyOptions";
|
|
||||||
import { Organization } from "../models/domain/organization";
|
|
||||||
import { Policy } from "../models/domain/policy";
|
|
||||||
import { ResetPasswordPolicyOptions } from "../models/domain/resetPasswordPolicyOptions";
|
|
||||||
import { ListResponse } from "../models/response/listResponse";
|
|
||||||
import { PolicyResponse } from "../models/response/policyResponse";
|
|
||||||
|
|
||||||
export class PolicyService implements PolicyServiceAbstraction {
|
|
||||||
policyCache: Policy[];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private stateService: StateService,
|
|
||||||
private organizationService: OrganizationService,
|
|
||||||
private apiService: ApiService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async clearCache(): Promise<void> {
|
|
||||||
await this.stateService.setDecryptedPolicies(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAll(type?: PolicyType, userId?: string): Promise<Policy[]> {
|
|
||||||
let response: Policy[] = [];
|
|
||||||
const decryptedPolicies = await this.stateService.getDecryptedPolicies({ userId: userId });
|
|
||||||
if (decryptedPolicies != null) {
|
|
||||||
response = decryptedPolicies;
|
|
||||||
} else {
|
|
||||||
const diskPolicies = await this.stateService.getEncryptedPolicies({ userId: userId });
|
|
||||||
for (const id in diskPolicies) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
if (diskPolicies.hasOwnProperty(id)) {
|
|
||||||
response.push(new Policy(diskPolicies[id]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await this.stateService.setDecryptedPolicies(response, { userId: userId });
|
|
||||||
}
|
|
||||||
if (type != null) {
|
|
||||||
return response.filter((policy) => policy.type === type);
|
|
||||||
} else {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPolicyForOrganization(policyType: PolicyType, organizationId: string): Promise<Policy> {
|
|
||||||
const org = await this.organizationService.get(organizationId);
|
|
||||||
if (org?.isProviderUser) {
|
|
||||||
const orgPolicies = await this.apiService.getPolicies(organizationId);
|
|
||||||
const policy = orgPolicies.data.find((p) => p.organizationId === organizationId);
|
|
||||||
|
|
||||||
if (policy == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Policy(new PolicyData(policy));
|
|
||||||
}
|
|
||||||
|
|
||||||
const policies = await this.getAll(policyType);
|
|
||||||
return policies.find((p) => p.organizationId === organizationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
async replace(policies: { [id: string]: PolicyData }): Promise<any> {
|
|
||||||
await this.stateService.setDecryptedPolicies(null);
|
|
||||||
await this.stateService.setEncryptedPolicies(policies);
|
|
||||||
}
|
|
||||||
|
|
||||||
async clear(userId?: string): Promise<any> {
|
|
||||||
await this.stateService.setDecryptedPolicies(null, { userId: userId });
|
|
||||||
await this.stateService.setEncryptedPolicies(null, { userId: userId });
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMasterPasswordPoliciesForInvitedUsers(
|
|
||||||
orgId: string,
|
|
||||||
): Promise<MasterPasswordPolicyOptions> {
|
|
||||||
const userId = await this.stateService.getUserId();
|
|
||||||
const response = await this.apiService.getPoliciesByInvitedUser(orgId, userId);
|
|
||||||
const policies = await this.mapPoliciesFromToken(response);
|
|
||||||
return this.getMasterPasswordPolicyOptions(policies);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMasterPasswordPolicyOptions(policies?: Policy[]): Promise<MasterPasswordPolicyOptions> {
|
|
||||||
let enforcedOptions: MasterPasswordPolicyOptions = null;
|
|
||||||
|
|
||||||
if (policies == null) {
|
|
||||||
policies = await this.getAll(PolicyType.MasterPassword);
|
|
||||||
} else {
|
|
||||||
policies = policies.filter((p) => p.type === PolicyType.MasterPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (policies == null || policies.length === 0) {
|
|
||||||
return enforcedOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
policies.forEach((currentPolicy) => {
|
|
||||||
if (!currentPolicy.enabled || currentPolicy.data == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedOptions == null) {
|
|
||||||
enforcedOptions = new MasterPasswordPolicyOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPolicy.data.minComplexity != null &&
|
|
||||||
currentPolicy.data.minComplexity > enforcedOptions.minComplexity
|
|
||||||
) {
|
|
||||||
enforcedOptions.minComplexity = currentPolicy.data.minComplexity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPolicy.data.minLength != null &&
|
|
||||||
currentPolicy.data.minLength > enforcedOptions.minLength
|
|
||||||
) {
|
|
||||||
enforcedOptions.minLength = currentPolicy.data.minLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.requireUpper) {
|
|
||||||
enforcedOptions.requireUpper = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.requireLower) {
|
|
||||||
enforcedOptions.requireLower = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.requireNumbers) {
|
|
||||||
enforcedOptions.requireNumbers = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentPolicy.data.requireSpecial) {
|
|
||||||
enforcedOptions.requireSpecial = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return enforcedOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluateMasterPassword(
|
|
||||||
passwordStrength: number,
|
|
||||||
newPassword: string,
|
|
||||||
enforcedPolicyOptions: MasterPasswordPolicyOptions,
|
|
||||||
): boolean {
|
|
||||||
if (enforcedPolicyOptions == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
enforcedPolicyOptions.minComplexity > 0 &&
|
|
||||||
enforcedPolicyOptions.minComplexity > passwordStrength
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
enforcedPolicyOptions.minLength > 0 &&
|
|
||||||
enforcedPolicyOptions.minLength > newPassword.length
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.requireUpper && newPassword.toLocaleLowerCase() === newPassword) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.requireLower && newPassword.toLocaleUpperCase() === newPassword) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enforcedPolicyOptions.requireNumbers && !/[0-9]/.test(newPassword)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
if (enforcedPolicyOptions.requireSpecial && !/[!@#$%\^&*]/g.test(newPassword)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getResetPasswordPolicyOptions(
|
|
||||||
policies: Policy[],
|
|
||||||
orgId: string,
|
|
||||||
): [ResetPasswordPolicyOptions, boolean] {
|
|
||||||
const resetPasswordPolicyOptions = new ResetPasswordPolicyOptions();
|
|
||||||
|
|
||||||
if (policies == null || orgId == null) {
|
|
||||||
return [resetPasswordPolicyOptions, false];
|
|
||||||
}
|
|
||||||
|
|
||||||
const policy = policies.find(
|
|
||||||
(p) => p.organizationId === orgId && p.type === PolicyType.ResetPassword && p.enabled,
|
|
||||||
);
|
|
||||||
resetPasswordPolicyOptions.autoEnrollEnabled = policy?.data?.autoEnrollEnabled ?? false;
|
|
||||||
|
|
||||||
return [resetPasswordPolicyOptions, policy?.enabled ?? false];
|
|
||||||
}
|
|
||||||
|
|
||||||
mapPoliciesFromToken(policiesResponse: ListResponse<PolicyResponse>): Policy[] {
|
|
||||||
if (policiesResponse == null || policiesResponse.data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const policiesData = policiesResponse.data.map((p) => new PolicyData(p));
|
|
||||||
return policiesData.map((p) => new Policy(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
async policyAppliesToUser(
|
|
||||||
policyType: PolicyType,
|
|
||||||
policyFilter?: (policy: Policy) => boolean,
|
|
||||||
userId?: string,
|
|
||||||
) {
|
|
||||||
const policies = await this.getAll(policyType, userId);
|
|
||||||
const organizations = await this.organizationService.getAll(userId);
|
|
||||||
let filteredPolicies;
|
|
||||||
|
|
||||||
if (policyFilter != null) {
|
|
||||||
filteredPolicies = policies.filter((p) => p.enabled && policyFilter(p));
|
|
||||||
} else {
|
|
||||||
filteredPolicies = policies.filter((p) => p.enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
const policySet = new Set(filteredPolicies.map((p) => p.organizationId));
|
|
||||||
|
|
||||||
return organizations.some(
|
|
||||||
(o) =>
|
|
||||||
o.enabled &&
|
|
||||||
o.status >= OrganizationUserStatusType.Accepted &&
|
|
||||||
o.usePolicies &&
|
|
||||||
!this.isExcemptFromPolicies(o, policyType) &&
|
|
||||||
policySet.has(o.id),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private isExcemptFromPolicies(organization: Organization, policyType: PolicyType) {
|
|
||||||
if (policyType === PolicyType.MaximumVaultTimeout) {
|
|
||||||
return organization.type === OrganizationUserType.Owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
return organization.isExemptFromPolicies;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,15 +4,12 @@ import { KeyConnectorService } from "../abstractions/keyConnector.service";
|
|||||||
import { LogService } from "../abstractions/log.service";
|
import { LogService } from "../abstractions/log.service";
|
||||||
import { MessagingService } from "../abstractions/messaging.service";
|
import { MessagingService } from "../abstractions/messaging.service";
|
||||||
import { OrganizationService } from "../abstractions/organization.service";
|
import { OrganizationService } from "../abstractions/organization.service";
|
||||||
import { PolicyService } from "../abstractions/policy.service";
|
|
||||||
import { SettingsService } from "../abstractions/settings.service";
|
import { SettingsService } from "../abstractions/settings.service";
|
||||||
import { StateService } from "../abstractions/state.service";
|
import { StateService } from "../abstractions/state.service";
|
||||||
import { SyncService as SyncServiceAbstraction } from "../abstractions/sync.service";
|
import { SyncService as SyncServiceAbstraction } from "../abstractions/sync.service";
|
||||||
import { sequentialize } from "../misc/sequentialize";
|
import { sequentialize } from "../misc/sequentialize";
|
||||||
import { OrganizationData } from "../models/data/organizationData";
|
import { OrganizationData } from "../models/data/organizationData";
|
||||||
import { PolicyData } from "../models/data/policyData";
|
|
||||||
import { DomainsResponse } from "../models/response/domainsResponse";
|
import { DomainsResponse } from "../models/response/domainsResponse";
|
||||||
import { PolicyResponse } from "../models/response/policyResponse";
|
|
||||||
import { ProfileResponse } from "../models/response/profileResponse";
|
import { ProfileResponse } from "../models/response/profileResponse";
|
||||||
|
|
||||||
export class SyncService implements SyncServiceAbstraction {
|
export class SyncService implements SyncServiceAbstraction {
|
||||||
@@ -23,7 +20,6 @@ export class SyncService implements SyncServiceAbstraction {
|
|||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private policyService: PolicyService,
|
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private keyConnectorService: KeyConnectorService,
|
private keyConnectorService: KeyConnectorService,
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
@@ -77,7 +73,6 @@ export class SyncService implements SyncServiceAbstraction {
|
|||||||
|
|
||||||
await this.syncProfile(response.profile);
|
await this.syncProfile(response.profile);
|
||||||
await this.syncSettings(response.domains);
|
await this.syncSettings(response.domains);
|
||||||
await this.syncPolicies(response.policies);
|
|
||||||
|
|
||||||
await this.setLastSync(now);
|
await this.setLastSync(now);
|
||||||
return this.syncCompleted(true);
|
return this.syncCompleted(true);
|
||||||
@@ -176,14 +171,4 @@ export class SyncService implements SyncServiceAbstraction {
|
|||||||
|
|
||||||
return this.settingsService.setEquivalentDomains(eqDomains);
|
return this.settingsService.setEquivalentDomains(eqDomains);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async syncPolicies(response: PolicyResponse[]) {
|
|
||||||
const policies: { [id: string]: PolicyData } = {};
|
|
||||||
if (response != null) {
|
|
||||||
response.forEach((p) => {
|
|
||||||
policies[p.id] = new PolicyData(p);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return await this.policyService.replace(policies);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { EnvironmentService } from "@/jslib/common/src/abstractions/environment.
|
|||||||
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
import { PasswordGenerationService } from "@/jslib/common/src/abstractions/passwordGeneration.service";
|
import { PasswordGenerationService } from "@/jslib/common/src/abstractions/passwordGeneration.service";
|
||||||
import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service";
|
import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service";
|
||||||
import { PolicyService } from "@/jslib/common/src/abstractions/policy.service";
|
|
||||||
import { StateService } from "@/jslib/common/src/abstractions/state.service";
|
import { StateService } from "@/jslib/common/src/abstractions/state.service";
|
||||||
import { TwoFactorService } from "@/jslib/common/src/abstractions/twoFactor.service";
|
import { TwoFactorService } from "@/jslib/common/src/abstractions/twoFactor.service";
|
||||||
import { TwoFactorProviderType } from "@/jslib/common/src/enums/twoFactorProviderType";
|
import { TwoFactorProviderType } from "@/jslib/common/src/enums/twoFactorProviderType";
|
||||||
@@ -53,7 +52,6 @@ export class LoginCommand {
|
|||||||
protected platformUtilsService: PlatformUtilsService,
|
protected platformUtilsService: PlatformUtilsService,
|
||||||
protected stateService: StateService,
|
protected stateService: StateService,
|
||||||
protected cryptoService: CryptoService,
|
protected cryptoService: CryptoService,
|
||||||
protected policyService: PolicyService,
|
|
||||||
protected twoFactorService: TwoFactorService,
|
protected twoFactorService: TwoFactorService,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
) {
|
) {
|
||||||
@@ -372,23 +370,9 @@ export class LoginCommand {
|
|||||||
const masterPasswordHint = hint.input;
|
const masterPasswordHint = hint.input;
|
||||||
|
|
||||||
// Retrieve details for key generation
|
// Retrieve details for key generation
|
||||||
const enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions();
|
|
||||||
const kdf = await this.stateService.getKdfType();
|
const kdf = await this.stateService.getKdfType();
|
||||||
const kdfIterations = await this.stateService.getKdfIterations();
|
const kdfIterations = await this.stateService.getKdfIterations();
|
||||||
|
|
||||||
if (
|
|
||||||
enforcedPolicyOptions != null &&
|
|
||||||
!this.policyService.evaluateMasterPassword(
|
|
||||||
strengthResult.score,
|
|
||||||
masterPassword,
|
|
||||||
enforcedPolicyOptions,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return this.updateTempPassword(
|
|
||||||
"Your new master password does not meet the policy requirements.\n",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create new key and hash new password
|
// Create new key and hash new password
|
||||||
const newKey = await this.cryptoService.makeKey(
|
const newKey = await this.cryptoService.makeKey(
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import { KeyConnectorService } from "@/jslib/common/src/services/keyConnector.se
|
|||||||
import { NoopMessagingService } from "@/jslib/common/src/services/noopMessaging.service";
|
import { NoopMessagingService } from "@/jslib/common/src/services/noopMessaging.service";
|
||||||
import { OrganizationService } from "@/jslib/common/src/services/organization.service";
|
import { OrganizationService } from "@/jslib/common/src/services/organization.service";
|
||||||
import { PasswordGenerationService } from "@/jslib/common/src/services/passwordGeneration.service";
|
import { PasswordGenerationService } from "@/jslib/common/src/services/passwordGeneration.service";
|
||||||
import { PolicyService } from "@/jslib/common/src/services/policy.service";
|
|
||||||
import { SearchService } from "@/jslib/common/src/services/search.service";
|
import { SearchService } from "@/jslib/common/src/services/search.service";
|
||||||
import { SettingsService } from "@/jslib/common/src/services/settings.service";
|
import { SettingsService } from "@/jslib/common/src/services/settings.service";
|
||||||
import { TokenService } from "@/jslib/common/src/services/token.service";
|
import { TokenService } from "@/jslib/common/src/services/token.service";
|
||||||
@@ -61,7 +60,6 @@ export class Main {
|
|||||||
settingsService: SettingsService;
|
settingsService: SettingsService;
|
||||||
syncService: SyncService;
|
syncService: SyncService;
|
||||||
passwordGenerationService: PasswordGenerationService;
|
passwordGenerationService: PasswordGenerationService;
|
||||||
policyService: PolicyService;
|
|
||||||
keyConnectorService: KeyConnectorService;
|
keyConnectorService: KeyConnectorService;
|
||||||
program: Program;
|
program: Program;
|
||||||
stateService: StateService;
|
stateService: StateService;
|
||||||
@@ -194,15 +192,8 @@ export class Main {
|
|||||||
this.stateService,
|
this.stateService,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.policyService = new PolicyService(
|
|
||||||
this.stateService,
|
|
||||||
this.organizationService,
|
|
||||||
this.apiService,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.passwordGenerationService = new PasswordGenerationService(
|
this.passwordGenerationService = new PasswordGenerationService(
|
||||||
this.cryptoService,
|
this.cryptoService,
|
||||||
this.policyService,
|
|
||||||
this.stateService,
|
this.stateService,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ export class Program extends BaseProgram {
|
|||||||
this.main.platformUtilsService,
|
this.main.platformUtilsService,
|
||||||
this.main.stateService,
|
this.main.stateService,
|
||||||
this.main.cryptoService,
|
this.main.cryptoService,
|
||||||
this.main.policyService,
|
|
||||||
this.main.twoFactorService,
|
this.main.twoFactorService,
|
||||||
"connector",
|
"connector",
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user