mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 16:23:44 +00:00
SG-680 - DomainAddEditDialog - Unique domain name enforcement implemented
This commit is contained in:
@@ -5568,6 +5568,9 @@
|
||||
"domainVerified": {
|
||||
"message": "Domain verified"
|
||||
},
|
||||
"duplicateDomainError": {
|
||||
"message": "You can't claim the same domain twice."
|
||||
},
|
||||
"domainNotVerified": {
|
||||
"message": "$DOMAIN$ not verified. Check your DNS record.",
|
||||
"placeholders": {
|
||||
@@ -5577,5 +5580,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { OrganizationDomainRequest } from "@bitwarden/common/services/organization-domain/requests/organization-domain.request";
|
||||
|
||||
import { domainNameValidator } from "./domain-name.validator";
|
||||
import { uniqueInArrayValidator } from "./unique-in-array.validator";
|
||||
export interface DomainAddEditDialogData {
|
||||
organizationId: string;
|
||||
orgDomain: OrganizationDomainResponse;
|
||||
@@ -26,11 +27,17 @@ export class DomainAddEditDialogComponent implements OnInit {
|
||||
disablePadding = false;
|
||||
|
||||
// TODO: should invalidDomainNameMessage have something like: "'https://', 'http://', or 'www.' domain prefixes not allowed."
|
||||
// TODO: write separate uniqueIn validator w/ translated msg: "You can’t claim the same domain twice."
|
||||
domainForm: FormGroup = this.formBuilder.group({
|
||||
domainName: [
|
||||
"",
|
||||
[Validators.required, domainNameValidator(this.i18nService.t("invalidDomainNameMessage"))],
|
||||
[
|
||||
Validators.required,
|
||||
domainNameValidator(this.i18nService.t("invalidDomainNameMessage")),
|
||||
uniqueInArrayValidator(
|
||||
this.data.existingDomainNames,
|
||||
this.i18nService.t("duplicateDomainError")
|
||||
),
|
||||
],
|
||||
],
|
||||
txt: [{ value: null, disabled: true }],
|
||||
});
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { AbstractControl, ValidationErrors, ValidatorFn } from "@angular/forms";
|
||||
export function uniqueInArrayValidator(values: Array<string>, errorMessage: string): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
const value = control.value;
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const lowerTrimmedValue = value.toLowerCase().trim();
|
||||
|
||||
// check if the entered value is unique
|
||||
if (values.some((val) => val.toLowerCase().trim() === lowerTrimmedValue)) {
|
||||
return {
|
||||
nonUniqueValue: {
|
||||
message: errorMessage,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, Params } from "@angular/router";
|
||||
import { concatMap, Observable, Subject, takeUntil } from "rxjs";
|
||||
import { concatMap, Observable, Subject, take, takeUntil } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
@@ -68,7 +68,7 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
const domainAddEditDialogData: DomainAddEditDialogData = {
|
||||
organizationId: this.organizationId,
|
||||
orgDomain: null,
|
||||
existingDomainNames: [],
|
||||
existingDomainNames: this.getExistingDomainNames(),
|
||||
};
|
||||
|
||||
this.dialogService.open(DomainAddEditDialogComponent, {
|
||||
@@ -80,7 +80,7 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
const domainAddEditDialogData: DomainAddEditDialogData = {
|
||||
organizationId: this.organizationId,
|
||||
orgDomain: orgDomain,
|
||||
existingDomainNames: [],
|
||||
existingDomainNames: this.getExistingDomainNames(),
|
||||
};
|
||||
|
||||
this.dialogService.open(DomainAddEditDialogComponent, {
|
||||
@@ -88,6 +88,15 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
private getExistingDomainNames(): Array<string> {
|
||||
let existingDomainNames: string[];
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
this.orgDomains$.pipe(take(1)).subscribe((orgDomains: Array<OrganizationDomainResponse>) => {
|
||||
existingDomainNames = orgDomains.map((o) => o.domainName);
|
||||
});
|
||||
return existingDomainNames;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.componentDestroyed$.next();
|
||||
this.componentDestroyed$.complete();
|
||||
|
||||
Reference in New Issue
Block a user