mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-07 23:27: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" />
|
<img class="idp-logo light" src="./assets/images/idp/github.svg" alt="github" />
|
||||||
GitHub Enterprise Server
|
GitHub Enterprise Server
|
||||||
</div>
|
</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 class="idp-table-provider-type" *ngSwitchDefault>coming soon</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -162,6 +166,10 @@
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
actions
|
actions
|
||||||
|
*ngIf="
|
||||||
|
(serviceType === PolicyComponentServiceType.MGMT && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
||||||
|
(serviceType === PolicyComponentServiceType.ADMIN && idp.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM)
|
||||||
|
"
|
||||||
[disabled]="
|
[disabled]="
|
||||||
(serviceType === PolicyComponentServiceType.MGMT && idp?.providerType === IDPOwnerType.IDP_OWNER_TYPE_ORG) ||
|
(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];
|
return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'google', row.id];
|
||||||
case ProviderType.PROVIDER_TYPE_GITLAB:
|
case ProviderType.PROVIDER_TYPE_GITLAB:
|
||||||
return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'gitlab', row.id];
|
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:
|
case ProviderType.PROVIDER_TYPE_GITLAB_SELF_HOSTED:
|
||||||
return [
|
return [
|
||||||
row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org',
|
row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org',
|
||||||
|
@ -161,4 +161,22 @@
|
|||||||
<span class="title">Generic JWT</span>
|
<span class="title">Generic JWT</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</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>
|
</div>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
*ngIf="(getCustomInitMessageTextMap$ | async) && (getCustomInitMessageTextMap$ | async)?.isDefault === false"
|
*ngIf="(getCustomInitMessageTextMap$ | async) && (getCustomInitMessageTextMap$ | async)?.isDefault === false"
|
||||||
[disabled]="(canWrite$ | async) === false"
|
[disabled]="(canWrite$ | async) === false"
|
||||||
(click)="resetDefault()"
|
(click)="resetDefault()"
|
||||||
color="warn"
|
color="message-text-warn"
|
||||||
type="submit"
|
type="submit"
|
||||||
mat-stroked-button
|
mat-stroked-button
|
||||||
>
|
>
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.warn {
|
.message-text-warn {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
display: block;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -3,7 +3,7 @@ import { Location } from '@angular/common';
|
|||||||
import { Component, Injector, Type } from '@angular/core';
|
import { Component, Injector, Type } from '@angular/core';
|
||||||
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
|
||||||
import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips';
|
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 { take } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
AddAzureADProviderRequest as AdminAddAzureADProviderRequest,
|
AddAzureADProviderRequest as AdminAddAzureADProviderRequest,
|
||||||
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -50,7 +51,7 @@ export class ProviderAzureADComponent {
|
|||||||
];
|
];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -67,6 +68,23 @@ export class ProviderAzureADComponent {
|
|||||||
emailVerified: new FormControl(false),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -44,6 +45,7 @@ export class ProviderGithubESComponent {
|
|||||||
public provider?: Provider.AsObject;
|
public provider?: Provider.AsObject;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -60,6 +62,23 @@ export class ProviderGithubESComponent {
|
|||||||
scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -45,6 +46,7 @@ export class ProviderGithubComponent {
|
|||||||
public updateClientSecret: boolean = false;
|
public updateClientSecret: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -58,6 +60,23 @@ export class ProviderGithubComponent {
|
|||||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -45,6 +46,7 @@ export class ProviderGitlabSelfHostedComponent {
|
|||||||
public updateClientSecret: boolean = false;
|
public updateClientSecret: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -59,6 +61,23 @@ export class ProviderGitlabSelfHostedComponent {
|
|||||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -45,6 +46,7 @@ export class ProviderGitlabComponent {
|
|||||||
public updateClientSecret: boolean = false;
|
public updateClientSecret: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -58,6 +60,23 @@ export class ProviderGitlabComponent {
|
|||||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -45,6 +46,7 @@ export class ProviderGoogleComponent {
|
|||||||
public updateClientSecret: boolean = false;
|
public updateClientSecret: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -58,6 +60,23 @@ export class ProviderGoogleComponent {
|
|||||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -42,6 +43,7 @@ export class ProviderJWTComponent {
|
|||||||
public provider?: Provider.AsObject;
|
public provider?: Provider.AsObject;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -87,6 +89,23 @@ export class ProviderJWTComponent {
|
|||||||
jwtEndpoint: new UntypedFormControl('', [requiredValidator]),
|
jwtEndpoint: new UntypedFormControl('', [requiredValidator]),
|
||||||
keysEndpoint: 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 {
|
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>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -3,7 +3,7 @@ import { Location } from '@angular/common';
|
|||||||
import { Component, Injector, Type } from '@angular/core';
|
import { Component, Injector, Type } from '@angular/core';
|
||||||
import { AbstractControl, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
import { AbstractControl, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips';
|
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 { take } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
AddGenericOAuthProviderRequest as AdminAddGenericOAuthProviderRequest,
|
AddGenericOAuthProviderRequest as AdminAddGenericOAuthProviderRequest,
|
||||||
@ -18,6 +18,7 @@ import {
|
|||||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.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 { ManagementService } from 'src/app/services/mgmt.service';
|
||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
import { requiredValidator } from '../../form-field/validators/validators';
|
import { requiredValidator } from '../../form-field/validators/validators';
|
||||||
@ -44,7 +45,7 @@ export class ProviderOAuthComponent {
|
|||||||
public provider?: Provider.AsObject;
|
public provider?: Provider.AsObject;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private authService: GrpcAuthService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -62,6 +63,23 @@ export class ProviderOAuthComponent {
|
|||||||
scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []),
|
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.route.data.pipe(take(1)).subscribe((data) => {
|
||||||
this.serviceType = data.serviceType;
|
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>
|
<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">
|
<div class="identity-provider-content">
|
||||||
<cnsl-form-field class="formfield">
|
<cnsl-form-field class="formfield">
|
||||||
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
<cnsl-label>{{ 'IDP.NAME' | translate }}</cnsl-label>
|
||||||
@ -86,7 +86,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="identity-provider-create-actions">
|
<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.SAVE' | translate }}</span>
|
||||||
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
<span *ngIf="!id">{{ 'ACTIONS.CREATE' | translate }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -37,7 +37,7 @@ export class ProviderOIDCComponent {
|
|||||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||||
private service!: ManagementService | AdminService;
|
private service!: ManagementService | AdminService;
|
||||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||||
public oidcFormGroup!: UntypedFormGroup;
|
public form!: UntypedFormGroup;
|
||||||
|
|
||||||
public loading: boolean = false;
|
public loading: boolean = false;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ export class ProviderOIDCComponent {
|
|||||||
private _location: Location,
|
private _location: Location,
|
||||||
breadcrumbService: BreadcrumbService,
|
breadcrumbService: BreadcrumbService,
|
||||||
) {
|
) {
|
||||||
this.oidcFormGroup = new UntypedFormGroup({
|
this.form = new UntypedFormGroup({
|
||||||
name: new UntypedFormControl('', [requiredValidator]),
|
name: new UntypedFormControl('', [requiredValidator]),
|
||||||
clientId: new UntypedFormControl('', [requiredValidator]),
|
clientId: new UntypedFormControl('', [requiredValidator]),
|
||||||
clientSecret: new UntypedFormControl('', [requiredValidator]),
|
clientSecret: new UntypedFormControl('', [requiredValidator]),
|
||||||
@ -105,7 +105,7 @@ export class ProviderOIDCComponent {
|
|||||||
this.provider = resp.idp;
|
this.provider = resp.idp;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (this.provider?.config?.oidc) {
|
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);
|
this.name?.setValue(this.provider.name);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -204,22 +204,22 @@ export class ProviderOIDCComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get name(): AbstractControl | null {
|
public get name(): AbstractControl | null {
|
||||||
return this.oidcFormGroup.get('name');
|
return this.form.get('name');
|
||||||
}
|
}
|
||||||
|
|
||||||
public get clientId(): AbstractControl | null {
|
public get clientId(): AbstractControl | null {
|
||||||
return this.oidcFormGroup.get('clientId');
|
return this.form.get('clientId');
|
||||||
}
|
}
|
||||||
|
|
||||||
public get clientSecret(): AbstractControl | null {
|
public get clientSecret(): AbstractControl | null {
|
||||||
return this.oidcFormGroup.get('clientSecret');
|
return this.form.get('clientSecret');
|
||||||
}
|
}
|
||||||
|
|
||||||
public get issuer(): AbstractControl | null {
|
public get issuer(): AbstractControl | null {
|
||||||
return this.oidcFormGroup.get('issuer');
|
return this.form.get('issuer');
|
||||||
}
|
}
|
||||||
|
|
||||||
public get scopesList(): AbstractControl | null {
|
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 {
|
h1 {
|
||||||
margin: 0 1rem 0 0;
|
margin: 0 1rem 0 0;
|
||||||
}
|
}
|
||||||
@ -54,6 +60,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.identity-provider-content {
|
.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 {
|
.desc {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
@ -93,7 +113,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
h2 {
|
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',
|
path: 'provider',
|
||||||
canActivate: [AuthGuard, RoleGuard],
|
canActivate: [AuthGuard, RoleGuard],
|
||||||
|
loadChildren: () => import('src/app/modules/providers/providers.module'),
|
||||||
data: {
|
data: {
|
||||||
roles: ['iam.idp.write'],
|
roles: ['iam.idp.read'],
|
||||||
serviceType: PolicyComponentServiceType.ADMIN,
|
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',
|
path: 'provider',
|
||||||
canActivate: [AuthGuard, RoleGuard],
|
canActivate: [AuthGuard, RoleGuard],
|
||||||
|
loadChildren: () => import('src/app/modules/providers/providers.module'),
|
||||||
data: {
|
data: {
|
||||||
roles: ['org.idp.write'],
|
roles: ['org.idp.read'],
|
||||||
serviceType: PolicyComponentServiceType.MGMT,
|
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: '',
|
path: '',
|
||||||
|
@ -110,10 +110,9 @@
|
|||||||
|
|
||||||
<cnsl-redirect-uris
|
<cnsl-redirect-uris
|
||||||
class="redirect-section"
|
class="redirect-section"
|
||||||
[canWrite]="true"
|
[disabled]="false"
|
||||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||||
(changedUris)="oidcAppRequest.setRedirectUrisList($any($event))"
|
[(ngModel)]="redirectUris"
|
||||||
[urisList]="oidcAppRequest.toObject().redirectUrisList"
|
|
||||||
[getValues]="requestRedirectValuesSubject$"
|
[getValues]="requestRedirectValuesSubject$"
|
||||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||||
data-e2e="redirect-uris"
|
data-e2e="redirect-uris"
|
||||||
@ -139,11 +138,10 @@
|
|||||||
|
|
||||||
<cnsl-redirect-uris
|
<cnsl-redirect-uris
|
||||||
class="redirect-section"
|
class="redirect-section"
|
||||||
[canWrite]="true"
|
[disabled]="false"
|
||||||
(changedUris)="oidcAppRequest.setPostLogoutRedirectUrisList($any($event))"
|
[(ngModel)]="postLogoutUrisList"
|
||||||
[urisList]="oidcAppRequest.toObject().postLogoutRedirectUrisList"
|
|
||||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
|
||||||
[getValues]="requestRedirectValuesSubject$"
|
[getValues]="requestRedirectValuesSubject$"
|
||||||
|
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||||
data-e2e="postlogout-uris"
|
data-e2e="postlogout-uris"
|
||||||
>
|
>
|
||||||
@ -431,20 +429,18 @@
|
|||||||
<div class="formfield full-width">
|
<div class="formfield full-width">
|
||||||
<cnsl-redirect-uris
|
<cnsl-redirect-uris
|
||||||
class="redirect-section"
|
class="redirect-section"
|
||||||
[canWrite]="true"
|
[disabled]="false"
|
||||||
(changedUris)="oidcAppRequest.setRedirectUrisList($any($event))"
|
[(ngModel)]="redirectUris"
|
||||||
[urisList]="oidcAppRequest.toObject().redirectUrisList"
|
|
||||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
|
||||||
[getValues]="requestRedirectValuesSubject$"
|
[getValues]="requestRedirectValuesSubject$"
|
||||||
|
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||||
>
|
>
|
||||||
</cnsl-redirect-uris>
|
</cnsl-redirect-uris>
|
||||||
|
|
||||||
<cnsl-redirect-uris
|
<cnsl-redirect-uris
|
||||||
class="redirect-section"
|
class="redirect-section"
|
||||||
[canWrite]="true"
|
[disabled]="false"
|
||||||
(changedUris)="oidcAppRequest.setPostLogoutRedirectUrisList($any($event))"
|
[(ngModel)]="postLogoutUrisList"
|
||||||
[urisList]="oidcAppRequest.toObject().postLogoutRedirectUrisList"
|
|
||||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||||
[getValues]="requestRedirectValuesSubject$"
|
[getValues]="requestRedirectValuesSubject$"
|
||||||
[isNative]="appType?.value.oidcAppType === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
[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 {
|
public ngOnInit(): void {
|
||||||
this.subscription = this.route.params.subscribe((params) => this.getData(params));
|
this.subscription = this.route.params.subscribe((params) => this.getData(params));
|
||||||
|
|
||||||
|
@ -334,11 +334,9 @@
|
|||||||
<cnsl-redirect-uris
|
<cnsl-redirect-uris
|
||||||
*ngIf="appType?.value !== undefined"
|
*ngIf="appType?.value !== undefined"
|
||||||
class="redirect-section"
|
class="redirect-section"
|
||||||
[canWrite]="canWrite"
|
[disabled]="!canWrite"
|
||||||
[devMode]="devMode?.value"
|
[devMode]="devMode?.value"
|
||||||
[getValues]="requestRedirectValuesSubject$"
|
[(ngModel)]="redirectUrisList"
|
||||||
(changedUris)="redirectUrisList = $any($event)"
|
|
||||||
[urisList]="redirectUrisList"
|
|
||||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
title="{{ 'APP.OIDC.REDIRECT' | translate }}"
|
||||||
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||||
>
|
>
|
||||||
@ -347,11 +345,9 @@
|
|||||||
<cnsl-redirect-uris
|
<cnsl-redirect-uris
|
||||||
*ngIf="appType?.value !== undefined"
|
*ngIf="appType?.value !== undefined"
|
||||||
class="redirect-section"
|
class="redirect-section"
|
||||||
[canWrite]="canWrite"
|
[disabled]="!canWrite"
|
||||||
[devMode]="devMode?.value"
|
[devMode]="devMode?.value"
|
||||||
(changedUris)="postLogoutRedirectUrisList = $any($event)"
|
[(ngModel)]="postLogoutRedirectUrisList"
|
||||||
[urisList]="postLogoutRedirectUrisList"
|
|
||||||
[getValues]="requestRedirectValuesSubject$"
|
|
||||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}"
|
||||||
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
[isNative]="appType?.value === OIDCAppType.OIDC_APP_TYPE_NATIVE"
|
||||||
>
|
>
|
||||||
|
@ -268,12 +268,6 @@
|
|||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--warn);
|
|
||||||
margin: 0 0.5rem 1.5rem 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-container {
|
.btn-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
matTooltip="{{ 'ACTIONS.ADD' | translate }}"
|
matTooltip="{{ 'ACTIONS.ADD' | translate }}"
|
||||||
type="submit"
|
type="submit"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
[disabled]="redirectControl.invalid || !canWrite"
|
[disabled]="redirectControl.invalid || redirectControl.disabled"
|
||||||
>
|
>
|
||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="redirect-uris-list">
|
<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
|
<span
|
||||||
class="uri"
|
class="uri"
|
||||||
[ngClass]="{ green: !devMode && uri?.startsWith('https://'), red: !devMode && !uri?.startsWith('https://') }"
|
[ngClass]="{ green: !devMode && uri?.startsWith('https://'), red: !devMode && !uri?.startsWith('https://') }"
|
||||||
@ -29,7 +29,13 @@
|
|||||||
"
|
"
|
||||||
></i>
|
></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>
|
<mat-icon class="icon">cancel</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,44 +1,83 @@
|
|||||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
|
import { Component, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { UntypedFormControl } from '@angular/forms';
|
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cnsl-redirect-uris',
|
selector: 'cnsl-redirect-uris',
|
||||||
templateUrl: './redirect-uris.component.html',
|
templateUrl: './redirect-uris.component.html',
|
||||||
styleUrls: ['./redirect-uris.component.scss'],
|
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() title: string = '';
|
||||||
@Input() devMode: boolean = false;
|
@Input() devMode: boolean = false;
|
||||||
@Input() canWrite: boolean = false;
|
|
||||||
@Input() isNative!: boolean;
|
@Input() isNative!: boolean;
|
||||||
@Input() public urisList: string[] = [];
|
@Input() public getValues: Observable<void> = new Observable(); // adds formfieldinput to array on emission
|
||||||
@Input() public redirectControl: UntypedFormControl = new UntypedFormControl({ value: '', disabled: true });
|
|
||||||
@Output() public changedUris: EventEmitter<string[]> = new EventEmitter();
|
|
||||||
@Input() public getValues: Observable<void> = new Observable();
|
|
||||||
|
|
||||||
|
public redirectControl: FormControl = new FormControl<string>({ value: '', disabled: true });
|
||||||
|
private destroy$: Subject<void> = new Subject();
|
||||||
@ViewChild('redInput') input!: any;
|
@ViewChild('redInput') input!: any;
|
||||||
private sub: Subscription = new Subscription();
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this.canWrite) {
|
this.getValues.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
||||||
this.redirectControl.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sub = this.getValues.subscribe(() => {
|
|
||||||
this.add(this.input.nativeElement);
|
this.add(this.input.nativeElement);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
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 {
|
public add(input: any): void {
|
||||||
if (this.redirectControl.valid) {
|
if (this.redirectControl.valid) {
|
||||||
if (input.value !== '' && input.value !== ' ' && input.value !== '/') {
|
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) {
|
if (input) {
|
||||||
input.value = '';
|
input.value = '';
|
||||||
@ -47,10 +86,12 @@ export class RedirectUrisComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public remove(redirect: any): void {
|
public remove(redirect: any): void {
|
||||||
const index = this.urisList.indexOf(redirect);
|
const index = this.value.indexOf(redirect);
|
||||||
|
|
||||||
if (index >= 0) {
|
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,
|
AddIDPToLoginPolicyResponse,
|
||||||
AddJWTProviderRequest,
|
AddJWTProviderRequest,
|
||||||
AddJWTProviderResponse,
|
AddJWTProviderResponse,
|
||||||
|
AddLDAPProviderRequest,
|
||||||
|
AddLDAPProviderResponse,
|
||||||
AddMultiFactorToLoginPolicyRequest,
|
AddMultiFactorToLoginPolicyRequest,
|
||||||
AddMultiFactorToLoginPolicyResponse,
|
AddMultiFactorToLoginPolicyResponse,
|
||||||
AddNotificationPolicyRequest,
|
AddNotificationPolicyRequest,
|
||||||
@ -226,6 +228,8 @@ import {
|
|||||||
UpdateJWTProviderResponse,
|
UpdateJWTProviderResponse,
|
||||||
UpdateLabelPolicyRequest,
|
UpdateLabelPolicyRequest,
|
||||||
UpdateLabelPolicyResponse,
|
UpdateLabelPolicyResponse,
|
||||||
|
UpdateLDAPProviderRequest,
|
||||||
|
UpdateLDAPProviderResponse,
|
||||||
UpdateLockoutPolicyRequest,
|
UpdateLockoutPolicyRequest,
|
||||||
UpdateLockoutPolicyResponse,
|
UpdateLockoutPolicyResponse,
|
||||||
UpdateLoginPolicyRequest,
|
UpdateLoginPolicyRequest,
|
||||||
@ -926,6 +930,14 @@ export class AdminService {
|
|||||||
return this.grpcService.admin.updateGoogleProvider(req, null).then((resp) => resp.toObject());
|
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> {
|
public addGitLabProvider(req: AddGitLabProviderRequest): Promise<AddGitLabProviderResponse.AsObject> {
|
||||||
return this.grpcService.admin.addGitLabProvider(req, null).then((resp) => resp.toObject());
|
return this.grpcService.admin.addGitLabProvider(req, null).then((resp) => resp.toObject());
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ import {
|
|||||||
AddIDPToLoginPolicyResponse,
|
AddIDPToLoginPolicyResponse,
|
||||||
AddJWTProviderRequest,
|
AddJWTProviderRequest,
|
||||||
AddJWTProviderResponse,
|
AddJWTProviderResponse,
|
||||||
|
AddLDAPProviderRequest,
|
||||||
|
AddLDAPProviderResponse,
|
||||||
AddMachineKeyRequest,
|
AddMachineKeyRequest,
|
||||||
AddMachineKeyResponse,
|
AddMachineKeyResponse,
|
||||||
AddMachineUserRequest,
|
AddMachineUserRequest,
|
||||||
@ -461,6 +463,8 @@ import {
|
|||||||
UpdateHumanProfileResponse,
|
UpdateHumanProfileResponse,
|
||||||
UpdateJWTProviderRequest,
|
UpdateJWTProviderRequest,
|
||||||
UpdateJWTProviderResponse,
|
UpdateJWTProviderResponse,
|
||||||
|
UpdateLDAPProviderRequest,
|
||||||
|
UpdateLDAPProviderResponse,
|
||||||
UpdateMachineRequest,
|
UpdateMachineRequest,
|
||||||
UpdateMachineResponse,
|
UpdateMachineResponse,
|
||||||
UpdateOIDCAppConfigRequest,
|
UpdateOIDCAppConfigRequest,
|
||||||
@ -885,6 +889,14 @@ export class ManagementService {
|
|||||||
return this.grpcService.mgmt.updateGoogleProvider(req, null).then((resp) => resp.toObject());
|
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> {
|
public addGitLabProvider(req: AddGitLabProviderRequest): Promise<AddGitLabProviderResponse.AsObject> {
|
||||||
return this.grpcService.mgmt.addGitLabProvider(req, null).then((resp) => resp.toObject());
|
return this.grpcService.mgmt.addGitLabProvider(req, null).then((resp) => resp.toObject());
|
||||||
}
|
}
|
||||||
|
@ -1648,6 +1648,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Microsoft Provider",
|
"TITLE": "Microsoft Provider",
|
||||||
"DESCRIPTION": "Geben Sie die erforderlichen Daten für Ihren Microsoft-Identitätsprovider ein."
|
"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": {
|
"DETAIL": {
|
||||||
@ -1690,6 +1694,8 @@
|
|||||||
"EMAILVERIFIED": "Email verifiziert",
|
"EMAILVERIFIED": "Email verifiziert",
|
||||||
"NAMEHINT": "Wenn angegeben, wir er im Login interface angezeigt.",
|
"NAMEHINT": "Wenn angegeben, wir er im Login interface angezeigt.",
|
||||||
"OPTIONAL": "optional",
|
"OPTIONAL": "optional",
|
||||||
|
"LDAPATTRIBUTES": "LDAP Attribute",
|
||||||
|
"UPDATEBINDPASSWORD": "Bind Password updaten",
|
||||||
"UPDATECLIENTSECRET": "Client Secret updaten",
|
"UPDATECLIENTSECRET": "Client Secret updaten",
|
||||||
"ADD": "Identity Provider hinzufügen",
|
"ADD": "Identity Provider hinzufügen",
|
||||||
"TYPE": "Typ",
|
"TYPE": "Typ",
|
||||||
@ -1711,6 +1717,31 @@
|
|||||||
"SCOPESLIST": "Scopes List",
|
"SCOPESLIST": "Scopes List",
|
||||||
"CLIENTID": "Client ID",
|
"CLIENTID": "Client ID",
|
||||||
"CLIENTSECRET": "Client Secret",
|
"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",
|
"IDPDISPLAYNAMMAPPING": "IDP Anzeigename Mapping",
|
||||||
"USERNAMEMAPPING": "Username Mapping",
|
"USERNAMEMAPPING": "Username Mapping",
|
||||||
"DATES": "Datum",
|
"DATES": "Datum",
|
||||||
|
@ -1653,6 +1653,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Microsoft Provider",
|
"TITLE": "Microsoft Provider",
|
||||||
"DESCRIPTION": "Enter the credentials for your Microsoft Identity Provider"
|
"DESCRIPTION": "Enter the credentials for your Microsoft Identity Provider"
|
||||||
|
},
|
||||||
|
"LDAP": {
|
||||||
|
"TITLE": "Active Directory / LDAP",
|
||||||
|
"DESCRIPTION": "Enter the credentials for your LDAP Provider"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DETAIL": {
|
"DETAIL": {
|
||||||
@ -1690,6 +1694,8 @@
|
|||||||
"EMAILVERIFIED": "Email verified",
|
"EMAILVERIFIED": "Email verified",
|
||||||
"NAMEHINT": "If specified it will be shown in the login interface.",
|
"NAMEHINT": "If specified it will be shown in the login interface.",
|
||||||
"OPTIONAL": "optional",
|
"OPTIONAL": "optional",
|
||||||
|
"LDAPATTRIBUTES": "LDAP Attributes",
|
||||||
|
"UPDATEBINDPASSWORD": "update Bind Password",
|
||||||
"UPDATECLIENTSECRET": "update client secret",
|
"UPDATECLIENTSECRET": "update client secret",
|
||||||
"ADD": "Add Identity Provider",
|
"ADD": "Add Identity Provider",
|
||||||
"TYPE": "Type",
|
"TYPE": "Type",
|
||||||
@ -1711,6 +1717,31 @@
|
|||||||
"SCOPESLIST": "Scopes List",
|
"SCOPESLIST": "Scopes List",
|
||||||
"CLIENTID": "Client ID",
|
"CLIENTID": "Client ID",
|
||||||
"CLIENTSECRET": "Client Secret",
|
"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",
|
"IDPDISPLAYNAMMAPPING": "IDP Display Name Mapping",
|
||||||
"USERNAMEMAPPING": "Username Mapping",
|
"USERNAMEMAPPING": "Username Mapping",
|
||||||
"DATES": "Dates",
|
"DATES": "Dates",
|
||||||
|
@ -1652,6 +1652,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Fournisseur Microsoft",
|
"TITLE": "Fournisseur Microsoft",
|
||||||
"DESCRIPTION": "Saisissez les informations d'identification de votre fournisseur d'identité 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": {
|
"DETAIL": {
|
||||||
@ -1694,6 +1698,8 @@
|
|||||||
"EMAILVERIFIED": "Courriel vérifié",
|
"EMAILVERIFIED": "Courriel vérifié",
|
||||||
"NAMEHINT": "Si elle est spécifiée, elle sera affichée dans l'interface de connexion.",
|
"NAMEHINT": "Si elle est spécifiée, elle sera affichée dans l'interface de connexion.",
|
||||||
"OPTIONAL": "optionnel",
|
"OPTIONAL": "optionnel",
|
||||||
|
"LDAPATTRIBUTES": "Attributs LDAP",
|
||||||
|
"UPDATEBINDPASSWORD": "mettre à jour le mot de bind password",
|
||||||
"UPDATECLIENTSECRET": "mise à jour du secret client",
|
"UPDATECLIENTSECRET": "mise à jour du secret client",
|
||||||
"ADD": "Ajouter un fournisseur d'identité",
|
"ADD": "Ajouter un fournisseur d'identité",
|
||||||
"TYPE": "Type",
|
"TYPE": "Type",
|
||||||
@ -1715,6 +1721,31 @@
|
|||||||
"SCOPESLIST": "Liste des champs d'application",
|
"SCOPESLIST": "Liste des champs d'application",
|
||||||
"CLIENTID": "ID du client",
|
"CLIENTID": "ID du client",
|
||||||
"CLIENTSECRET": "Secret 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",
|
"IDPDISPLAYNAMMAPPING": "Mappage de IDP nom d'affichage",
|
||||||
"USERNAMEMAPPING": "Mappage des noms d'utilisateur",
|
"USERNAMEMAPPING": "Mappage des noms d'utilisateur",
|
||||||
"DATES": "Dates",
|
"DATES": "Dates",
|
||||||
|
@ -1653,6 +1653,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Microsoft Provider",
|
"TITLE": "Microsoft Provider",
|
||||||
"DESCRIPTION": "Inserisci i dati necessari per il tuo 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": {
|
"DETAIL": {
|
||||||
@ -1695,6 +1699,8 @@
|
|||||||
"EMAILVERIFIED": "Email verificata",
|
"EMAILVERIFIED": "Email verificata",
|
||||||
"NAMEHINT": "Se specificato, verrà mostrato nell'interfaccia di accesso.",
|
"NAMEHINT": "Se specificato, verrà mostrato nell'interfaccia di accesso.",
|
||||||
"OPTIONAL": "opzionale",
|
"OPTIONAL": "opzionale",
|
||||||
|
"LDAPATTRIBUTES": "Attributi LDAP",
|
||||||
|
"UPDATEBINDPASSWORD": "aggiorna Bind Password",
|
||||||
"UPDATECLIENTSECRET": "Aggiorna secret",
|
"UPDATECLIENTSECRET": "Aggiorna secret",
|
||||||
"ADD": "Aggiungi Identity Provider",
|
"ADD": "Aggiungi Identity Provider",
|
||||||
"TYPE": "Tipo",
|
"TYPE": "Tipo",
|
||||||
@ -1716,6 +1722,31 @@
|
|||||||
"SCOPESLIST": "Scope list",
|
"SCOPESLIST": "Scope list",
|
||||||
"CLIENTID": "Client ID",
|
"CLIENTID": "Client ID",
|
||||||
"CLIENTSECRET": "Client Secret",
|
"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",
|
"IDPDISPLAYNAMMAPPING": "Mapping del nome di visualizzazione IDP",
|
||||||
"USERNAMEMAPPING": "Mapping del nome utente",
|
"USERNAMEMAPPING": "Mapping del nome utente",
|
||||||
"DATES": "Date",
|
"DATES": "Date",
|
||||||
|
@ -1653,6 +1653,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Microsoftプロバイダー",
|
"TITLE": "Microsoftプロバイダー",
|
||||||
"DESCRIPTION": "Microsoftプロバイダーのクレデンシャルを入力してください。"
|
"DESCRIPTION": "Microsoftプロバイダーのクレデンシャルを入力してください。"
|
||||||
|
},
|
||||||
|
"LDAP": {
|
||||||
|
"TITLE": "LDAPプロバイダー",
|
||||||
|
"DESCRIPTION": "LDAPプロバイダーのクレデンシャルを入力してください。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DETAIL": {
|
"DETAIL": {
|
||||||
@ -1690,6 +1694,8 @@
|
|||||||
"EMAILVERIFIED": "検証済みメールアドレス",
|
"EMAILVERIFIED": "検証済みメールアドレス",
|
||||||
"NAMEHINT": "指定されている場合、ログイン画面に表示されます。",
|
"NAMEHINT": "指定されている場合、ログイン画面に表示されます。",
|
||||||
"OPTIONAL": "オプション",
|
"OPTIONAL": "オプション",
|
||||||
|
"LDAPATTRIBUTES": "LDAP 属性",
|
||||||
|
"UPDATEBINDPASSWORD": "バインドパスワードの更新",
|
||||||
"UPDATECLIENTSECRET": "クライアントシークレットを更新する",
|
"UPDATECLIENTSECRET": "クライアントシークレットを更新する",
|
||||||
"ADD": "IDプロバイダーを追加する",
|
"ADD": "IDプロバイダーを追加する",
|
||||||
"TYPE": "タイプ",
|
"TYPE": "タイプ",
|
||||||
@ -1711,6 +1717,31 @@
|
|||||||
"SCOPESLIST": "スコープリスト",
|
"SCOPESLIST": "スコープリスト",
|
||||||
"CLIENTID": "クライアントID",
|
"CLIENTID": "クライアントID",
|
||||||
"CLIENTSECRET": "クライアントシークレット",
|
"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表示名マッピング",
|
"IDPDISPLAYNAMMAPPING": "IDP表示名マッピング",
|
||||||
"USERNAMEMAPPING": "ユーザー名マッピング",
|
"USERNAMEMAPPING": "ユーザー名マッピング",
|
||||||
"DATES": "日付",
|
"DATES": "日付",
|
||||||
|
@ -1652,6 +1652,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Microsoft Provider",
|
"TITLE": "Microsoft Provider",
|
||||||
"DESCRIPTION": "Wprowadź dane dla swojego dostawcy tożsamości Microsoft"
|
"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": {
|
"DETAIL": {
|
||||||
@ -1694,6 +1698,8 @@
|
|||||||
"EMAILVERIFIED": "Email zweryfikowany",
|
"EMAILVERIFIED": "Email zweryfikowany",
|
||||||
"NAMEHINT": "Jeśli zostanie podany, będzie widoczny w interfejsie logowania.",
|
"NAMEHINT": "Jeśli zostanie podany, będzie widoczny w interfejsie logowania.",
|
||||||
"OPTIONAL": "opcjonalnie",
|
"OPTIONAL": "opcjonalnie",
|
||||||
|
"LDAPATTRIBUTES": "LDAP Atrybuty",
|
||||||
|
"UPDATEBINDPASSWORD": "aktualizacja bind password",
|
||||||
"UPDATECLIENTSECRET": "aktualizacja tajemnicy klienta",
|
"UPDATECLIENTSECRET": "aktualizacja tajemnicy klienta",
|
||||||
"ADD": "Dodaj dostawcę tożsamości",
|
"ADD": "Dodaj dostawcę tożsamości",
|
||||||
"TYPE": "Typ",
|
"TYPE": "Typ",
|
||||||
@ -1715,6 +1721,31 @@
|
|||||||
"SCOPESLIST": "Lista zakresów",
|
"SCOPESLIST": "Lista zakresów",
|
||||||
"CLIENTID": "Identyfikator klienta",
|
"CLIENTID": "Identyfikator klienta",
|
||||||
"CLIENTSECRET": "Tajne 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",
|
"IDPDISPLAYNAMMAPPING": "Mapowanie wyświetlanej nazwy IDP",
|
||||||
"USERNAMEMAPPING": "Mapowanie nazwy użytkownika",
|
"USERNAMEMAPPING": "Mapowanie nazwy użytkownika",
|
||||||
"DATES": "Daty",
|
"DATES": "Daty",
|
||||||
|
@ -1651,6 +1651,10 @@
|
|||||||
"AZUREAD": {
|
"AZUREAD": {
|
||||||
"TITLE": "Microsoft 身份提供者",
|
"TITLE": "Microsoft 身份提供者",
|
||||||
"DESCRIPTION": "输入您的 Microsoft 身份提供商的凭据"
|
"DESCRIPTION": "输入您的 Microsoft 身份提供商的凭据"
|
||||||
|
},
|
||||||
|
"LDAP": {
|
||||||
|
"TITLE": "LDAP 身份提供者",
|
||||||
|
"DESCRIPTION": "输入您的 LDAP 身份提供商的凭据"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DETAIL": {
|
"DETAIL": {
|
||||||
@ -1693,6 +1697,8 @@
|
|||||||
"EMAILVERIFIED": "电子邮件已验证",
|
"EMAILVERIFIED": "电子邮件已验证",
|
||||||
"NAMEHINT": "如果指定,它将显示在登录界面。",
|
"NAMEHINT": "如果指定,它将显示在登录界面。",
|
||||||
"OPTIONAL": "可选",
|
"OPTIONAL": "可选",
|
||||||
|
"LDAPATTRIBUTES": "LDAP 属性",
|
||||||
|
"UPDATEBINDPASSWORD": "更新绑定密码",
|
||||||
"UPDATECLIENTSECRET": "更新客户秘密",
|
"UPDATECLIENTSECRET": "更新客户秘密",
|
||||||
"ADD": "添加身份提供者",
|
"ADD": "添加身份提供者",
|
||||||
"TYPE": "类型",
|
"TYPE": "类型",
|
||||||
@ -1714,6 +1720,31 @@
|
|||||||
"SCOPESLIST": "Scopes List",
|
"SCOPESLIST": "Scopes List",
|
||||||
"CLIENTID": "Client ID",
|
"CLIENTID": "Client ID",
|
||||||
"CLIENTSECRET": "Client Secret",
|
"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 展示名称映射",
|
"IDPDISPLAYNAMMAPPING": "IDP 展示名称映射",
|
||||||
"USERNAMEMAPPING": "用户名映射",
|
"USERNAMEMAPPING": "用户名映射",
|
||||||
"DATES": "日期",
|
"DATES": "日期",
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
@import 'src/app/modules/refresh-table/refresh-table.component.scss';
|
@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/form-field/field/form-field.component.scss';
|
||||||
@import 'src/app/modules/label/label.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/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/pages/projects/owned-projects/project-grant-detail/project-grant-illustration/project-grant-illustration.component';
|
||||||
@import 'src/app/modules/accounts-card/accounts-card.component.scss';
|
@import 'src/app/modules/accounts-card/accounts-card.component.scss';
|
||||||
@ -99,6 +100,7 @@
|
|||||||
@include input-theme($theme);
|
@include input-theme($theme);
|
||||||
@include cnsl-form-field-theme($theme);
|
@include cnsl-form-field-theme($theme);
|
||||||
@include contributors-theme($theme);
|
@include contributors-theme($theme);
|
||||||
|
@include string-list-theme($theme);
|
||||||
@include shortcut-theme($theme);
|
@include shortcut-theme($theme);
|
||||||
@include message-texts-theme($theme);
|
@include message-texts-theme($theme);
|
||||||
@include app-detail-theme($theme);
|
@include app-detail-theme($theme);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user