mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-29 18:42:15 +00:00
fix(console): move org domains into settings page of the organization (#6612)
* fix: hide domains settings for unauthorized users * refine sidenav object mapping * move domains to settings * change docs * set anchor to list element * remove canwrite check in ngif --------- Co-authored-by: Miguel A. C <[email protected]>
This commit is contained in:
co-authored by
Miguel A. C
parent
eb31c2a3be
commit
d01f4d229f
@@ -0,0 +1,18 @@
|
||||
<span class="title" mat-dialog-title>{{ 'ORG.DOMAINS.ADD.TITLE' | translate }}</span>
|
||||
<div mat-dialog-content>
|
||||
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.ADD.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<cnsl-form-field label="Domain" required="true" class="form-field">
|
||||
<cnsl-label>Domain</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="newdomain" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button mat-stroked-button (click)="closeDialog()">
|
||||
{{ 'ACTIONS.CANCEL' | translate }}
|
||||
</button>
|
||||
|
||||
<button color="primary" mat-raised-button class="ok-button" [disabled]="!newdomain" (click)="closeDialogWithSuccess()">
|
||||
{{ 'ACTIONS.ADD' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
.title {
|
||||
font-size: 1.2rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.ok-button {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { AddDomainDialogComponent } from './add-domain-dialog.component';
|
||||
|
||||
describe('WarnDialogComponent', () => {
|
||||
let component: AddDomainDialogComponent;
|
||||
let fixture: ComponentFixture<AddDomainDialogComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [AddDomainDialogComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddDomainDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import {
|
||||
MatLegacyDialogRef as MatDialogRef,
|
||||
MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA,
|
||||
} from '@angular/material/legacy-dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-add-domain-dialog',
|
||||
templateUrl: './add-domain-dialog.component.html',
|
||||
styleUrls: ['./add-domain-dialog.component.scss'],
|
||||
})
|
||||
export class AddDomainDialogComponent {
|
||||
public newdomain: string = '';
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<AddDomainDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
) {}
|
||||
|
||||
public closeDialog(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
public closeDialogWithSuccess(): void {
|
||||
this.dialogRef.close(this.newdomain);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { AddDomainDialogComponent } from './add-domain-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AddDomainDialogComponent],
|
||||
imports: [CommonModule, TranslateModule, MatButtonModule, InputModule, FormsModule],
|
||||
})
|
||||
export class AddDomainDialogModule {}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
<span class="title" mat-dialog-title>{{ 'ORG.PAGES.ORGDOMAIN.TITLE' | translate }} {{ domain?.domainName }}</span>
|
||||
<div mat-dialog-content>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION' | translate }}</p>
|
||||
|
||||
<cnsl-info-section [type]="InfoSectionType.WARN" class="desc">{{
|
||||
'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_DESC' | translate
|
||||
}}</cnsl-info-section>
|
||||
|
||||
<p
|
||||
*ngIf="domain?.validationType !== DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED && !(dns || http)"
|
||||
class="desc"
|
||||
>
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING' | translate: domain }}
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_VALIDATION_ONGOING_TYPE' | translate }}
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.TYPES.' + domain?.validationType | translate }}
|
||||
</p>
|
||||
|
||||
<div class="btn-container">
|
||||
<button
|
||||
[disabled]="domain?.validationType === DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED"
|
||||
color="primary"
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
*ngIf="!(dns || http)"
|
||||
(click)="validate()"
|
||||
>
|
||||
{{ 'ACTIONS.VERIFY' | translate }}
|
||||
</button>
|
||||
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
|
||||
|
||||
<button *ngIf="!showNew" mat-stroked-button color="primary" (click)="showNew = true">
|
||||
{{ 'ORG.PAGES.ORGDOMAIN.REQUESTNEWTOKEN' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="showNew">
|
||||
<p>{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_NEWTOKEN_TITLE' | translate }}</p>
|
||||
<p class="desc">{{ 'ORG.PAGES.ORGDOMAIN.VERIFICATION_NEWTOKEN_DESC' | translate }}</p>
|
||||
|
||||
<div class="btn-container" *ngIf="!(http || dns)">
|
||||
<button color="primary" mat-raised-button (click)="loadHttpToken()">HTTP</button>
|
||||
<button color="primary" mat-raised-button (click)="loadDnsToken()">DNS</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="http">
|
||||
<p>HTTP TOKEN</p>
|
||||
<p class="entry">{{ http.url }}</p>
|
||||
|
||||
<div class="btn-container">
|
||||
<button mat-stroked-button (click)="saveFile()" color="primary">{{ 'ORG.PAGES.DOWNLOAD_FILE' | translate }}</button>
|
||||
<button color="primary" class="verify-button" type="submit" mat-raised-button (click)="validate()">
|
||||
<span>{{ 'ACTIONS.VERIFY' | translate }}</span>
|
||||
</button>
|
||||
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="dns">
|
||||
<p>DNS TOKEN</p>
|
||||
<div class="domain-line" *ngIf="dns.token">
|
||||
<p class="entry">{{ dns.token }}</p>
|
||||
<button
|
||||
color="primary"
|
||||
[disabled]="copied === data.clientSecret"
|
||||
matTooltip="copy to clipboard"
|
||||
cnslCopyToClipboard
|
||||
[valueToCopy]="dns.token"
|
||||
(copiedValue)="copied = $event"
|
||||
mat-icon-button
|
||||
>
|
||||
<i *ngIf="copied !== dns.token" class="las la-clipboard"></i>
|
||||
<i *ngIf="copied === dns.token" class="las la-clipboard-check"></i>
|
||||
</button>
|
||||
<button color="primary" type="submit" mat-raised-button class="verify-button" (click)="validate()">
|
||||
{{ 'ACTIONS.VERIFY' | translate }}
|
||||
</button>
|
||||
<mat-spinner class="spinner" *ngIf="validating" diameter="20" mode="indeterminate"></mat-spinner>
|
||||
</div>
|
||||
<p class="entry">{{ dns.url }}</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button mat-stroked-button (click)="closeDialog()">
|
||||
{{ 'ACTIONS.CLOSE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
.btn-container {
|
||||
display: flex;
|
||||
margin: -0.5rem;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
margin: 1rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.entry {
|
||||
margin: 0.5rem 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.domain-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { DomainVerificationComponent } from './domain-verification.component';
|
||||
|
||||
describe('DomainVerificationComponent', () => {
|
||||
let component: DomainVerificationComponent;
|
||||
let fixture: ComponentFixture<DomainVerificationComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DomainVerificationComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DomainVerificationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,93 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import {
|
||||
MatLegacyDialogRef as MatDialogRef,
|
||||
MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA,
|
||||
} from '@angular/material/legacy-dialog';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { InfoSectionType } from 'src/app/modules/info-section/info-section.component';
|
||||
import { GenerateOrgDomainValidationResponse } from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { Domain, DomainValidationType } from 'src/app/proto/generated/zitadel/org_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-domain-verification',
|
||||
templateUrl: './domain-verification.component.html',
|
||||
styleUrls: ['./domain-verification.component.scss'],
|
||||
})
|
||||
export class DomainVerificationComponent {
|
||||
public domain?: Domain.AsObject;
|
||||
|
||||
public DomainValidationType: any = DomainValidationType;
|
||||
|
||||
public http?: GenerateOrgDomainValidationResponse.AsObject;
|
||||
public dns?: GenerateOrgDomainValidationResponse.AsObject;
|
||||
|
||||
public copied: string = '';
|
||||
|
||||
public showNew: boolean = false;
|
||||
|
||||
public validating: boolean = false;
|
||||
public InfoSectionType: any = InfoSectionType;
|
||||
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
public dialogRef: MatDialogRef<DomainVerificationComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private mgmtService: ManagementService,
|
||||
) {
|
||||
this.domain = data.domain;
|
||||
|
||||
if (this.domain?.validationType === DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED) {
|
||||
this.showNew = true;
|
||||
}
|
||||
}
|
||||
|
||||
async loadHttpToken(): Promise<void> {
|
||||
if (this.domain) {
|
||||
this.mgmtService
|
||||
.generateOrgDomainValidation(this.domain.domainName, DomainValidationType.DOMAIN_VALIDATION_TYPE_HTTP)
|
||||
.then((http) => {
|
||||
this.http = http;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async loadDnsToken(): Promise<void> {
|
||||
if (this.domain) {
|
||||
this.mgmtService
|
||||
.generateOrgDomainValidation(this.domain.domainName, DomainValidationType.DOMAIN_VALIDATION_TYPE_DNS)
|
||||
.then((dns) => {
|
||||
this.dns = dns;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
public validate(): void {
|
||||
this.validating = true;
|
||||
if (this.domain) {
|
||||
this.mgmtService
|
||||
.validateOrgDomain(this.domain.domainName)
|
||||
.then(() => {
|
||||
this.dialogRef.close(true);
|
||||
this.toast.showInfo('ORG.PAGES.ORGDOMAIN.VERIFICATION_SUCCESSFUL', true);
|
||||
this.validating = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
this.validating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public saveFile(): void {
|
||||
if (this.http) {
|
||||
const blob = new Blob([this.http.token], { type: 'text/plain;charset=utf-8' });
|
||||
saveAs(blob, this.http.token + '.txt');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<ng-container *ngIf="['org.write$'] | hasRole as canwrite$">
|
||||
<div class="domain-top-view">
|
||||
<div>
|
||||
<div class="domain-title-row">
|
||||
<h2>{{ 'ORG.DOMAINS.TITLE' | translate }}</h2>
|
||||
<a
|
||||
mat-icon-button
|
||||
href="https://zitadel.com/docs/guides/manage/console/organizations#how-zitadel-handles-usernames"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<i class="las la-info-circle"></i>
|
||||
</a>
|
||||
</div>
|
||||
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.DESCRIPTION' | translate }}</p>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<button
|
||||
[disabled]="(canwrite$ | async) === false"
|
||||
matTooltip="Add domain"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
class="cnsl-action-button"
|
||||
(click)="addNewDomain()"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
<cnsl-action-keys (actionTriggered)="addNewDomain()"> </cnsl-action-keys>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<cnsl-card *ngFor="let domain of domains" class="domain-card">
|
||||
<div class="domain">
|
||||
<span class="title">{{ domain.domainName }}</span>
|
||||
|
||||
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
||||
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
||||
<a
|
||||
*ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)"
|
||||
class="primaryset"
|
||||
(click)="setPrimary(domain)"
|
||||
>{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a
|
||||
>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
||||
*ngIf="verifyOrgDomains"
|
||||
(click)="verifyDomain(domain)"
|
||||
>
|
||||
<i class="las la-pen"></i>
|
||||
</button>
|
||||
<button
|
||||
class="domain-rem-button"
|
||||
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
||||
matTooltip="Remove domain"
|
||||
color="warn"
|
||||
mat-icon-button
|
||||
(click)="removeDomain(domain.domainName)"
|
||||
>
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</ng-container>
|
||||
@@ -0,0 +1,68 @@
|
||||
.domain-top-view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.domain-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a i {
|
||||
font-size: 1.2rem;
|
||||
height: 1.2rem;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-bottom: 2rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.domain-card {
|
||||
.domain {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.primaryset {
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.verified,
|
||||
.primary {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.verify-btn {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OrgDomainsComponent } from './org-domains.component';
|
||||
|
||||
describe('OrgDomainsComponent', () => {
|
||||
let component: OrgDomainsComponent;
|
||||
let fixture: ComponentFixture<OrgDomainsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [OrgDomainsComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OrgDomainsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,133 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog';
|
||||
import { InfoSectionType } from 'src/app/modules/info-section/info-section.component';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { Domain, DomainValidationType } from 'src/app/proto/generated/zitadel/org_pb';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import { AddDomainDialogComponent } from './add-domain-dialog/add-domain-dialog.component';
|
||||
import { DomainVerificationComponent } from './domain-verification/domain-verification.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-domains',
|
||||
templateUrl: './domains.component.html',
|
||||
styleUrls: ['./domains.component.scss'],
|
||||
})
|
||||
export class DomainsComponent implements OnInit {
|
||||
public domains: Domain.AsObject[] = [];
|
||||
public primaryDomain: string = '';
|
||||
public InfoSectionType: any = InfoSectionType;
|
||||
public verifyOrgDomains: boolean | undefined;
|
||||
|
||||
constructor(
|
||||
private mgmtService: ManagementService,
|
||||
private toast: ToastService,
|
||||
private dialog: MatDialog,
|
||||
breadcrumbService: BreadcrumbService,
|
||||
) {
|
||||
const bread: Breadcrumb = {
|
||||
type: BreadcrumbType.ORG,
|
||||
routerLink: ['/org'],
|
||||
};
|
||||
breadcrumbService.setBreadcrumb([bread]);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadDomains();
|
||||
}
|
||||
|
||||
public loadDomains(): void {
|
||||
this.mgmtService.getDomainPolicy().then((result) => {
|
||||
this.verifyOrgDomains = result.policy?.validateOrgDomains;
|
||||
});
|
||||
|
||||
this.mgmtService.listOrgDomains().then((result) => {
|
||||
this.domains = result.resultList;
|
||||
this.primaryDomain = this.domains.find((domain) => domain.isPrimary)?.domainName ?? '';
|
||||
});
|
||||
}
|
||||
|
||||
public setPrimary(domain: Domain.AsObject): void {
|
||||
this.mgmtService
|
||||
.setPrimaryOrgDomain(domain.domainName)
|
||||
.then(() => {
|
||||
this.toast.showInfo('ORG.TOAST.SETPRIMARY', true);
|
||||
this.loadDomains();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public addNewDomain(): void {
|
||||
const dialogRef = this.dialog.open(AddDomainDialogComponent, {
|
||||
data: {},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((domainName) => {
|
||||
if (domainName) {
|
||||
this.mgmtService
|
||||
.addOrgDomain(domainName)
|
||||
.then(() => {
|
||||
this.toast.showInfo('ORG.TOAST.DOMAINADDED', true);
|
||||
if (this.verifyOrgDomains) {
|
||||
this.verifyDomain({
|
||||
domainName: domainName,
|
||||
validationType: DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED,
|
||||
});
|
||||
} else {
|
||||
this.loadDomains();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public removeDomain(domain: string): void {
|
||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'ORG.DOMAINS.DELETE.TITLE',
|
||||
descriptionKey: 'ORG.DOMAINS.DELETE.DESCRIPTION',
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((del) => {
|
||||
if (del) {
|
||||
this.mgmtService
|
||||
.removeOrgDomain(domain)
|
||||
.then(() => {
|
||||
this.toast.showInfo('ORG.TOAST.DOMAINREMOVED', true);
|
||||
const index = this.domains.findIndex((d) => d.domainName === domain);
|
||||
if (index > -1) {
|
||||
this.domains.splice(index, 1);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public verifyDomain(domain: Partial<Domain.AsObject>): void {
|
||||
const dialogRef = this.dialog.open(DomainVerificationComponent, {
|
||||
data: {
|
||||
domain: domain,
|
||||
},
|
||||
width: '500px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(() => {
|
||||
this.loadDomains();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module';
|
||||
import { ActionKeysModule } from 'src/app/modules/action-keys/action-keys.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
|
||||
import { AddDomainDialogModule } from './add-domain-dialog/add-domain-dialog.module';
|
||||
import { DomainVerificationComponent } from './domain-verification/domain-verification.component';
|
||||
import { DomainsComponent } from './domains.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [DomainsComponent, DomainVerificationComponent],
|
||||
imports: [
|
||||
AddDomainDialogModule,
|
||||
CommonModule,
|
||||
MatIconModule,
|
||||
CardModule,
|
||||
HasRolePipeModule,
|
||||
ActionKeysModule,
|
||||
InfoSectionModule,
|
||||
MatButtonModule,
|
||||
MatTooltipModule,
|
||||
CopyToClipboardModule,
|
||||
InputModule,
|
||||
TranslateModule,
|
||||
InfoSectionModule,
|
||||
MatProgressSpinnerModule,
|
||||
],
|
||||
exports: [DomainsComponent],
|
||||
})
|
||||
export default class DomainsModule {}
|
||||
@@ -177,17 +177,6 @@
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<a
|
||||
class="nav-item"
|
||||
[routerLinkActive]="['active']"
|
||||
[routerLink]="['/domains']"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<span class="label">{{ 'MENU.DOMAINS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<a
|
||||
class="nav-item"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<h2>{{ 'POLICY.DOMAIN_POLICY.TITLE' | translate }}</h2>
|
||||
<cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section>
|
||||
|
||||
<!-- <ng-template cnslHasRole [hasRole]="['domain.policy.delete']"> -->
|
||||
<button
|
||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||
@@ -26,7 +25,6 @@
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
<!-- </ng-template> -->
|
||||
|
||||
<div class="domain-policy-content" *ngIf="domainData">
|
||||
<div class="row">
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
<ng-container *ngIf="currentSetting === 'login'">
|
||||
<cnsl-login-policy [serviceType]="serviceType"></cnsl-login-policy>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentSetting === 'verified_domains'">
|
||||
<cnsl-domains></cnsl-domains>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="currentSetting === 'domain' && (['iam.policy.write'] | hasRole | async) === true">
|
||||
<cnsl-domain-policy [serviceType]="serviceType"></cnsl-domain-policy>
|
||||
</ng-container>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
|
||||
import { CardModule } from '../card/card.module';
|
||||
import DomainsModule from '../domains/domains.module';
|
||||
import { DomainPolicyModule } from '../policies/domain-policy/domain-policy.module';
|
||||
import { GeneralSettingsModule } from '../policies/general-settings/general-settings.module';
|
||||
import { IdpSettingsModule } from '../policies/idp-settings/idp-settings.module';
|
||||
@@ -40,6 +41,7 @@ import { SettingsListComponent } from './settings-list.component';
|
||||
PrivacyPolicyModule,
|
||||
MessageTextsPolicyModule,
|
||||
SecurityPolicyModule,
|
||||
DomainsModule,
|
||||
LoginTextsPolicyModule,
|
||||
DomainPolicyModule,
|
||||
TranslateModule,
|
||||
|
||||
@@ -43,6 +43,15 @@ export const LOGIN: SidenavSetting = {
|
||||
},
|
||||
};
|
||||
|
||||
export const VERIFIED_DOMAINS: SidenavSetting = {
|
||||
id: 'verified_domains',
|
||||
i18nKey: 'SETTINGS.LIST.VERIFIED_DOMAINS',
|
||||
groupI18nKey: 'SETTINGS.GROUPS.DOMAIN',
|
||||
requiredRoles: {
|
||||
[PolicyComponentServiceType.MGMT]: ['org.read'],
|
||||
},
|
||||
};
|
||||
|
||||
export const DOMAIN: SidenavSetting = {
|
||||
id: 'domain',
|
||||
i18nKey: 'SETTINGS.LIST.DOMAIN',
|
||||
|
||||
Reference in New Issue
Block a user