diff --git a/console/src/app/modules/idp-table/idp-table.component.html b/console/src/app/modules/idp-table/idp-table.component.html index 7ffdeeca57..79bfeb6a17 100644 --- a/console/src/app/modules/idp-table/idp-table.component.html +++ b/console/src/app/modules/idp-table/idp-table.component.html @@ -46,6 +46,10 @@ Generic OIDC +
+ + Generic OAuth +
Generic JWT diff --git a/console/src/app/modules/idp-table/idp-table.component.ts b/console/src/app/modules/idp-table/idp-table.component.ts index 5acf81ce2c..1449d57029 100644 --- a/console/src/app/modules/idp-table/idp-table.component.ts +++ b/console/src/app/modules/idp-table/idp-table.component.ts @@ -228,6 +228,8 @@ export class IdpTableComponent implements OnInit { switch (row.type) { case ProviderType.PROVIDER_TYPE_OIDC: return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'oidc', row.id]; + case ProviderType.PROVIDER_TYPE_OAUTH: + return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'oauth', row.id]; case ProviderType.PROVIDER_TYPE_JWT: return [row.owner === IDPOwnerType.IDP_OWNER_TYPE_SYSTEM ? '/instance' : '/org', 'provider', 'jwt', row.id]; case ProviderType.PROVIDER_TYPE_GOOGLE: diff --git a/console/src/app/modules/policies/idp-settings/idp-settings.component.html b/console/src/app/modules/policies/idp-settings/idp-settings.component.html index bff6b403ba..1b9f7f40b7 100644 --- a/console/src/app/modules/policies/idp-settings/idp-settings.component.html +++ b/console/src/app/modules/policies/idp-settings/idp-settings.component.html @@ -68,6 +68,23 @@
+ + + +
+ Generic OAuth +
+
+ +
+
+ + +

{{ 'IDP.CREATE.OAUTH.TITLE' | translate }}

+ +
+ +

{{ 'IDP.CREATE.OAUTH.DESCRIPTION' | translate }}

+ +
+ + {{ 'IDP.NAME' | translate }} + + + + + {{ 'IDP.AUTHORIZATIONENDPOINT' | translate }} + + + + + {{ 'IDP.TOKENENDPOINT' | translate }} + + + + + {{ 'IDP.USERENDPOINT' | translate }} + + + + + {{ 'IDP.IDATTRIBUTE' | translate }} + + + +
+ + {{ 'IDP.CLIENTID' | translate }} + + + + {{ + 'IDP.UPDATECLIENTSECRET' | translate + }} + + {{ 'IDP.CLIENTSECRET' | translate }} + + + +
+

{{ 'IDP.OPTIONAL' | translate }}

