mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-06 14:37:41 +00:00
feat(console): Active Directory / LDAP, cleanup idp component routing (#5506)
feat(console): LDAP
This commit is contained in:
parent
a14bfff0bb
commit
542271b467
@ -76,6 +76,10 @@
|
||||
<img class="idp-logo light" src="./assets/images/idp/github.svg" alt="github" />
|
||||
GitHub Enterprise Server
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchCase="ProviderType.PROVIDER_TYPE_LDAP">
|
||||
<i class="idp-icon las la-building"></i>
|
||||
Active Directory / LDAP
|
||||
</div>
|
||||
<div class="idp-table-provider-type" *ngSwitchDefault>coming soon</div>
|
||||
</div>
|
||||
</td>
|
||||
@ -162,6 +166,10 @@
|
||||
</button>
|
||||
<button
|
||||
actions
|
||||
*ngIf="
|
||||
(serviceType === PolicyComponentServiceType.MGMT && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||
(serviceType === PolicyComponentServiceType.ADMIN && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM)
|
||||
"
|
||||
[disabled]="
|
||||
(serviceType === PolicyComponentServiceType.MGMT && idp?.providerType === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||
([
|
||||
|
@ -226,6 +226,8 @@ export class IdpTableComponent implements OnInit {
|
||||
return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'google', row.id];
|
||||
case ProviderType.PROVIDER_TYPE_GITLAB:
|
||||
return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'gitlab', row.id];
|
||||
case ProviderType.PROVIDER_TYPE_LDAP:
|
||||
return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'ldap', row.id];
|
||||
case ProviderType.PROVIDER_TYPE_GITLAB_SELF_HOSTED:
|
||||
return [
|
||||
row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org',
|
||||
|
@ -161,4 +161,22 @@
|
||||
<span class="title">Generic JWT</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a
|
||||
class="item card"
|
||||
[routerLink]="
|
||||
serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['/instance', 'provider', 'ldap', 'create']
|
||||
: serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['/org', 'provider', 'ldap', 'create']
|
||||
: []
|
||||
"
|
||||
>
|
||||
<div class="idp-icon">
|
||||
<i class="icon las la-building" svgIcon="mdi_jwt" alt="jwt"></i>
|
||||
</div>
|
||||
<div class="text-container">
|
||||
<span class="title">Active Directory / LDAP</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
||||
*ngIf="(getCustomInitMessageTextMap$ | async) && (getCustomInitMessageTextMap$ | async)?.isDefault === false"
|
||||
[disabled]="(canWrite$ | async) === false"
|
||||
(click)="resetDefault()"
|
||||
color="warn"
|
||||
color="message-text-warn"
|
||||
type="submit"
|
||||
mat-stroked-button
|
||||
>
|
||||
|
@ -35,7 +35,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.warn {
|
||||
.message-text-warn {
|
||||
margin-top: 1rem;
|
||||
display: block;
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
<form [formGroup]="form" class="attribute-form">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.LDAPIDATTRIBUTE' | translate }}*</cnsl-label>
|
||||
<input cnslInput formControlName="idAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.AVATARURLATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="avatarUrlAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.DISPLAYNAMEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="displayNameAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.EMAILATTRIBUTEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="emailAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.EMAILVERIFIEDATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="emailVerifiedAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.FIRSTNAMEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="firstNameAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.LASTNAMEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="lastNameAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.NICKNAMEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="nickNameAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.PHONEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="phoneAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.PHONEVERIFIEDATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="phoneVerifiedAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.PREFERREDLANGUAGEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="preferredLanguageAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.PREFERREDUSERNAMEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="preferredUsernameAttribute" />
|
||||
</cnsl-form-field>
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.PROFILEATTRIBUTE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="profileAttribute" />
|
||||
</cnsl-form-field>
|
||||
</form>
|
@ -0,0 +1,6 @@
|
||||
.attribute-form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
max-width: 400px;
|
||||
padding-bottom: 1rem;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LDAPAttributesComponent } from './ldap-attributes.component';
|
||||
|
||||
describe('LDAPAttributesComponent', () => {
|
||||
let component: LDAPAttributesComponent;
|
||||
let fixture: ComponentFixture<LDAPAttributesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [LDAPAttributesComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LDAPAttributesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,64 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { LDAPAttributes } from 'src/app/proto/generated/zitadel/idp_pb';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-ldap-attributes',
|
||||
templateUrl: './ldap-attributes.component.html',
|
||||
styleUrls: ['./ldap-attributes.component.scss'],
|
||||
})
|
||||
export class LDAPAttributesComponent implements OnChanges, OnDestroy {
|
||||
@Input() public initialAttributes?: LDAPAttributes.AsObject;
|
||||
@Output() public attributesChanged: EventEmitter<LDAPAttributes> = new EventEmitter<LDAPAttributes>();
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
public form: FormGroup = new FormGroup({
|
||||
avatarUrlAttribute: new FormControl('', []),
|
||||
displayNameAttribute: new FormControl('', []),
|
||||
emailAttribute: new FormControl('', []),
|
||||
emailVerifiedAttribute: new FormControl('', []),
|
||||
firstNameAttribute: new FormControl('', []),
|
||||
idAttribute: new FormControl('', [requiredValidator]),
|
||||
lastNameAttribute: new FormControl('', []),
|
||||
nickNameAttribute: new FormControl('', []),
|
||||
phoneAttribute: new FormControl('', []),
|
||||
phoneVerifiedAttribute: new FormControl('', []),
|
||||
preferredLanguageAttribute: new FormControl('', []),
|
||||
preferredUsernameAttribute: new FormControl('', []),
|
||||
profileAttribute: new FormControl('', []),
|
||||
});
|
||||
|
||||
constructor() {
|
||||
this.form.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) => {
|
||||
if (value) {
|
||||
const attr = new LDAPAttributes();
|
||||
attr.setAvatarUrlAttribute(value.avatarUrlAttribute);
|
||||
attr.setDisplayNameAttribute(value.displayNameAttribute);
|
||||
attr.setEmailAttribute(value.emailAttribute);
|
||||
attr.setEmailVerifiedAttribute(value.emailVerifiedAttribute);
|
||||
attr.setFirstNameAttribute(value.firstNameAttribute);
|
||||
attr.setIdAttribute(value.idAttribute);
|
||||
attr.setLastNameAttribute(value.lastNameAttribute);
|
||||
attr.setNickNameAttribute(value.nickNameAttribute);
|
||||
attr.setPhoneAttribute(value.phoneAttribute);
|
||||
attr.setPhoneVerifiedAttribute(value.phoneVerifiedAttribute);
|
||||
attr.setPreferredLanguageAttribute(value.preferredLanguageAttribute);
|
||||
attr.setPreferredUsernameAttribute(value.preferredUsernameAttribute);
|
||||
attr.setProfileAttribute(value.profileAttribute);
|
||||
this.attributesChanged.emit(attr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
if (this.initialAttributes) {
|
||||
this.form.patchValue(this.initialAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProviderAzureADComponent } from './provider-azure-ad.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderAzureADComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderAzureADRoutingModule {}
|
@ -98,7 +98,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -3,7 +3,7 @@ import { Location } from '@angular/common';
|
||||
import { Component, Injector, Type } from '@angular/core';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { take } from 'rxjs';
|
||||
import {
|
||||
AddAzureADProviderRequest as AdminAddAzureADProviderRequest,
|
||||
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -50,7 +51,7 @@ export class ProviderAzureADComponent {
|
||||
];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -67,6 +68,23 @@ export class ProviderAzureADComponent {
|
||||
emailVerified: new FormControl(false),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderAzureADRoutingModule } from './provider-azure-ad-routing.module';
|
||||
import { ProviderAzureADComponent } from './provider-azure-ad.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderAzureADComponent],
|
||||
imports: [
|
||||
ProviderAzureADRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderAzureADModule {}
|
@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ProviderGithubESComponent } from './provider-github-es.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderGithubESComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderGithubESRoutingModule {}
|
@ -97,7 +97,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -44,6 +45,7 @@ export class ProviderGithubESComponent {
|
||||
public provider?: Provider.AsObject;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -60,6 +62,23 @@ export class ProviderGithubESComponent {
|
||||
scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderGithubESRoutingModule } from './provider-github-es-routing.module';
|
||||
import { ProviderGithubESComponent } from './provider-github-es.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderGithubESComponent],
|
||||
imports: [
|
||||
ProviderGithubESRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderGithubESModule {}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProviderGithubComponent } from './provider-github.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderGithubComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderGithubRoutingModule {}
|
@ -84,7 +84,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -45,6 +46,7 @@ export class ProviderGithubComponent {
|
||||
public updateClientSecret: boolean = false;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -58,6 +60,23 @@ export class ProviderGithubComponent {
|
||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderGithubRoutingModule } from './provider-github-routing.module';
|
||||
import { ProviderGithubComponent } from './provider-github.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderGithubComponent],
|
||||
imports: [
|
||||
ProviderGithubRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderGithubModule {}
|
@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ProviderGitlabSelfHostedComponent } from './provider-gitlab-self-hosted.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderGitlabSelfHostedComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderGitlabSelfHostedRoutingModule {}
|
@ -87,7 +87,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -45,6 +46,7 @@ export class ProviderGitlabSelfHostedComponent {
|
||||
public updateClientSecret: boolean = false;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -59,6 +61,23 @@ export class ProviderGitlabSelfHostedComponent {
|
||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderGitlabSelfHostedRoutingModule } from './provider-gitlab-self-hosted-routing.module';
|
||||
import { ProviderGitlabSelfHostedComponent } from './provider-gitlab-self-hosted.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderGitlabSelfHostedComponent],
|
||||
imports: [
|
||||
ProviderGitlabSelfHostedRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderGitlabSelfHostedModule {}
|
@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ProviderGitlabComponent } from './provider-gitlab.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderGitlabComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderGitlabRoutingModule {}
|
@ -83,7 +83,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -45,6 +46,7 @@ export class ProviderGitlabComponent {
|
||||
public updateClientSecret: boolean = false;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -58,6 +60,23 @@ export class ProviderGitlabComponent {
|
||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderGitlabRoutingModule } from './provider-gitlab-routing.module';
|
||||
import { ProviderGitlabComponent } from './provider-gitlab.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderGitlabComponent],
|
||||
imports: [
|
||||
ProviderGitlabRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderGitlabModule {}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProviderGoogleComponent } from './provider-google.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderGoogleComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderGoogleRoutingModule {}
|
@ -83,7 +83,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -45,6 +46,7 @@ export class ProviderGoogleComponent {
|
||||
public updateClientSecret: boolean = false;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -58,6 +60,23 @@ export class ProviderGoogleComponent {
|
||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderGoogleRoutingModule } from './provider-google-routing.module';
|
||||
import { ProviderGoogleComponent } from './provider-google.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderGoogleComponent],
|
||||
imports: [
|
||||
ProviderGoogleRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderGoogleModule {}
|
@ -1,17 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ProviderJWTComponent } from './provider-jwt.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderJWTComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderJWTCreateRoutingModule {}
|
@ -50,7 +50,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -42,6 +43,7 @@ export class ProviderJWTComponent {
|
||||
public provider?: Provider.AsObject;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -87,6 +89,23 @@ export class ProviderJWTComponent {
|
||||
jwtEndpoint: new UntypedFormControl('', [requiredValidator]),
|
||||
keysEndpoint: new UntypedFormControl('', [requiredValidator]),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getData(id: string): void {
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderJWTCreateRoutingModule } from './provider-jwt-routing.module';
|
||||
import { ProviderJWTComponent } from './provider-jwt.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderJWTComponent],
|
||||
imports: [
|
||||
ProviderJWTCreateRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderJWTModule {}
|
@ -0,0 +1,125 @@
|
||||
<cnsl-create-layout
|
||||
title="{{ id ? ('IDP.DETAIL.TITLE' | translate) : ('IDP.CREATE.TITLE' | translate) }}"
|
||||
(closed)="close()"
|
||||
>
|
||||
<div class="identity-provider-create-content">
|
||||
<div class="title-row">
|
||||
<i class="idp-icon las la-building"></i>
|
||||
<h1>{{ 'IDP.CREATE.LDAP.TITLE' | translate }}</h1>
|
||||
<mat-spinner diameter="25" *ngIf="loading" color="primary"></mat-spinner>
|
||||
</div>
|
||||
|
||||
<p class="identity-provider-desc cnsl-secondary-text">
|
||||
{{ !provider ? ('IDP.CREATE.LDAP.DESCRIPTION' | translate) : ('IDP.DETAIL.DESCRIPTION' | translate) }}
|
||||
</p>
|
||||
|
||||
<form [formGroup]="form" (ngSubmit)="submitForm()">
|
||||
<div class="identity-provider-content">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<h2 class="subheader">{{ 'IDP.LDAPCONNECTION' | translate }}</h2>
|
||||
|
||||
<cnsl-string-list
|
||||
title="{{ 'IDP.SERVERS' | translate }}"
|
||||
formControlName="serversList"
|
||||
[required]="true"
|
||||
></cnsl-string-list>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.BASEDN' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="baseDn" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<div [ngClass]="{ 'identity-provider-2-col': !provider }">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.BINDDN' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="bindDn" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<mat-checkbox *ngIf="provider" [(ngModel)]="updateBindPassword" [ngModelOptions]="{ standalone: true }">{{
|
||||
'IDP.UPDATEBINDPASSWORD' | translate
|
||||
}}</mat-checkbox>
|
||||
<cnsl-form-field *ngIf="!provider || (provider && updateBindPassword)" class="formfield">
|
||||
<cnsl-label>{{ 'IDP.BINDPASSWORD' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="bindPassword" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
|
||||
<h2 class="subheader">{{ 'IDP.LDAPUSERBINDING' | translate }}</h2>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.USERBASE' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="userBase" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-string-list
|
||||
title="{{ 'IDP.USERFILTERS' | translate }}"
|
||||
formControlName="userFiltersList"
|
||||
[required]="true"
|
||||
></cnsl-string-list>
|
||||
|
||||
<cnsl-string-list
|
||||
title="{{ 'IDP.USEROBJECTCLASSES' | translate }}"
|
||||
formControlName="userObjectClassesList"
|
||||
[required]="true"
|
||||
></cnsl-string-list>
|
||||
|
||||
<div class="identity-provider-optional-h-wrapper">
|
||||
<h2>{{ 'IDP.LDAPATTRIBUTES' | translate }}</h2>
|
||||
|
||||
<button (click)="showAttributes = !showAttributes" type="button" mat-icon-button>
|
||||
<mat-icon *ngIf="showAttributes">keyboard_arrow_up</mat-icon>
|
||||
<mat-icon *ngIf="!showAttributes">keyboard_arrow_down</mat-icon>
|
||||
</button>
|
||||
|
||||
<span *ngIf="!provider?.config?.ldap?.attributes?.idAttribute" class="state error">{{
|
||||
'IDP.REQUIRED' | translate
|
||||
}}</span>
|
||||
</div>
|
||||
<div *ngIf="showAttributes">
|
||||
<cnsl-ldap-attributes
|
||||
[initialAttributes]="provider?.config?.ldap?.attributes"
|
||||
(attributesChanged)="attributes = $event"
|
||||
></cnsl-ldap-attributes>
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-optional-h-wrapper">
|
||||
<h2>{{ 'IDP.OPTIONAL' | translate }}</h2>
|
||||
<button (click)="showOptional = !showOptional" type="button" mat-icon-button>
|
||||
<mat-icon *ngIf="showOptional">keyboard_arrow_up</mat-icon
|
||||
><mat-icon *ngIf="!showOptional">keyboard_arrow_down</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="showOptional">
|
||||
<mat-checkbox formControlName="startTls">{{ 'IDP.STARTTLS' | translate }}</mat-checkbox>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.TIMEOUT' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="timeout" type="number" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-provider-options
|
||||
[initialOptions]="provider?.config?.options"
|
||||
(optionsChanged)="options = $event"
|
||||
></cnsl-provider-options>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="(form.invalid && attributes.toObject().idAttribute !== '') || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</cnsl-create-layout>
|
@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ProviderLDAPComponent } from './provider-ldap.component';
|
||||
|
||||
describe('ProviderLDAPComponent', () => {
|
||||
let component: ProviderLDAPComponent;
|
||||
let fixture: ComponentFixture<ProviderLDAPComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ProviderLDAPComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProviderLDAPComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,264 @@
|
||||
import { Location } from '@angular/common';
|
||||
import { Component, Injector, Type } from '@angular/core';
|
||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
||||
import { take } from 'rxjs';
|
||||
import {
|
||||
AddLDAPProviderRequest as AdminAddLDAPProviderRequest,
|
||||
GetProviderByIDRequest as AdminGetProviderByIDRequest,
|
||||
UpdateLDAPProviderRequest as AdminUpdateLDAPProviderRequest,
|
||||
} from 'src/app/proto/generated/zitadel/admin_pb';
|
||||
import { LDAPAttributes, Options, Provider } from 'src/app/proto/generated/zitadel/idp_pb';
|
||||
import {
|
||||
AddLDAPProviderRequest as MgmtAddLDAPProviderRequest,
|
||||
GetProviderByIDRequest as MgmtGetProviderByIDRequest,
|
||||
UpdateLDAPProviderRequest as MgmtUpdateLDAPProviderRequest,
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
|
||||
import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-provider-ldap',
|
||||
templateUrl: './provider-ldap.component.html',
|
||||
})
|
||||
export class ProviderLDAPComponent {
|
||||
public updateBindPassword: boolean = false;
|
||||
public showAttributes: boolean = false;
|
||||
public showOptional: boolean = false;
|
||||
public options: Options = new Options().setIsCreationAllowed(true).setIsLinkingAllowed(true);
|
||||
public attributes: LDAPAttributes = new LDAPAttributes();
|
||||
public id: string | null = '';
|
||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||
private service!: ManagementService | AdminService;
|
||||
|
||||
public form!: FormGroup;
|
||||
|
||||
public loading: boolean = false;
|
||||
|
||||
public provider?: Provider.AsObject;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
private _location: Location,
|
||||
private breadcrumbService: BreadcrumbService,
|
||||
) {
|
||||
this.form = new FormGroup({
|
||||
name: new FormControl('', [requiredValidator]),
|
||||
serversList: new FormControl('', [requiredValidator]),
|
||||
baseDn: new FormControl('', [requiredValidator]),
|
||||
bindDn: new FormControl('', [requiredValidator]),
|
||||
bindPassword: new FormControl('', [requiredValidator]),
|
||||
userBase: new FormControl('', [requiredValidator]),
|
||||
userFiltersList: new FormControl('', [requiredValidator]),
|
||||
userObjectClassesList: new FormControl('', [requiredValidator]),
|
||||
timeout: new FormControl<number>(0),
|
||||
startTls: new FormControl(false),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
|
||||
const bread: Breadcrumb = {
|
||||
type: BreadcrumbType.ORG,
|
||||
routerLink: ['/org'],
|
||||
};
|
||||
|
||||
this.breadcrumbService.setBreadcrumb([bread]);
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
|
||||
const iamBread = new Breadcrumb({
|
||||
type: BreadcrumbType.ORG,
|
||||
name: 'Instance',
|
||||
routerLink: ['/instance'],
|
||||
});
|
||||
this.breadcrumbService.setBreadcrumb([iamBread]);
|
||||
break;
|
||||
}
|
||||
|
||||
this.id = this.route.snapshot.paramMap.get('id');
|
||||
if (this.id) {
|
||||
this.getData(this.id);
|
||||
this.bindPassword?.setValidators([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getData(id: string): void {
|
||||
const req =
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? new AdminGetProviderByIDRequest()
|
||||
: new MgmtGetProviderByIDRequest();
|
||||
req.setId(id);
|
||||
this.service
|
||||
.getProviderByID(req)
|
||||
.then((resp) => {
|
||||
this.provider = resp.idp;
|
||||
this.loading = false;
|
||||
if (this.provider?.config?.ldap) {
|
||||
this.form.patchValue(this.provider.config.ldap);
|
||||
this.name?.setValue(this.provider.name);
|
||||
this.timeout?.setValue(this.provider.config.ldap.timeout?.seconds);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
public submitForm(): void {
|
||||
this.provider ? this.updateLDAPProvider() : this.addLDAPProvider();
|
||||
}
|
||||
|
||||
public addLDAPProvider(): void {
|
||||
const req =
|
||||
this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? new MgmtAddLDAPProviderRequest()
|
||||
: new AdminAddLDAPProviderRequest();
|
||||
|
||||
req.setName(this.name?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
req.setAttributes(this.attributes);
|
||||
|
||||
req.setBaseDn(this.baseDn?.value);
|
||||
req.setBindDn(this.bindDn?.value);
|
||||
req.setBindPassword(this.bindPassword?.value);
|
||||
req.setServersList(this.serversList?.value); // list
|
||||
req.setStartTls(this.startTls?.value);
|
||||
req.setTimeout(new Duration().setSeconds(this.timeout?.value ?? 0));
|
||||
req.setUserBase(this.userBase?.value);
|
||||
req.setUserFiltersList(this.userFiltersList?.value); // list
|
||||
req.setUserObjectClassesList(this.userObjectClassesList?.value); // list
|
||||
|
||||
this.loading = true;
|
||||
(this.service as ManagementService)
|
||||
.addLDAPProvider(req)
|
||||
.then((idp) => {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.close();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
public updateLDAPProvider(): void {
|
||||
if (this.provider) {
|
||||
const req =
|
||||
this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? new MgmtUpdateLDAPProviderRequest()
|
||||
: new AdminUpdateLDAPProviderRequest();
|
||||
req.setId(this.provider.id);
|
||||
req.setName(this.name?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
|
||||
req.setAttributes(this.attributes);
|
||||
|
||||
req.setBaseDn(this.baseDn?.value);
|
||||
req.setBindDn(this.bindDn?.value);
|
||||
if (this.updateBindPassword) {
|
||||
req.setBindPassword(this.bindPassword?.value);
|
||||
}
|
||||
req.setServersList(this.serversList?.value);
|
||||
req.setStartTls(this.startTls?.value);
|
||||
req.setTimeout(new Duration().setSeconds(this.timeout?.value ?? 0));
|
||||
req.setUserBase(this.userBase?.value);
|
||||
req.setUserFiltersList(this.userFiltersList?.value);
|
||||
req.setUserObjectClassesList(this.userObjectClassesList?.value);
|
||||
|
||||
this.loading = true;
|
||||
(this.service as ManagementService)
|
||||
.updateLDAPProvider(req)
|
||||
.then((idp) => {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.close();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this._location.back();
|
||||
}
|
||||
|
||||
public get name(): AbstractControl | null {
|
||||
return this.form.get('name');
|
||||
}
|
||||
|
||||
public get baseDn(): AbstractControl | null {
|
||||
return this.form.get('baseDn');
|
||||
}
|
||||
|
||||
public get bindDn(): AbstractControl | null {
|
||||
return this.form.get('bindDn');
|
||||
}
|
||||
|
||||
public get bindPassword(): AbstractControl | null {
|
||||
return this.form.get('bindPassword');
|
||||
}
|
||||
|
||||
public get serversList(): AbstractControl | null {
|
||||
return this.form.get('serversList');
|
||||
}
|
||||
|
||||
public get startTls(): AbstractControl | null {
|
||||
return this.form.get('startTls');
|
||||
}
|
||||
|
||||
public get timeout(): AbstractControl | null {
|
||||
return this.form.get('timeout');
|
||||
}
|
||||
|
||||
public get userBase(): AbstractControl | null {
|
||||
return this.form.get('userBase');
|
||||
}
|
||||
|
||||
public get userFiltersList(): AbstractControl | null {
|
||||
return this.form.get('userFiltersList');
|
||||
}
|
||||
|
||||
public get userObjectClassesList(): AbstractControl | null {
|
||||
return this.form.get('userObjectClassesList');
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProviderOAuthComponent } from './provider-oauth.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderOAuthComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderOAuthRoutingModule {}
|
@ -101,7 +101,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -3,7 +3,7 @@ import { Location } from '@angular/common';
|
||||
import { Component, Injector, Type } from '@angular/core';
|
||||
import { AbstractControl, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { take } from 'rxjs';
|
||||
import {
|
||||
AddGenericOAuthProviderRequest as AdminAddGenericOAuthProviderRequest,
|
||||
@ -18,6 +18,7 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { requiredValidator } from '../../form-field/validators/validators';
|
||||
@ -44,7 +45,7 @@ export class ProviderOAuthComponent {
|
||||
public provider?: Provider.AsObject;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private authService: GrpcAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
@ -62,6 +63,23 @@ export class ProviderOAuthComponent {
|
||||
scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []),
|
||||
});
|
||||
|
||||
this.authService
|
||||
.isAllowed(
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN
|
||||
? ['iam.idp.write']
|
||||
: this.serviceType === PolicyComponentServiceType.MGMT
|
||||
? ['org.idp.write']
|
||||
: [],
|
||||
)
|
||||
.pipe(take(1))
|
||||
.subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.form.enable();
|
||||
} else {
|
||||
this.form.disable();
|
||||
}
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe((data) => {
|
||||
this.serviceType = data.serviceType;
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderOAuthRoutingModule } from './provider-oauth-routing.module';
|
||||
import { ProviderOAuthComponent } from './provider-oauth.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderOAuthComponent],
|
||||
imports: [
|
||||
ProviderOAuthRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderOAuthModule {}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProviderOIDCComponent } from './provider-oidc.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ProviderOIDCComponent,
|
||||
data: { animation: 'DetailPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProviderOIDCRoutingModule {}
|
@ -11,7 +11,7 @@
|
||||
|
||||
<p class="identity-provider-desc cnsl-secondary-text">{{ 'IDP.CREATE.OIDC.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<form [formGroup]="oidcFormGroup" (ngSubmit)="submitForm()">
|
||||
<form [formGroup]="form" (ngSubmit)="submitForm()">
|
||||
<div class="identity-provider-content">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||
@ -86,7 +86,13 @@
|
||||
</div>
|
||||
|
||||
<div class="identity-provider-create-actions">
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="oidcFormGroup.invalid" type="submit">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
[disabled]="form.invalid || form.disabled"
|
||||
type="submit"
|
||||
>
|
||||
<span *ngIf="id">{{ 'ACTIONS.SAVE' | translate }}</span>
|
||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -37,7 +37,7 @@ export class ProviderOIDCComponent {
|
||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||
private service!: ManagementService | AdminService;
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
public oidcFormGroup!: UntypedFormGroup;
|
||||
public form!: UntypedFormGroup;
|
||||
|
||||
public loading: boolean = false;
|
||||
|
||||
@ -50,7 +50,7 @@ export class ProviderOIDCComponent {
|
||||
private _location: Location,
|
||||
breadcrumbService: BreadcrumbService,
|
||||
) {
|
||||
this.oidcFormGroup = new UntypedFormGroup({
|
||||
this.form = new UntypedFormGroup({
|
||||
name: new UntypedFormControl('', [requiredValidator]),
|
||||
clientId: new UntypedFormControl('', [requiredValidator]),
|
||||
clientSecret: new UntypedFormControl('', [requiredValidator]),
|
||||
@ -105,7 +105,7 @@ export class ProviderOIDCComponent {
|
||||
this.provider = resp.idp;
|
||||
this.loading = false;
|
||||
if (this.provider?.config?.oidc) {
|
||||
this.oidcFormGroup.patchValue(this.provider.config.oidc);
|
||||
this.form.patchValue(this.provider.config.oidc);
|
||||
this.name?.setValue(this.provider.name);
|
||||
}
|
||||
})
|
||||
@ -204,22 +204,22 @@ export class ProviderOIDCComponent {
|
||||
}
|
||||
|
||||
public get name(): AbstractControl | null {
|
||||
return this.oidcFormGroup.get('name');
|
||||
return this.form.get('name');
|
||||
}
|
||||
|
||||
public get clientId(): AbstractControl | null {
|
||||
return this.oidcFormGroup.get('clientId');
|
||||
return this.form.get('clientId');
|
||||
}
|
||||
|
||||
public get clientSecret(): AbstractControl | null {
|
||||
return this.oidcFormGroup.get('clientSecret');
|
||||
return this.form.get('clientSecret');
|
||||
}
|
||||
|
||||
public get issuer(): AbstractControl | null {
|
||||
return this.oidcFormGroup.get('issuer');
|
||||
return this.form.get('issuer');
|
||||
}
|
||||
|
||||
public get scopesList(): AbstractControl | null {
|
||||
return this.oidcFormGroup.get('scopesList');
|
||||
return this.form.get('scopesList');
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../../card/card.module';
|
||||
import { CreateLayoutModule } from '../../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../../provider-options/provider-options.module';
|
||||
import { ProviderOIDCRoutingModule } from './provider-oidc-routing.module';
|
||||
import { ProviderOIDCComponent } from './provider-oidc.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProviderOIDCComponent],
|
||||
imports: [
|
||||
ProviderOIDCRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProviderOIDCModule {}
|
@ -0,0 +1,52 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProviderType } from 'src/app/proto/generated/zitadel/idp_pb';
|
||||
import { ProviderAzureADComponent } from './provider-azure-ad/provider-azure-ad.component';
|
||||
import { ProviderGithubESComponent } from './provider-github-es/provider-github-es.component';
|
||||
import { ProviderGithubComponent } from './provider-github/provider-github.component';
|
||||
import { ProviderGitlabSelfHostedComponent } from './provider-gitlab-self-hosted/provider-gitlab-self-hosted.component';
|
||||
import { ProviderGitlabComponent } from './provider-gitlab/provider-gitlab.component';
|
||||
import { ProviderGoogleComponent } from './provider-google/provider-google.component';
|
||||
import { ProviderJWTComponent } from './provider-jwt/provider-jwt.component';
|
||||
import { ProviderLDAPComponent } from './provider-ldap/provider-ldap.component';
|
||||
import { ProviderOAuthComponent } from './provider-oauth/provider-oauth.component';
|
||||
import { ProviderOIDCComponent } from './provider-oidc/provider-oidc.component';
|
||||
|
||||
const typeMap = {
|
||||
[ProviderType.PROVIDER_TYPE_AZURE_AD]: { path: 'azure', component: ProviderAzureADComponent },
|
||||
[ProviderType.PROVIDER_TYPE_GITHUB]: { path: 'github', component: ProviderGithubComponent },
|
||||
[ProviderType.PROVIDER_TYPE_GITHUB_ES]: { path: 'github-es', component: ProviderGithubESComponent },
|
||||
[ProviderType.PROVIDER_TYPE_GITLAB]: { path: 'gitlab', component: ProviderGitlabComponent },
|
||||
[ProviderType.PROVIDER_TYPE_GITLAB_SELF_HOSTED]: {
|
||||
path: 'gitlab-self-hosted',
|
||||
component: ProviderGitlabSelfHostedComponent,
|
||||
},
|
||||
[ProviderType.PROVIDER_TYPE_GOOGLE]: { path: 'google', component: ProviderGoogleComponent },
|
||||
[ProviderType.PROVIDER_TYPE_JWT]: { path: 'jwt', component: ProviderJWTComponent },
|
||||
[ProviderType.PROVIDER_TYPE_OAUTH]: { path: 'oauth', component: ProviderOAuthComponent },
|
||||
[ProviderType.PROVIDER_TYPE_OIDC]: { path: 'oidc', component: ProviderOIDCComponent },
|
||||
[ProviderType.PROVIDER_TYPE_LDAP]: { path: 'ldap', component: ProviderLDAPComponent },
|
||||
};
|
||||
|
||||
const routes: Routes = Object.entries(typeMap).map(([key, value]) => {
|
||||
return {
|
||||
path: value.path,
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
component: value.component,
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: value.component,
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ProvidersRoutingModule {}
|
68
console/src/app/modules/providers/providers.module.ts
Normal file
68
console/src/app/modules/providers/providers.module.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
|
||||
import { MatLegacyChipsModule as MatChipsModule } from '@angular/material/legacy-chips';
|
||||
import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
|
||||
import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select';
|
||||
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
|
||||
import { CardModule } from '../card/card.module';
|
||||
import { CreateLayoutModule } from '../create-layout/create-layout.module';
|
||||
import { InfoSectionModule } from '../info-section/info-section.module';
|
||||
import { ProviderOptionsModule } from '../provider-options/provider-options.module';
|
||||
import { StringListModule } from '../string-list/string-list.module';
|
||||
import { LDAPAttributesComponent } from './ldap-attributes/ldap-attributes.component';
|
||||
import { ProviderAzureADComponent } from './provider-azure-ad/provider-azure-ad.component';
|
||||
import { ProviderGithubESComponent } from './provider-github-es/provider-github-es.component';
|
||||
import { ProviderGithubComponent } from './provider-github/provider-github.component';
|
||||
import { ProviderGitlabSelfHostedComponent } from './provider-gitlab-self-hosted/provider-gitlab-self-hosted.component';
|
||||
import { ProviderGitlabComponent } from './provider-gitlab/provider-gitlab.component';
|
||||
import { ProviderGoogleComponent } from './provider-google/provider-google.component';
|
||||
import { ProviderJWTComponent } from './provider-jwt/provider-jwt.component';
|
||||
import { ProviderLDAPComponent } from './provider-ldap/provider-ldap.component';
|
||||
import { ProviderOAuthComponent } from './provider-oauth/provider-oauth.component';
|
||||
import { ProviderOIDCComponent } from './provider-oidc/provider-oidc.component';
|
||||
import { ProvidersRoutingModule } from './providers-routing.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ProviderGoogleComponent,
|
||||
ProviderGithubComponent,
|
||||
ProviderGithubESComponent,
|
||||
ProviderAzureADComponent,
|
||||
LDAPAttributesComponent,
|
||||
ProviderGitlabSelfHostedComponent,
|
||||
ProviderGitlabComponent,
|
||||
ProviderGithubESComponent,
|
||||
ProviderJWTComponent,
|
||||
ProviderOIDCComponent,
|
||||
ProviderOAuthComponent,
|
||||
ProviderLDAPComponent,
|
||||
],
|
||||
imports: [
|
||||
ProvidersRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CreateLayoutModule,
|
||||
StringListModule,
|
||||
InfoSectionModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSelectModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
CardModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
ProviderOptionsModule,
|
||||
MatLegacyProgressSpinnerModule,
|
||||
],
|
||||
})
|
||||
export default class ProvidersModule {}
|
@ -25,6 +25,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.idp-icon {
|
||||
font-size: 36px;
|
||||
margin-right: 1rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 1rem 0 0;
|
||||
}
|
||||
@ -54,6 +60,20 @@
|
||||
}
|
||||
|
||||
.identity-provider-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.subheader {
|
||||
margin: 2rem 0 0.5rem 0;
|
||||
}
|
||||
|
||||
.identity-provider-2-col {
|
||||
max-width: 400px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
column-gap: 1rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
@ -93,7 +113,7 @@
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
margin-right: 0.25rem;
|
||||
margin: 1rem 0.25rem 1rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
<form class="string-list-form" (ngSubmit)="add(redInput)">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ title }}</cnsl-label>
|
||||
<input #redInput cnslInput [formControl]="control" />
|
||||
</cnsl-form-field>
|
||||
<button
|
||||
matTooltip="{{ 'ACTIONS.ADD' | translate }}"
|
||||
type="submit"
|
||||
mat-icon-button
|
||||
[disabled]="control.invalid || control.disabled"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="string-list">
|
||||
<div *ngFor="let str of value" class="value-line">
|
||||
<span>{{ str }}</span>
|
||||
<span class="fill-space"></span>
|
||||
<button
|
||||
type="button"
|
||||
matTooltip="{{ 'ACTIONS.DELETE' | translate }}"
|
||||
mat-icon-button
|
||||
(click)="remove(str)"
|
||||
class="icon-button"
|
||||
>
|
||||
<mat-icon class="icon">cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,60 @@
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
@mixin string-list-theme($theme) {
|
||||
$foreground: map-get($theme, foreground);
|
||||
$background: map-get($theme, background);
|
||||
$is-dark-theme: map-get($theme, is-dark);
|
||||
$warn: map-get($theme, warn);
|
||||
$warn-color: map-get($warn, 500);
|
||||
$button-text-color: map-get($foreground, text);
|
||||
$button-disabled-text-color: map-get($foreground, disabled-button);
|
||||
$divider-color: map-get($foreground, dividers);
|
||||
$secondary-text: map-get($foreground, secondary-text);
|
||||
|
||||
.string-list {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
|
||||
.value-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0.5rem 0;
|
||||
padding: 0 0 0 0.75rem;
|
||||
border-radius: 4px;
|
||||
background: map-get($background, infosection);
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
|
||||
.icon {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
&:not(:hover) {
|
||||
color: $secondary-text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.string-list-form {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
min-width: 320px;
|
||||
|
||||
.formfield {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-bottom: 0.9rem;
|
||||
margin-right: -0.5rem;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StringListComponent } from './string-list.component';
|
||||
|
||||
describe('StringListComponent', () => {
|
||||
let component: StringListComponent;
|
||||
let fixture: ComponentFixture<StringListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [StringListComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(StringListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
100
console/src/app/modules/string-list/string-list.component.ts
Normal file
100
console/src/app/modules/string-list/string-list.component.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { Component, forwardRef, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { Observable, Subject, takeUntil } from 'rxjs';
|
||||
import { requiredValidator } from '../form-field/validators/validators';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-string-list',
|
||||
templateUrl: './string-list.component.html',
|
||||
styleUrls: ['./string-list.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => StringListComponent),
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class StringListComponent implements ControlValueAccessor, OnInit, OnDestroy {
|
||||
@Input() title: string = '';
|
||||
@Input() required: boolean = false;
|
||||
@Input() public getValues: Observable<void> = new Observable(); // adds formfieldinput to array on emission
|
||||
|
||||
@Input() public control: FormControl = new FormControl<string>({ value: '', disabled: true });
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
@ViewChild('redInput') input!: any;
|
||||
private val: string[] = [];
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getValues.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
||||
this.add(this.input.nativeElement);
|
||||
});
|
||||
|
||||
this.required ? this.control.setValidators([requiredValidator]) : this.control.setValidators([]);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
onChange: any = () => {};
|
||||
onTouch: any = () => {};
|
||||
|
||||
set value(val: string[]) {
|
||||
if (val !== undefined && this.val !== val) {
|
||||
this.val = val;
|
||||
this.onChange(val);
|
||||
this.onTouch(val);
|
||||
}
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.val;
|
||||
}
|
||||
|
||||
writeValue(value: string[]) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
registerOnChange(fn: any) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any) {
|
||||
this.onTouch = fn;
|
||||
}
|
||||
|
||||
public setDisabledState(isDisabled: boolean): void {
|
||||
if (isDisabled) {
|
||||
this.control.disable();
|
||||
} else {
|
||||
this.control.enable();
|
||||
}
|
||||
}
|
||||
|
||||
public add(input: any): void {
|
||||
if (this.control.valid) {
|
||||
const trimmed = input.value.trim();
|
||||
if (trimmed) {
|
||||
this.val ? this.val.push(input.value) : (this.val = [input.value]);
|
||||
this.onChange(this.val);
|
||||
this.onTouch(this.val);
|
||||
}
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(str: string): void {
|
||||
const index = this.value.indexOf(str);
|
||||
|
||||
if (index >= 0) {
|
||||
this.value.splice(index, 1);
|
||||
this.onChange(this.value);
|
||||
this.onTouch(this.value);
|
||||
}
|
||||
}
|
||||
}
|
25
console/src/app/modules/string-list/string-list.module.ts
Normal file
25
console/src/app/modules/string-list/string-list.module.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatLegacyButtonModule } from '@angular/material/legacy-button';
|
||||
import { MatLegacyTooltipModule } from '@angular/material/legacy-tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { InputModule } from '../input/input.module';
|
||||
import { StringListComponent } from './string-list.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [StringListComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
InputModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
MatIconModule,
|
||||
MatLegacyTooltipModule,
|
||||
MatLegacyButtonModule,
|
||||
],
|
||||
exports: [StringListComponent],
|
||||
})
|
||||
export class StringListModule {}
|
@ -26,131 +26,11 @@ const routes: Routes = [
|
||||
{
|
||||
path: 'provider',
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
loadChildren: () => import('src/app/modules/providers/providers.module'),
|
||||
data: {
|
||||
roles: ['iam.idp.write'],
|
||||
roles: ['iam.idp.read'],
|
||||
serviceType: PolicyComponentServiceType.ADMIN,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'azure-ad',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-azure-ad/provider-azure-ad.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-azure-ad/provider-azure-ad.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'oidc',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oidc/provider-oidc.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oidc/provider-oidc.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'oauth',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oauth/provider-oauth.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oauth/provider-oauth.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'github-es',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github-es/provider-github-es.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github-es/provider-github-es.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'jwt',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-jwt/provider-jwt.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-jwt/provider-jwt.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'google',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-google/provider-google.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-google/provider-google.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'gitlab',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-gitlab/provider-gitlab.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-gitlab/provider-gitlab.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'gitlab-self-hosted',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () =>
|
||||
import('src/app/modules/providers/provider-gitlab-self-hosted/provider-gitlab-self-hosted.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () =>
|
||||
import('src/app/modules/providers/provider-gitlab-self-hosted/provider-gitlab-self-hosted.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'github',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -14,131 +14,11 @@ const routes: Routes = [
|
||||
{
|
||||
path: 'provider',
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
loadChildren: () => import('src/app/modules/providers/providers.module'),
|
||||
data: {
|
||||
roles: ['org.idp.write'],
|
||||
roles: ['org.idp.read'],
|
||||
serviceType: PolicyComponentServiceType.MGMT,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'oauth',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oauth/provider-oauth.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oauth/provider-oauth.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'oidc',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oidc/provider-oidc.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-oidc/provider-oidc.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'github-es',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github-es/provider-github-es.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github-es/provider-github-es.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'jwt',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-jwt/provider-jwt.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-jwt/provider-jwt.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'google',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-google/provider-google.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-google/provider-google.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'gitlab',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-gitlab/provider-gitlab.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-gitlab/provider-gitlab.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'gitlab-self-hosted',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () =>
|
||||
import('src/app/modules/providers/provider-gitlab-self-hosted/provider-gitlab-self-hosted.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () =>
|
||||
import('src/app/modules/providers/provider-gitlab-self-hosted/provider-gitlab-self-hosted.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'github',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-github/provider-github.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'azure-ad',
|
||||
children: [
|
||||
{
|
||||
path: 'create',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-azure-ad/provider-azure-ad.module'),
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
loadChildren: () => import('src/app/modules/providers/provider-azure-ad/provider-azure-ad.module'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
|
@ -110,10 +110,9 @@
|
||||
|
||||
<cnsl-redirect-uris
|
||||
class="redirect-section"
|
||||
[canWrite]="true"
|
||||
[disabled]="false"
|
||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||
(changedUris)="oidcAppRequest.setRedirectUrisList($any($event))"
|
||||
[urisList]="oidcAppRequest.toObject().redirectUrisList"
|
||||
[(ngModel)]="redirectUris"
|
||||
[getValues]="requestRedirectValuesSubject$"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||
data-e2e="redirect-uris"
|
||||
@ -139,11 +138,10 @@
|
||||
|
||||
<cnsl-redirect-uris
|
||||
class="redirect-section"
|
||||
[canWrite]="true"
|
||||
(changedUris)="oidcAppRequest.setPostLogoutRedirectUrisList($any($event))"
|
||||
[urisList]="oidcAppRequest.toObject().postLogoutRedirectUrisList"
|
||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||
[disabled]="false"
|
||||
[(ngModel)]="postLogoutUrisList"
|
||||
[getValues]="requestRedirectValuesSubject$"
|
||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||
data-e2e="postlogout-uris"
|
||||
>
|
||||
@ -431,20 +429,18 @@
|
||||
<div class="formfield full-width">
|
||||
<cnsl-redirect-uris
|
||||
class="redirect-section"
|
||||
[canWrite]="true"
|
||||
(changedUris)="oidcAppRequest.setRedirectUrisList($any($event))"
|
||||
[urisList]="oidcAppRequest.toObject().redirectUrisList"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||
[disabled]="false"
|
||||
[(ngModel)]="redirectUris"
|
||||
[getValues]="requestRedirectValuesSubject$"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||
>
|
||||
</cnsl-redirect-uris>
|
||||
|
||||
<cnsl-redirect-uris
|
||||
class="redirect-section"
|
||||
[canWrite]="true"
|
||||
(changedUris)="oidcAppRequest.setPostLogoutRedirectUrisList($any($event))"
|
||||
[urisList]="oidcAppRequest.toObject().postLogoutRedirectUrisList"
|
||||
[disabled]="false"
|
||||
[(ngModel)]="postLogoutUrisList"
|
||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||
[getValues]="requestRedirectValuesSubject$"
|
||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||
|
@ -221,6 +221,22 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
public get redirectUris() {
|
||||
return this.oidcAppRequest.toObject().redirectUrisList;
|
||||
}
|
||||
|
||||
public set redirectUris(value: string[]) {
|
||||
this.oidcAppRequest.setRedirectUrisList(value);
|
||||
}
|
||||
|
||||
public get postLogoutUrisList() {
|
||||
return this.oidcAppRequest.toObject().postLogoutRedirectUrisList;
|
||||
}
|
||||
|
||||
public set postLogoutUrisList(value: string[]) {
|
||||
this.oidcAppRequest.setPostLogoutRedirectUrisList(value);
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.subscription = this.route.params.subscribe((params) => this.getData(params));
|
||||
|
||||
|
@ -334,11 +334,9 @@
|
||||
<cnsl-redirect-uris
|
||||
*ngIf="appType?.value !== undefined"
|
||||
class="redirect-section"
|
||||
[canWrite]="canWrite"
|
||||
[disabled]="!canWrite"
|
||||
[devMode]="devMode?.value"
|
||||
[getValues]="requestRedirectValuesSubject$"
|
||||
(changedUris)="redirectUrisList = $any($event)"
|
||||
[urisList]="redirectUrisList"
|
||||
[(ngModel)]="redirectUrisList"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||
>
|
||||
@ -347,11 +345,9 @@
|
||||
<cnsl-redirect-uris
|
||||
*ngIf="appType?.value !== undefined"
|
||||
class="redirect-section"
|
||||
[canWrite]="canWrite"
|
||||
[disabled]="!canWrite"
|
||||
[devMode]="devMode?.value"
|
||||
(changedUris)="postLogoutRedirectUrisList = $any($event)"
|
||||
[urisList]="postLogoutRedirectUrisList"
|
||||
[getValues]="requestRedirectValuesSubject$"
|
||||
[(ngModel)]="postLogoutRedirectUrisList"
|
||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||
>
|
||||
|
@ -268,12 +268,6 @@
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.error {
|
||||
font-size: 13px;
|
||||
color: var(--warn);
|
||||
margin: 0 0.5rem 1.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
@ -8,14 +8,14 @@
|
||||
matTooltip="{{ 'ACTIONS.ADD' | translate }}"
|
||||
type="submit"
|
||||
mat-icon-button
|
||||
[disabled]="redirectControl.invalid || !canWrite"
|
||||
[disabled]="redirectControl.invalid || redirectControl.disabled"
|
||||
>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="redirect-uris-list">
|
||||
<div *ngFor="let uri of urisList" class="uri-line" [ngClass]="{ alert: !devMode && !(uri | redirect : isNative) }">
|
||||
<div *ngFor="let uri of value" class="uri-line" [ngClass]="{ alert: !devMode && !(uri | redirect : isNative) }">
|
||||
<span
|
||||
class="uri"
|
||||
[ngClass]="{ green: !devMode && uri?.startsWith('https://'), red: !devMode && !uri?.startsWith('https://') }"
|
||||
@ -29,7 +29,13 @@
|
||||
"
|
||||
></i>
|
||||
|
||||
<button matTooltip="{{ 'ACTIONS.DELETE' | translate }}" mat-icon-button (click)="remove(uri)" class="icon-button">
|
||||
<button
|
||||
type="button"
|
||||
matTooltip="{{ 'ACTIONS.DELETE' | translate }}"
|
||||
mat-icon-button
|
||||
(click)="remove(uri)"
|
||||
class="icon-button"
|
||||
>
|
||||
<mat-icon class="icon">cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,44 +1,83 @@
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Component, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { Observable, Subject, takeUntil } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-redirect-uris',
|
||||
templateUrl: './redirect-uris.component.html',
|
||||
styleUrls: ['./redirect-uris.component.scss'],
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => RedirectUrisComponent),
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class RedirectUrisComponent implements OnInit, OnDestroy {
|
||||
export class RedirectUrisComponent implements ControlValueAccessor, OnInit, OnDestroy {
|
||||
@Input() title: string = '';
|
||||
@Input() devMode: boolean = false;
|
||||
@Input() canWrite: boolean = false;
|
||||
@Input() isNative!: boolean;
|
||||
@Input() public urisList: string[] = [];
|
||||
@Input() public redirectControl: UntypedFormControl = new UntypedFormControl({ value: '', disabled: true });
|
||||
@Output() public changedUris: EventEmitter<string[]> = new EventEmitter();
|
||||
@Input() public getValues: Observable<void> = new Observable();
|
||||
@Input() public getValues: Observable<void> = new Observable(); // adds formfieldinput to array on emission
|
||||
|
||||
public redirectControl: FormControl = new FormControl<string>({ value: '', disabled: true });
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
@ViewChild('redInput') input!: any;
|
||||
private sub: Subscription = new Subscription();
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.canWrite) {
|
||||
this.redirectControl.enable();
|
||||
}
|
||||
|
||||
this.sub = this.getValues.subscribe(() => {
|
||||
this.getValues.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
||||
this.add(this.input.nativeElement);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.sub.unsubscribe();
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
onChange: any = () => {};
|
||||
onTouch: any = () => {};
|
||||
|
||||
private val: string[] = [];
|
||||
|
||||
set value(val: string[]) {
|
||||
if (val !== undefined && this.val !== val) {
|
||||
this.val = val;
|
||||
this.onChange(val);
|
||||
this.onTouch(val);
|
||||
}
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.val;
|
||||
}
|
||||
|
||||
writeValue(value: string[]) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
registerOnChange(fn: any) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any) {
|
||||
this.onTouch = fn;
|
||||
}
|
||||
|
||||
public setDisabledState(isDisabled: boolean): void {
|
||||
if (isDisabled) {
|
||||
this.redirectControl.disable();
|
||||
} else {
|
||||
this.redirectControl.enable();
|
||||
}
|
||||
}
|
||||
|
||||
public add(input: any): void {
|
||||
if (this.redirectControl.valid) {
|
||||
if (input.value !== '' && input.value !== ' ' && input.value !== '/') {
|
||||
this.urisList.push(input.value);
|
||||
this.val.push(input.value);
|
||||
this.onChange(this.val);
|
||||
this.onTouch(this.val);
|
||||
}
|
||||
if (input) {
|
||||
input.value = '';
|
||||
@ -47,10 +86,12 @@ export class RedirectUrisComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public remove(redirect: any): void {
|
||||
const index = this.urisList.indexOf(redirect);
|
||||
const index = this.value.indexOf(redirect);
|
||||
|
||||
if (index >= 0) {
|
||||
this.urisList.splice(index, 1);
|
||||
this.value.splice(index, 1);
|
||||
this.onChange(this.value);
|
||||
this.onTouch(this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ import {
|
||||
AddIDPToLoginPolicyResponse,
|
||||
AddJWTProviderRequest,
|
||||
AddJWTProviderResponse,
|
||||
AddLDAPProviderRequest,
|
||||
AddLDAPProviderResponse,
|
||||
AddMultiFactorToLoginPolicyRequest,
|
||||
AddMultiFactorToLoginPolicyResponse,
|
||||
AddNotificationPolicyRequest,
|
||||
@ -226,6 +228,8 @@ import {
|
||||
UpdateJWTProviderResponse,
|
||||
UpdateLabelPolicyRequest,
|
||||
UpdateLabelPolicyResponse,
|
||||
UpdateLDAPProviderRequest,
|
||||
UpdateLDAPProviderResponse,
|
||||
UpdateLockoutPolicyRequest,
|
||||
UpdateLockoutPolicyResponse,
|
||||
UpdateLoginPolicyRequest,
|
||||
@ -926,6 +930,14 @@ export class AdminService {
|
||||
return this.grpcService.admin.updateGoogleProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public addLDAPProvider(req: AddLDAPProviderRequest): Promise<AddLDAPProviderResponse.AsObject> {
|
||||
return this.grpcService.admin.addLDAPProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public updateLDAPProvider(req: UpdateLDAPProviderRequest): Promise<UpdateLDAPProviderResponse.AsObject> {
|
||||
return this.grpcService.admin.updateLDAPProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public addGitLabProvider(req: AddGitLabProviderRequest): Promise<AddGitLabProviderResponse.AsObject> {
|
||||
return this.grpcService.admin.addGitLabProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ import {
|
||||
AddIDPToLoginPolicyResponse,
|
||||
AddJWTProviderRequest,
|
||||
AddJWTProviderResponse,
|
||||
AddLDAPProviderRequest,
|
||||
AddLDAPProviderResponse,
|
||||
AddMachineKeyRequest,
|
||||
AddMachineKeyResponse,
|
||||
AddMachineUserRequest,
|
||||
@ -461,6 +463,8 @@ import {
|
||||
UpdateHumanProfileResponse,
|
||||
UpdateJWTProviderRequest,
|
||||
UpdateJWTProviderResponse,
|
||||
UpdateLDAPProviderRequest,
|
||||
UpdateLDAPProviderResponse,
|
||||
UpdateMachineRequest,
|
||||
UpdateMachineResponse,
|
||||
UpdateOIDCAppConfigRequest,
|
||||
@ -885,6 +889,14 @@ export class ManagementService {
|
||||
return this.grpcService.mgmt.updateGoogleProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public addLDAPProvider(req: AddLDAPProviderRequest): Promise<AddLDAPProviderResponse.AsObject> {
|
||||
return this.grpcService.mgmt.addLDAPProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public updateLDAPProvider(req: UpdateLDAPProviderRequest): Promise<UpdateLDAPProviderResponse.AsObject> {
|
||||
return this.grpcService.mgmt.updateLDAPProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public addGitLabProvider(req: AddGitLabProviderRequest): Promise<AddGitLabProviderResponse.AsObject> {
|
||||
return this.grpcService.mgmt.addGitLabProvider(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
@ -1648,6 +1648,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Microsoft Provider",
|
||||
"DESCRIPTION": "Geben Sie die erforderlichen Daten für Ihren Microsoft-Identitätsprovider ein."
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "Active Directory / LDAP",
|
||||
"DESCRIPTION": "Geben Sie die erforderlichen Daten für Ihren LDAP Provider ein."
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1690,6 +1694,8 @@
|
||||
"EMAILVERIFIED": "Email verifiziert",
|
||||
"NAMEHINT": "Wenn angegeben, wir er im Login interface angezeigt.",
|
||||
"OPTIONAL": "optional",
|
||||
"LDAPATTRIBUTES": "LDAP Attribute",
|
||||
"UPDATEBINDPASSWORD": "Bind Password updaten",
|
||||
"UPDATECLIENTSECRET": "Client Secret updaten",
|
||||
"ADD": "Identity Provider hinzufügen",
|
||||
"TYPE": "Typ",
|
||||
@ -1711,6 +1717,31 @@
|
||||
"SCOPESLIST": "Scopes List",
|
||||
"CLIENTID": "Client ID",
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"LDAPCONNECTION": "Verbindung",
|
||||
"LDAPUSERBINDING": "User binding",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in Sekunden",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "erfolderlich",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "IDP Anzeigename Mapping",
|
||||
"USERNAMEMAPPING": "Username Mapping",
|
||||
"DATES": "Datum",
|
||||
|
@ -1653,6 +1653,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Microsoft Provider",
|
||||
"DESCRIPTION": "Enter the credentials for your Microsoft Identity Provider"
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "Active Directory / LDAP",
|
||||
"DESCRIPTION": "Enter the credentials for your LDAP Provider"
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1690,6 +1694,8 @@
|
||||
"EMAILVERIFIED": "Email verified",
|
||||
"NAMEHINT": "If specified it will be shown in the login interface.",
|
||||
"OPTIONAL": "optional",
|
||||
"LDAPATTRIBUTES": "LDAP Attributes",
|
||||
"UPDATEBINDPASSWORD": "update Bind Password",
|
||||
"UPDATECLIENTSECRET": "update client secret",
|
||||
"ADD": "Add Identity Provider",
|
||||
"TYPE": "Type",
|
||||
@ -1711,6 +1717,31 @@
|
||||
"SCOPESLIST": "Scopes List",
|
||||
"CLIENTID": "Client ID",
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"LDAPCONNECTION": "Connection",
|
||||
"LDAPUSERBINDING": "User binding",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in seconds",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "required",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "IDP Display Name Mapping",
|
||||
"USERNAMEMAPPING": "Username Mapping",
|
||||
"DATES": "Dates",
|
||||
|
@ -1652,6 +1652,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Fournisseur Microsoft",
|
||||
"DESCRIPTION": "Saisissez les informations d'identification de votre fournisseur d'identité Microsoft"
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "Active Directory / LDAP",
|
||||
"DESCRIPTION": "Saisissez les informations d'identification de votre fournisseur d'identité LDAP"
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1694,6 +1698,8 @@
|
||||
"EMAILVERIFIED": "Courriel vérifié",
|
||||
"NAMEHINT": "Si elle est spécifiée, elle sera affichée dans l'interface de connexion.",
|
||||
"OPTIONAL": "optionnel",
|
||||
"LDAPATTRIBUTES": "Attributs LDAP",
|
||||
"UPDATEBINDPASSWORD": "mettre à jour le mot de bind password",
|
||||
"UPDATECLIENTSECRET": "mise à jour du secret client",
|
||||
"ADD": "Ajouter un fournisseur d'identité",
|
||||
"TYPE": "Type",
|
||||
@ -1715,6 +1721,31 @@
|
||||
"SCOPESLIST": "Liste des champs d'application",
|
||||
"CLIENTID": "ID du client",
|
||||
"CLIENTSECRET": "Secret du client",
|
||||
"LDAPCONNECTION": "Connexion",
|
||||
"LDAPUSERBINDING": "Enchères utilisateur",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in seconds",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "requis",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "Mappage de IDP nom d'affichage",
|
||||
"USERNAMEMAPPING": "Mappage des noms d'utilisateur",
|
||||
"DATES": "Dates",
|
||||
|
@ -1653,6 +1653,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Microsoft Provider",
|
||||
"DESCRIPTION": "Inserisci i dati necessari per il tuo Microsoft provider."
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "Active Directory / LDAP",
|
||||
"DESCRIPTION": "Inserisci i dati necessari per il tuo provider LDAP."
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1695,6 +1699,8 @@
|
||||
"EMAILVERIFIED": "Email verificata",
|
||||
"NAMEHINT": "Se specificato, verrà mostrato nell'interfaccia di accesso.",
|
||||
"OPTIONAL": "opzionale",
|
||||
"LDAPATTRIBUTES": "Attributi LDAP",
|
||||
"UPDATEBINDPASSWORD": "aggiorna Bind Password",
|
||||
"UPDATECLIENTSECRET": "Aggiorna secret",
|
||||
"ADD": "Aggiungi Identity Provider",
|
||||
"TYPE": "Tipo",
|
||||
@ -1716,6 +1722,31 @@
|
||||
"SCOPESLIST": "Scope list",
|
||||
"CLIENTID": "Client ID",
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"LDAPCONNECTION": "Connessione",
|
||||
"LDAPUSERBINDING": "User binding",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in seconds",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "necessario",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "Mapping del nome di visualizzazione IDP",
|
||||
"USERNAMEMAPPING": "Mapping del nome utente",
|
||||
"DATES": "Date",
|
||||
|
@ -1653,6 +1653,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Microsoftプロバイダー",
|
||||
"DESCRIPTION": "Microsoftプロバイダーのクレデンシャルを入力してください。"
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "LDAPプロバイダー",
|
||||
"DESCRIPTION": "LDAPプロバイダーのクレデンシャルを入力してください。"
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1690,6 +1694,8 @@
|
||||
"EMAILVERIFIED": "検証済みメールアドレス",
|
||||
"NAMEHINT": "指定されている場合、ログイン画面に表示されます。",
|
||||
"OPTIONAL": "オプション",
|
||||
"LDAPATTRIBUTES": "LDAP 属性",
|
||||
"UPDATEBINDPASSWORD": "バインドパスワードの更新",
|
||||
"UPDATECLIENTSECRET": "クライアントシークレットを更新する",
|
||||
"ADD": "IDプロバイダーを追加する",
|
||||
"TYPE": "タイプ",
|
||||
@ -1711,6 +1717,31 @@
|
||||
"SCOPESLIST": "スコープリスト",
|
||||
"CLIENTID": "クライアントID",
|
||||
"CLIENTSECRET": "クライアントシークレット",
|
||||
"LDAPCONNECTION": "繋がり",
|
||||
"LDAPUSERBINDING": "ユーザーバインディング",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in seconds",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "必要",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "IDP表示名マッピング",
|
||||
"USERNAMEMAPPING": "ユーザー名マッピング",
|
||||
"DATES": "日付",
|
||||
|
@ -1652,6 +1652,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Microsoft Provider",
|
||||
"DESCRIPTION": "Wprowadź dane dla swojego dostawcy tożsamości Microsoft"
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "LDAP Provider",
|
||||
"DESCRIPTION": "Wprowadź dane dla swojego dostawcy tożsamości LDAP"
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1694,6 +1698,8 @@
|
||||
"EMAILVERIFIED": "Email zweryfikowany",
|
||||
"NAMEHINT": "Jeśli zostanie podany, będzie widoczny w interfejsie logowania.",
|
||||
"OPTIONAL": "opcjonalnie",
|
||||
"LDAPATTRIBUTES": "LDAP Atrybuty",
|
||||
"UPDATEBINDPASSWORD": "aktualizacja bind password",
|
||||
"UPDATECLIENTSECRET": "aktualizacja tajemnicy klienta",
|
||||
"ADD": "Dodaj dostawcę tożsamości",
|
||||
"TYPE": "Typ",
|
||||
@ -1715,6 +1721,31 @@
|
||||
"SCOPESLIST": "Lista zakresów",
|
||||
"CLIENTID": "Identyfikator klienta",
|
||||
"CLIENTSECRET": "Tajne klienta",
|
||||
"LDAPCONNECTION": "Połączenie",
|
||||
"LDAPUSERBINDING": "Wiązanie użytkownika",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in seconds",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "wymagany",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "Mapowanie wyświetlanej nazwy IDP",
|
||||
"USERNAMEMAPPING": "Mapowanie nazwy użytkownika",
|
||||
"DATES": "Daty",
|
||||
|
@ -1651,6 +1651,10 @@
|
||||
"AZUREAD": {
|
||||
"TITLE": "Microsoft 身份提供者",
|
||||
"DESCRIPTION": "输入您的 Microsoft 身份提供商的凭据"
|
||||
},
|
||||
"LDAP": {
|
||||
"TITLE": "LDAP 身份提供者",
|
||||
"DESCRIPTION": "输入您的 LDAP 身份提供商的凭据"
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
@ -1693,6 +1697,8 @@
|
||||
"EMAILVERIFIED": "电子邮件已验证",
|
||||
"NAMEHINT": "如果指定,它将显示在登录界面。",
|
||||
"OPTIONAL": "可选",
|
||||
"LDAPATTRIBUTES": "LDAP 属性",
|
||||
"UPDATEBINDPASSWORD": "更新绑定密码",
|
||||
"UPDATECLIENTSECRET": "更新客户秘密",
|
||||
"ADD": "添加身份提供者",
|
||||
"TYPE": "类型",
|
||||
@ -1714,6 +1720,31 @@
|
||||
"SCOPESLIST": "Scopes List",
|
||||
"CLIENTID": "Client ID",
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"LDAPCONNECTION": "联系",
|
||||
"LDAPUSERBINDING": "用户绑定",
|
||||
"BASEDN": "BaseDn",
|
||||
"BINDDN": "BindDn",
|
||||
"BINDPASSWORD": "Bind Password",
|
||||
"SERVERS": "Servers",
|
||||
"STARTTLS": "Start TLS",
|
||||
"TIMEOUT": "Timeout in seconds",
|
||||
"USERBASE": "Userbase",
|
||||
"USERFILTERS": "User filters",
|
||||
"USEROBJECTCLASSES": "User Object Classes",
|
||||
"REQUIRED": "必需的",
|
||||
"LDAPIDATTRIBUTE": "ID attribute",
|
||||
"AVATARURLATTRIBUTE": "Avatar Url attribute",
|
||||
"DISPLAYNAMEATTRIBUTE": "Displayname attribute",
|
||||
"EMAILATTRIBUTEATTRIBUTE": "Email attribute",
|
||||
"EMAILVERIFIEDATTRIBUTE": "Email verified attribute",
|
||||
"FIRSTNAMEATTRIBUTE": "Firstname attribute",
|
||||
"LASTNAMEATTRIBUTE": "Lastname attribute",
|
||||
"NICKNAMEATTRIBUTE": "Nickname attribute",
|
||||
"PHONEATTRIBUTE": "Phone attribute",
|
||||
"PHONEVERIFIEDATTRIBUTE": "Phone verified attribute",
|
||||
"PREFERREDLANGUAGEATTRIBUTE": "Preferred language attribute",
|
||||
"PREFERREDUSERNAMEATTRIBUTE": "Preferred username attribute",
|
||||
"PROFILEATTRIBUTE": "Profile attribute",
|
||||
"IDPDISPLAYNAMMAPPING": "IDP 展示名称映射",
|
||||
"USERNAMEMAPPING": "用户名映射",
|
||||
"DATES": "日期",
|
||||
|
@ -42,6 +42,7 @@
|
||||
@import 'src/app/modules/refresh-table/refresh-table.component.scss';
|
||||
@import 'src/app/modules/form-field/field/form-field.component.scss';
|
||||
@import 'src/app/modules/label/label.component.scss';
|
||||
@import 'src/app/modules/string-list/string-list.component.scss';
|
||||
@import 'src/app/modules/meta-layout/meta.scss';
|
||||
@import 'src/app/pages/projects/owned-projects/project-grant-detail/project-grant-illustration/project-grant-illustration.component';
|
||||
@import 'src/app/modules/accounts-card/accounts-card.component.scss';
|
||||
@ -99,6 +100,7 @@
|
||||
@include input-theme($theme);
|
||||
@include cnsl-form-field-theme($theme);
|
||||
@include contributors-theme($theme);
|
||||
@include string-list-theme($theme);
|
||||
@include shortcut-theme($theme);
|
||||
@include message-texts-theme($theme);
|
||||
@include app-detail-theme($theme);
|
||||
|
Loading…
x
Reference in New Issue
Block a user