diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html index add53a0cd33..1153ad58719 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill.component.html @@ -232,7 +232,7 @@ {{ "enableAutoTotpCopy" | i18n }} - + {{ "clearClipboard" | i18n }} - + {{ "defaultUriMatchDetection" | i18n }} - - {{ "settingDisabledByPolicy" | i18n }} - {{ hints[0] | i18n }} diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/index.ts b/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/index.ts index 7373e1ff888..9b46e228af9 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/index.ts +++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/index.ts @@ -10,6 +10,7 @@ export { RestrictedItemTypesPolicy } from "./restricted-item-types.component"; export { SendOptionsPolicy } from "./send-options.component"; export { SingleOrgPolicy } from "./single-org.component"; export { TwoFactorAuthenticationPolicy } from "./two-factor-authentication.component"; +export { UriMatchDefaultPolicy } from "./uri-match-default.component"; export { vNextOrganizationDataOwnershipPolicy, vNextOrganizationDataOwnershipPolicyComponent, diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/uri-match-default.component.html b/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/uri-match-default.component.html new file mode 100644 index 00000000000..399a4ad2dcd --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/uri-match-default.component.html @@ -0,0 +1,22 @@ + + {{ "requireSsoPolicyReq" | i18n }} + + + + + {{ "turnOn" | i18n }} + + +
+ + {{ "uriMatchDetectionOptionsLabel" | i18n }} + + + + +
diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/uri-match-default.component.ts b/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/uri-match-default.component.ts new file mode 100644 index 00000000000..5c0b667bea2 --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/uri-match-default.component.ts @@ -0,0 +1,72 @@ +import { Component, ChangeDetectionStrategy } from "@angular/core"; +import { FormBuilder, FormControl, Validators } from "@angular/forms"; + +import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { PolicyRequest } from "@bitwarden/common/admin-console/models/request/policy.request"; +import { + UriMatchStrategy, + UriMatchStrategySetting, +} from "@bitwarden/common/models/domain/domain-service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; + +import { SharedModule } from "../../../../shared"; +import { BasePolicyEditDefinition, BasePolicyEditComponent } from "../base-policy-edit.component"; + +export class UriMatchDefaultPolicy extends BasePolicyEditDefinition { + name = "uriMatchDetectionPolicy"; + description = "uriMatchDetectionPolicyDesc"; + type = PolicyType.UriMatchDefaults; + component = UriMatchDefaultPolicyComponent; +} +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: "uri-match-default.component.html", + imports: [SharedModule], +}) +export class UriMatchDefaultPolicyComponent extends BasePolicyEditComponent { + uriMatchOptions: { label: string; value: UriMatchStrategySetting | null; disabled?: boolean }[]; + + constructor( + private formBuilder: FormBuilder, + private i18nService: I18nService, + ) { + super(); + + this.data = this.formBuilder.group({ + uriMatchDetection: new FormControl(UriMatchStrategy.Domain, { + validators: [Validators.required], + nonNullable: true, + }), + }); + + this.uriMatchOptions = [ + { label: i18nService.t("baseDomain"), value: UriMatchStrategy.Domain }, + { label: i18nService.t("host"), value: UriMatchStrategy.Host }, + { label: i18nService.t("exact"), value: UriMatchStrategy.Exact }, + { label: i18nService.t("never"), value: UriMatchStrategy.Never }, + ]; + } + + protected loadData() { + const uriMatchDetection = this.policyResponse?.data?.uriMatchDetection; + + this.data?.patchValue({ + uriMatchDetection: uriMatchDetection, + }); + } + + protected buildRequestData() { + return { + uriMatchDetection: this.data?.value?.uriMatchDetection, + }; + } + + async buildRequest(): Promise { + const request = await super.buildRequest(); + if (request.data?.uriMatchDetection == null) { + throw new Error(this.i18nService.t("invalidUriMatchDefaultPolicySetting")); + } + + return request; + } +} diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit-register.ts b/apps/web/src/app/admin-console/organizations/policies/policy-edit-register.ts index ca44818764c..a4bdece0a7b 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policy-edit-register.ts +++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit-register.ts @@ -13,6 +13,7 @@ import { SendOptionsPolicy, SingleOrgPolicy, TwoFactorAuthenticationPolicy, + UriMatchDefaultPolicy, vNextOrganizationDataOwnershipPolicy, } from "./policy-edit-definitions"; @@ -34,5 +35,6 @@ export const ossPolicyEditRegister: BasePolicyEditDefinition[] = [ new SendOptionsPolicy(), new RestrictedItemTypesPolicy(), new DesktopAutotypeDefaultSettingPolicy(), + new UriMatchDefaultPolicy(), new AutoConfirmPolicy(), ]; diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 36d68429ac6..634e60db0c5 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -5881,6 +5881,19 @@ "message": "Always show member’s email address with recipients when creating or editing a Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, + "uriMatchDetectionPolicy": { + "message": "Default URI match detection" + }, + "uriMatchDetectionPolicyDesc": { + "message": "Determine when logins are suggested for autofill. Admins and owners are exempt from this policy." + }, + "uriMatchDetectionOptionsLabel": { + "message": "Default URI match detection" + }, + "invalidUriMatchDefaultPolicySetting": { + "message": "Please select a valid URI match detection option.", + "description": "Error message displayed when a user attempts to save URI match detection policy settings with an invalid selection." + }, "modifiedPolicyId": { "message": "Modified policy $ID$.", "placeholders": { @@ -9659,7 +9672,7 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, - "uriMatchDefaultStrategyHint": { + "uriMatchDefaultStrategyHint": { "message": "URI match detection is how Bitwarden identifies autofill suggestions.", "description": "Explains to the user that URI match detection determines how Bitwarden suggests autofill options, and clarifies that this default strategy applies when no specific match detection is set for a login item." }, diff --git a/libs/common/src/autofill/services/domain-settings.service.ts b/libs/common/src/autofill/services/domain-settings.service.ts index d6ab8851ad7..fa7a37ba732 100644 --- a/libs/common/src/autofill/services/domain-settings.service.ts +++ b/libs/common/src/autofill/services/domain-settings.service.ts @@ -166,7 +166,7 @@ export class DefaultDomainSettingsService implements DomainSettingsService { if (!policy?.enabled || policy?.data == null) { return null; } - const data = policy.data?.defaultUriMatchStrategy; + const data = policy.data?.uriMatchDetection; // Validate that data is a valid UriMatchStrategy value return Object.values(UriMatchStrategy).includes(data) ? data : null; }),