+ +
+
+
+
+ + {{ 'IDP.SCOPESLIST' | translate }} + + + + +
+ + + + + {{ scope }} cancel + + + +
+ + +
+
+ +
+ +
+
+
+ diff --git a/console/src/app/modules/providers/provider-oauth/provider-oauth.component.scss b/console/src/app/modules/providers/provider-oauth/provider-oauth.component.scss new file mode 100644 index 0000000000..7b9fadbb72 --- /dev/null +++ b/console/src/app/modules/providers/provider-oauth/provider-oauth.component.scss @@ -0,0 +1,84 @@ +.desc { + font-size: 14px; +} + +.oauth-create-content { + .title-row { + display: flex; + align-items: center; + + .idp-logo { + height: 36px; + width: 36px; + margin-right: 1rem; + flex-shrink: 0; + } + + h1 { + margin: 0 1rem 0 0; + } + } + + .formfield { + display: block; + max-width: 400px; + + .mat-chip-input { + width: 100%; + margin: 0; + } + + .chip { + border-radius: 0.5rem; + height: 40px; + } + + @media only screen and (max-width: 450px) { + max-width: none; + } + } + + .oauth-content { + .desc { + margin-bottom: 1rem; + } + + .idp-scopes { + padding-bottom: 0.5rem; + + .flex-line { + display: flex; + align-items: flex-start; + max-width: 400px; + + .formfield { + flex: 1; + } + + .scope-add-button { + margin-top: 1.75rem; + } + } + } + } +} + +.oauth-create-actions { + display: flex; + margin-top: 1rem; + + button[mat-raised-button] { + border-radius: 0.5rem; + margin-right: 1rem; + padding: 0.5rem 4rem; + } +} + +.optional-h-wrapper { + display: flex; + align-items: center; + + h2 { + margin-right: 0.25rem; + } +} diff --git a/console/src/app/modules/providers/provider-oauth/provider-oauth.component.spec.ts b/console/src/app/modules/providers/provider-oauth/provider-oauth.component.spec.ts new file mode 100644 index 0000000000..0086bf0ce3 --- /dev/null +++ b/console/src/app/modules/providers/provider-oauth/provider-oauth.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { ProviderOAuthComponent } from './provider-oauth.component'; + +describe('ProviderOAuthComponent', () => { + let component: ProviderOAuthComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ProviderOAuthComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProviderOAuthComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/providers/provider-oauth/provider-oauth.component.ts b/console/src/app/modules/providers/provider-oauth/provider-oauth.component.ts new file mode 100644 index 0000000000..a1958e1d6a --- /dev/null +++ b/console/src/app/modules/providers/provider-oauth/provider-oauth.component.ts @@ -0,0 +1,298 @@ +import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes'; +import { Location } from '@angular/common'; +import { Component, Injector, Type } from '@angular/core'; +import { AbstractControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; +import { MatLegacyChipInputEvent as MatChipInputEvent } from '@angular/material/legacy-chips'; +import { ActivatedRoute, Router } from '@angular/router'; +import { take } from 'rxjs'; +import { + AddGenericOAuthProviderRequest as AdminAddGenericOAuthProviderRequest, + GetProviderByIDRequest as AdminGetProviderByIDRequest, + UpdateGenericOAuthProviderRequest as AdminUpdateGenericOAuthProviderRequest, +} from 'src/app/proto/generated/zitadel/admin_pb'; +import { Options, Provider } from 'src/app/proto/generated/zitadel/idp_pb'; +import { + AddGenericOAuthProviderRequest as MgmtAddGenericOAuthProviderRequest, + GetProviderByIDRequest as MgmtGetProviderByIDRequest, + UpdateGenericOAuthProviderRequest as MgmtUpdateGenericOAuthProviderRequest, +} 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 { ManagementService } from 'src/app/services/mgmt.service'; +import { ToastService } from 'src/app/services/toast.service'; + +import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum'; + +@Component({ + selector: 'cnsl-provider-oauth', + templateUrl: './provider-oauth.component.html', + styleUrls: ['./provider-oauth.component.scss'], +}) +export class ProviderOAuthComponent { + public showOptional: boolean = false; + public options: Options = new Options(); + + public id: string | null = ''; + public updateClientSecret: boolean = false; + public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT; + private service!: ManagementService | AdminService; + public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE]; + public form!: UntypedFormGroup; + + public loading: boolean = false; + + public provider?: Provider.AsObject; + + constructor( + private router: Router, + private route: ActivatedRoute, + private toast: ToastService, + private injector: Injector, + private _location: Location, + breadcrumbService: BreadcrumbService, + ) { + this.form = new UntypedFormGroup({ + name: new UntypedFormControl('', [Validators.required]), + clientId: new UntypedFormControl('', [Validators.required]), + clientSecret: new UntypedFormControl('', [Validators.required]), + authorizationEndpoint: new UntypedFormControl('', [Validators.required]), + tokenEndpoint: new UntypedFormControl('', [Validators.required]), + userEndpoint: new UntypedFormControl('', [Validators.required]), + idAttribute: new UntypedFormControl('', [Validators.required]), + scopesList: new UntypedFormControl(['openid', 'profile', 'email'], []), + }); + + 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); + + const bread: Breadcrumb = { + type: BreadcrumbType.ORG, + routerLink: ['/org'], + }; + + breadcrumbService.setBreadcrumb([bread]); + break; + case PolicyComponentServiceType.ADMIN: + this.service = this.injector.get(AdminService as Type); + + const iamBread = new Breadcrumb({ + type: BreadcrumbType.ORG, + name: 'Instance', + routerLink: ['/instance'], + }); + breadcrumbService.setBreadcrumb([iamBread]); + break; + } + + this.id = this.route.snapshot.paramMap.get('id'); + if (this.id) { + this.clientSecret?.setValidators([]); + this.getData(this.id); + } + }); + } + + private getData(id: string): void { + this.loading = true; + 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?.oauth) { + this.form.patchValue(this.provider.config.oauth); + this.name?.setValue(this.provider.name); + } + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } + + public submitForm(): void { + this.provider ? this.updateGenericOAuthProvider() : this.addGenericOAuthProvider(); + } + + public addGenericOAuthProvider(): void { + if (this.serviceType === PolicyComponentServiceType.MGMT) { + const req = new MgmtAddGenericOAuthProviderRequest(); + + req.setName(this.name?.value); + req.setAuthorizationEndpoint(this.authorizationEndpoint?.value); + req.setIdAttribute(this.idAttribute?.value); + req.setTokenEndpoint(this.tokenEndpoint?.value); + req.setUserEndpoint(this.userEndpoint?.value); + req.setClientId(this.clientId?.value); + req.setClientSecret(this.clientSecret?.value); + req.setScopesList(this.scopesList?.value); + + this.loading = true; + (this.service as ManagementService) + .addGenericOAuthProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + }, 2000); + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } else if (PolicyComponentServiceType.ADMIN) { + const req = new AdminAddGenericOAuthProviderRequest(); + req.setName(this.name?.value); + req.setAuthorizationEndpoint(this.authorizationEndpoint?.value); + req.setIdAttribute(this.idAttribute?.value); + req.setTokenEndpoint(this.tokenEndpoint?.value); + req.setUserEndpoint(this.userEndpoint?.value); + req.setClientId(this.clientId?.value); + req.setClientSecret(this.clientSecret?.value); + req.setScopesList(this.scopesList?.value); + + this.loading = true; + (this.service as AdminService) + .addGenericOAuthProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + }, 2000); + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } + } + + public updateGenericOAuthProvider(): void { + if (this.provider) { + if (this.serviceType === PolicyComponentServiceType.MGMT) { + const req = new MgmtUpdateGenericOAuthProviderRequest(); + req.setId(this.provider.id); + req.setName(this.name?.value); + req.setAuthorizationEndpoint(this.authorizationEndpoint?.value); + req.setIdAttribute(this.idAttribute?.value); + req.setTokenEndpoint(this.tokenEndpoint?.value); + req.setUserEndpoint(this.userEndpoint?.value); + req.setClientId(this.clientId?.value); + req.setClientSecret(this.clientSecret?.value); + req.setScopesList(this.scopesList?.value); + + this.loading = true; + (this.service as ManagementService) + .updateGenericOAuthProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.router.navigate(['/org-settings'], { queryParams: { id: 'idp' } }); + }, 2000); + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } else if (PolicyComponentServiceType.ADMIN) { + const req = new AdminUpdateGenericOAuthProviderRequest(); + req.setId(this.provider.id); + req.setName(this.name?.value); + req.setAuthorizationEndpoint(this.authorizationEndpoint?.value); + req.setIdAttribute(this.idAttribute?.value); + req.setTokenEndpoint(this.tokenEndpoint?.value); + req.setUserEndpoint(this.userEndpoint?.value); + req.setClientId(this.clientId?.value); + req.setClientSecret(this.clientSecret?.value); + req.setScopesList(this.scopesList?.value); + + this.loading = true; + (this.service as AdminService) + .updateGenericOAuthProvider(req) + .then((idp) => { + setTimeout(() => { + this.loading = false; + this.router.navigate(['/settings'], { queryParams: { id: 'idp' } }); + }, 2000); + }) + .catch((error) => { + this.toast.showError(error); + this.loading = false; + }); + } + } + } + + public close(): void { + this._location.back(); + } + + public addScope(event: MatChipInputEvent): void { + const input = event.chipInput?.inputElement; + const value = event.value.trim(); + + if (value !== '') { + if (this.scopesList?.value) { + this.scopesList.value.push(value); + if (input) { + input.value = ''; + } + } + } + } + + public removeScope(uri: string): void { + if (this.scopesList?.value) { + const index = this.scopesList.value.indexOf(uri); + + if (index !== undefined && index >= 0) { + this.scopesList.value.splice(index, 1); + } + } + } + + public get name(): AbstractControl | null { + return this.form.get('name'); + } + + public get authorizationEndpoint(): AbstractControl | null { + return this.form.get('authorizationEndpoint'); + } + + public get tokenEndpoint(): AbstractControl | null { + return this.form.get('tokenEndpoint'); + } + + public get userEndpoint(): AbstractControl | null { + return this.form.get('userEndpoint'); + } + + public get idAttribute(): AbstractControl | null { + return this.form.get('idAttribute'); + } + + public get clientId(): AbstractControl | null { + return this.form.get('clientId'); + } + + public get clientSecret(): AbstractControl | null { + return this.form.get('clientSecret'); + } + + public get issuer(): AbstractControl | null { + return this.form.get('issuer'); + } + + public get scopesList(): AbstractControl | null { + return this.form.get('scopesList'); + } +} diff --git a/console/src/app/modules/providers/provider-oauth/provider-oauth.module.ts b/console/src/app/modules/providers/provider-oauth/provider-oauth.module.ts new file mode 100644 index 0000000000..0cbe334707 --- /dev/null +++ b/console/src/app/modules/providers/provider-oauth/provider-oauth.module.ts @@ -0,0 +1,43 @@ +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 {} diff --git a/console/src/app/pages/instance/instance-routing.module.ts b/console/src/app/pages/instance/instance-routing.module.ts index 956467ed5b..ec302781ef 100644 --- a/console/src/app/pages/instance/instance-routing.module.ts +++ b/console/src/app/pages/instance/instance-routing.module.ts @@ -44,6 +44,19 @@ const routes: Routes = [ }, ], }, + { + 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: 'jwt', children: [ diff --git a/console/src/app/pages/orgs/org-routing.module.ts b/console/src/app/pages/orgs/org-routing.module.ts index 93debd337f..24706df076 100644 --- a/console/src/app/pages/orgs/org-routing.module.ts +++ b/console/src/app/pages/orgs/org-routing.module.ts @@ -19,6 +19,19 @@ const routes: Routes = [ 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: [ diff --git a/console/src/app/services/admin.service.ts b/console/src/app/services/admin.service.ts index 78fd6be425..d6c4d69198 100644 --- a/console/src/app/services/admin.service.ts +++ b/console/src/app/services/admin.service.ts @@ -8,6 +8,8 @@ import { ActivateSMSProviderResponse, AddCustomDomainPolicyRequest, AddCustomOrgIAMPolicyResponse, + AddGenericOAuthProviderRequest, + AddGenericOAuthProviderResponse, AddGenericOIDCProviderRequest, AddGenericOIDCProviderResponse, AddGoogleProviderRequest, @@ -194,6 +196,8 @@ import { UpdateCustomDomainPolicyResponse, UpdateDomainPolicyRequest, UpdateDomainPolicyResponse, + UpdateGenericOAuthProviderRequest, + UpdateGenericOAuthProviderResponse, UpdateGenericOIDCProviderRequest, UpdateGenericOIDCProviderResponse, UpdateGoogleProviderRequest, @@ -912,6 +916,16 @@ export class AdminService { return this.grpcService.admin.updateGenericOIDCProvider(req, null).then((resp) => resp.toObject()); } + public addGenericOAuthProvider(req: AddGenericOAuthProviderRequest): Promise { + return this.grpcService.admin.addGenericOAuthProvider(req, null).then((resp) => resp.toObject()); + } + + public updateGenericOAuthProvider( + req: UpdateGenericOAuthProviderRequest, + ): Promise { + return this.grpcService.admin.updateGenericOAuthProvider(req, null).then((resp) => resp.toObject()); + } + public addJWTProvider(req: AddJWTProviderRequest): Promise { return this.grpcService.admin.addJWTProvider(req, null).then((resp) => resp.toObject()); } diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index db5e37b3df..d8a2a438ec 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -29,6 +29,8 @@ import { AddCustomPasswordComplexityPolicyResponse, AddCustomPrivacyPolicyRequest, AddCustomPrivacyPolicyResponse, + AddGenericOAuthProviderRequest, + AddGenericOAuthProviderResponse, AddGenericOIDCProviderRequest, AddGenericOIDCProviderResponse, AddGoogleProviderRequest, @@ -427,6 +429,8 @@ import { UpdateCustomPasswordComplexityPolicyResponse, UpdateCustomPrivacyPolicyRequest, UpdateCustomPrivacyPolicyResponse, + UpdateGenericOAuthProviderRequest, + UpdateGenericOAuthProviderResponse, UpdateGenericOIDCProviderRequest, UpdateGenericOIDCProviderResponse, UpdateGoogleProviderRequest, @@ -871,6 +875,16 @@ export class ManagementService { return this.grpcService.mgmt.updateGenericOIDCProvider(req, null).then((resp) => resp.toObject()); } + public addGenericOAuthProvider(req: AddGenericOAuthProviderRequest): Promise { + return this.grpcService.mgmt.addGenericOAuthProvider(req, null).then((resp) => resp.toObject()); + } + + public updateGenericOAuthProvider( + req: UpdateGenericOAuthProviderRequest, + ): Promise { + return this.grpcService.mgmt.updateGenericOAuthProvider(req, null).then((resp) => resp.toObject()); + } + public addJWTProvider(req: AddJWTProviderRequest): Promise { return this.grpcService.mgmt.addJWTProvider(req, null).then((resp) => resp.toObject()); } diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 88565db185..ffece15de8 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -1674,6 +1674,10 @@ "SETAVAILABLE": "verfügbar setzen", "SETUNAVAILABLE": "auf nicht verfügbar setzen", "NAME": "Name", + "AUTHORIZATIONENDPOINT": "Authorization Endpunkt", + "TOKENENDPOINT": "Token Endpunkt", + "USERENDPOINT": "User Endpunkt", + "IDATTRIBUTE": "ID Attribut", "CONFIG": "Konfiguration", "STATE": "Status", "ISSUER": "Issuer", @@ -1694,10 +1698,13 @@ "DELETE_SELECTION_DESCRIPTION": "Sie sind im Begriff mehrere Identity Provider zu löschen. Die dadurch hervorgerufenen Änderungen sind unwiderruflich. Wollen Sie dies wirklich tun?", "EMPTY": "Kein IDP vorhanden", "OIDC": { - "GENERAL": "Generelle Information", "TITLE": "OIDC Konfiguration", "DESCRIPTION": "Geben Sie die Daten OIDC Identity Providers ein." }, + "OAUTH": { + "TITLE": "OAuth Konfiguration", + "DESCRIPTION": "Geben Sie die Daten OAuth Identity Providers ein." + }, "JWT": { "TITLE": "JWT Konfiguration", "DESCRIPTION": "Geben Sie die Daten JWT Identity Providers ein. ", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index b3757f551c..924a24b8ba 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -1623,6 +1623,10 @@ "TITLE": "OIDC Provider", "DESCRIPTION": "Enter the required data for your OIDC provider." }, + "OAUTH": { + "TITLE": "OAuth Provider", + "DESCRIPTION": "Enter the required data for your OAuth provider." + }, "JWT": { "TITLE": "JWT Provider", "DESCRIPTION": "Enter the required data for your JWT provider." @@ -1665,6 +1669,10 @@ "OWNER": "Owner", "ID": "ID", "NAME": "Name", + "AUTHORIZATIONENDPOINT": "Authorization Endpoint", + "TOKENENDPOINT": "Token Endpoint", + "USERENDPOINT": "User Endpoint", + "IDATTRIBUTE": "ID Attribute", "AVAILABILITY": "Availability", "AVAILABLE": "available", "AVAILABLEBUTINACTIVE": "available but inactive", diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json index 08bd403058..c1851e7055 100644 --- a/console/src/assets/i18n/fr.json +++ b/console/src/assets/i18n/fr.json @@ -1622,6 +1622,10 @@ "TITLE": "Fournisseur OIDC", "DESCRIPTION": "Entrez les données requises pour votre fournisseur OIDC." }, + "OAuth": { + "TITLE": "Fournisseur OAuth", + "DESCRIPTION": "Entrez les données requises pour votre fournisseur OAuth." + }, "JWT": { "TITLE": "Fournisseur JWT", "DESCRIPTION": "Entrez les données requises pour votre fournisseur JWT." @@ -1669,6 +1673,10 @@ "OWNER": "Propriétaire", "ID": "ID", "NAME": "Nom", + "AUTHORIZATIONENDPOINT": "Authorization Endpoint", + "TOKENENDPOINT": "Token Endpoint", + "USERENDPOINT": "User Endpoint", + "IDATTRIBUTE": "Attribut d'identification", "AVAILABILITY": "Disponibilité", "AVAILABLE": "disponible", "AVAILABLEBUTINACTIVE": "disponible mais inactif", diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json index 6ee956a656..55134f3af7 100644 --- a/console/src/assets/i18n/it.json +++ b/console/src/assets/i18n/it.json @@ -1623,6 +1623,10 @@ "TITLE": "OIDC Provider", "DESCRIPTION": "Inserisci i dati necessari per il tuo provider OIDC." }, + "OAuth": { + "TITLE": "OAuth Provider", + "DESCRIPTION": "Inserisci i dati necessari per il tuo provider OAuth." + }, "JWT": { "TITLE": "JWT Provider", "DESCRIPTION": "Inserisci i dati necessari per il tuo provider JWT." @@ -1670,6 +1674,10 @@ "OWNER": "Owner", "ID": "ID", "NAME": "Nome", + "AUTHORIZATIONENDPOINT": "Authorization Endpoint", + "TOKENENDPOINT": "Token Endpoint", + "USERENDPOINT": "User Endpoint", + "IDATTRIBUTE": "Attributo ID", "AVAILABILITY": "Disponibilità", "AVAILABLE": "disponibile", "AVAILABLEBUTINACTIVE": "disponible ma inattivo", diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json index 2a27eafacd..0858d64fdd 100644 --- a/console/src/assets/i18n/pl.json +++ b/console/src/assets/i18n/pl.json @@ -1622,6 +1622,10 @@ "TITLE": "OIDC Provider", "DESCRIPTION": "Wprowadź wymagane dane dla swojego dostawcy OIDC." }, + "OAUTH": { + "TITLE": "OAuth Provider", + "DESCRIPTION": "Wprowadź wymagane dane dla swojego dostawcy OAuth." + }, "JWT": { "TITLE": "JWT Provider", "DESCRIPTION": "Wprowadź wymagane dane dla swojego dostawcy JWT." @@ -1669,6 +1673,10 @@ "OWNER": "Właściciel", "ID": "ID", "NAME": "Nazwa", + "AUTHORIZATIONENDPOINT": "Authorization Endpoint", + "TOKENENDPOINT": "Token Endpoint", + "USERENDPOINT": "User Endpoint", + "IDATTRIBUTE": "Atrybut identyfikatora", "AVAILABILITY": "Dostępność", "AVAILABLE": "dostępny", "AVAILABLEBUTINACTIVE": "dostępny ale nieaktywny", diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json index ddfba6c300..fdad26a0e2 100644 --- a/console/src/assets/i18n/zh.json +++ b/console/src/assets/i18n/zh.json @@ -1621,6 +1621,10 @@ "TITLE": "OIDC供应商", "DESCRIPTION": "输入你的OIDC供应商的必要数据。" }, + "OAUTH": { + "TITLE": "OAuth供应商", + "DESCRIPTION": "输入你的OAuth供应商的必要数据。" + }, "JWT": { "TITLE": "JWT供应商", "DESCRIPTION": "输入你的JWT供应商所需的数据。" @@ -1668,6 +1672,10 @@ "OWNER": "所有者", "ID": "ID", "NAME": "名称", + "AUTHORIZATIONENDPOINT": "授权端点", + "TOKENENDPOINT": "令牌端点", + "USERENDPOINT": "用户端点", + "IDATTRIBUTE": "标识属性", "AVAILABILITY": "可用性", "AVAILABLE": "可用的", "AVAILABLEBUTINACTIVE": "可用但已停用", diff --git a/console/src/assets/images/idp/oauth.svg b/console/src/assets/images/idp/oauth.svg new file mode 100644 index 0000000000..00d25690e0 --- /dev/null +++ b/console/src/assets/images/idp/oauth.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +