diff --git a/console/package.json b/console/package.json index 260b9aee7..947de2dda 100644 --- a/console/package.json +++ b/console/package.json @@ -69,4 +69,4 @@ "tslint": "~6.1.3", "typescript": "^4.0.7" } -} +} \ No newline at end of file diff --git a/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.html b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.html new file mode 100644 index 000000000..448b4f4eb --- /dev/null +++ b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.html @@ -0,0 +1,28 @@ +
+ + {{ title }} + + + + +
+ +
+
+ {{uri}} + + + + + +
+
+ +

+ {{'APP.OIDC.REDIRECTNOTVALID' | translate}}

\ No newline at end of file diff --git a/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.scss b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.scss new file mode 100644 index 000000000..fa3bade76 --- /dev/null +++ b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.scss @@ -0,0 +1,62 @@ +.form { + display: flex; + align-items: flex-end; + min-width: 320px; + + .formfield { + flex: 1; + } + + button { + margin-bottom: 14px; + margin-right: -.5rem; + } +} + +.uri-list { + margin: 0 .5rem; + width: 100%; + + .uri-line { + display: flex; + align-items: center; + + .uri { + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 14px; + } + + .fill-space { + flex: 1; + } + + i.green { + font-size: 1rem; + line-height: 35px; + height: 30px; + } + + i.red { + font-size: 1.2rem; + } + + .icon-button { + height: 30px; + line-height: 30px; + + .icon { + font-size: 1rem !important; + } + + &:not(:hover) { + color: var(--grey); + } + } + } +} + +.error { + font-size: 13px; + color: #f44336; + margin: 0 .5rem 1.5rem .5rem; +} diff --git a/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.spec.ts b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.spec.ts new file mode 100644 index 000000000..ae36ab6fd --- /dev/null +++ b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdditionalOriginsComponent } from './additional-origins.component'; + +describe('AdditionalOriginsComponent', () => { + let component: AdditionalOriginsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AdditionalOriginsComponent], + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AdditionalOriginsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.ts b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.ts new file mode 100644 index 000000000..8fcd38c99 --- /dev/null +++ b/console/src/app/pages/projects/apps/additional-origins/additional-origins.component.ts @@ -0,0 +1,56 @@ +import { Component, EventEmitter, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { Observable, Subscription } from 'rxjs'; + +@Component({ + selector: 'cnsl-additional-origins', + templateUrl: './additional-origins.component.html', + styleUrls: ['./additional-origins.component.scss'], +}) +export class AdditionalOriginsComponent implements OnInit, OnDestroy { + @Input() title: string = ''; + @Input() canWrite: boolean = false; + @Input() public urisList: string[] = []; + @Input() public redirectControl: FormControl = new FormControl({ value: '', disabled: true }); + @Input() public changedUris: EventEmitter = new EventEmitter(); + @Input() public getValues: Observable = new Observable(); + public placeholder: string = ' "://" [ ":" ]'; + + @ViewChild('originInput') input!: any; + private sub: Subscription = new Subscription(); + + constructor() { } + + ngOnInit(): void { + if (this.canWrite) { + this.redirectControl.enable(); + } + + this.sub = this.getValues.subscribe(() => { + this.add(this.input.nativeElement); + }); + } + + ngOnDestroy(): void { + this.sub.unsubscribe(); + } + + public add(input: any): void { + if (this.redirectControl.valid) { + if (input.value !== '' && input.value !== ' ' && input.value !== '/') { + this.urisList.push(input.value); + } + if (input) { + input.value = ''; + } + } + } + + public remove(redirect: any): void { + const index = this.urisList.indexOf(redirect); + + if (index >= 0) { + this.urisList.splice(index, 1); + } + } +} diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html index af0556d90..a6251c47a 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html @@ -118,7 +118,6 @@ {{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}} -
+ +
+ +
+

{{'APP.ADDITIONALORIGINS' | translate}} + +

+ +

{{'APP.ADDITIONALORIGINSDESC' | translate}}

+ + +
+
+ +
duration.lte.nanos: 0
duration.gte.seconds: 0
duration.gte.nanos: 0
| +| additional_origins | repeated string | - | | @@ -5194,6 +5195,7 @@ This is an empty request | id_token_role_assertion | bool | - | | | id_token_userinfo_assertion | bool | - | | | clock_skew | google.protobuf.Duration | - | duration.lte.seconds: 5
duration.lte.nanos: 0
duration.gte.seconds: 0
duration.gte.nanos: 0
| +| additional_origins | repeated string | - | | diff --git a/internal/api/grpc/management/project_application_converter.go b/internal/api/grpc/management/project_application_converter.go index e38ee5157..516bae58e 100644 --- a/internal/api/grpc/management/project_application_converter.go +++ b/internal/api/grpc/management/project_application_converter.go @@ -52,6 +52,7 @@ func AddOIDCAppRequestToDomain(req *mgmt_pb.AddOIDCAppRequest) *domain.OIDCApp { IDTokenRoleAssertion: req.IdTokenRoleAssertion, IDTokenUserinfoAssertion: req.IdTokenUserinfoAssertion, ClockSkew: req.ClockSkew.AsDuration(), + AdditionalOrigins: req.AdditionalOrigins, } } @@ -90,6 +91,7 @@ func UpdateOIDCAppConfigRequestToDomain(app *mgmt_pb.UpdateOIDCAppConfigRequest) IDTokenRoleAssertion: app.IdTokenRoleAssertion, IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion, ClockSkew: app.ClockSkew.AsDuration(), + AdditionalOrigins: app.AdditionalOrigins, } } diff --git a/internal/api/grpc/project/application.go b/internal/api/grpc/project/application.go index 07f1b60f0..efcf57689 100644 --- a/internal/api/grpc/project/application.go +++ b/internal/api/grpc/project/application.go @@ -55,6 +55,8 @@ func AppOIDCConfigToPb(app *proj_model.ApplicationView) *app_pb.App_OidcConfig { IdTokenRoleAssertion: app.IDTokenRoleAssertion, IdTokenUserinfoAssertion: app.IDTokenUserinfoAssertion, ClockSkew: durationpb.New(app.ClockSkew), + AdditionalOrigins: app.AdditionalOrigins, + AllowedOrigins: app.OriginAllowList, }, } } diff --git a/internal/api/http/origin.go b/internal/api/http/origin.go index 44f222790..62c6967bd 100644 --- a/internal/api/http/origin.go +++ b/internal/api/http/origin.go @@ -21,3 +21,12 @@ func IsOriginAllowed(allowList []string, origin string) bool { } return false } + +//IsOrigin checks if provided string is an origin (scheme://hostname[:port]) without path, query or fragment +func IsOrigin(rawOrigin string) bool { + parsedUrl, err := url.Parse(rawOrigin) + if err != nil { + return false + } + return parsedUrl.Scheme != "" && parsedUrl.Host != "" && parsedUrl.Path == "" && len(parsedUrl.Query()) == 0 && parsedUrl.Fragment == "" +} diff --git a/internal/command/project_application_oidc.go b/internal/command/project_application_oidc.go index 540c69eea..145340171 100644 --- a/internal/command/project_application_oidc.go +++ b/internal/command/project_application_oidc.go @@ -81,7 +81,8 @@ func (c *Commands) addOIDCApplication(ctx context.Context, projectAgg *eventstor oidcApp.AccessTokenRoleAssertion, oidcApp.IDTokenRoleAssertion, oidcApp.IDTokenUserinfoAssertion, - oidcApp.ClockSkew)) + oidcApp.ClockSkew, + oidcApp.AdditionalOrigins)) return events, stringPw, nil } @@ -115,7 +116,8 @@ func (c *Commands) ChangeOIDCApplication(ctx context.Context, oidc *domain.OIDCA oidc.AccessTokenRoleAssertion, oidc.IDTokenRoleAssertion, oidc.IDTokenUserinfoAssertion, - oidc.ClockSkew) + oidc.ClockSkew, + oidc.AdditionalOrigins) if err != nil { return nil, err } diff --git a/internal/command/project_application_oidc_model.go b/internal/command/project_application_oidc_model.go index 2a39778c9..7b9ac23df 100644 --- a/internal/command/project_application_oidc_model.go +++ b/internal/command/project_application_oidc_model.go @@ -33,6 +33,7 @@ type OIDCApplicationWriteModel struct { IDTokenUserinfoAssertion bool ClockSkew time.Duration State domain.AppState + AdditionalOrigins []string } func NewOIDCApplicationWriteModelWithAppID(projectID, appID, resourceOwner string) *OIDCApplicationWriteModel { @@ -151,6 +152,7 @@ func (wm *OIDCApplicationWriteModel) appendAddOIDCEvent(e *project.OIDCConfigAdd wm.IDTokenRoleAssertion = e.IDTokenRoleAssertion wm.IDTokenUserinfoAssertion = e.IDTokenUserinfoAssertion wm.ClockSkew = e.ClockSkew + wm.AdditionalOrigins = e.AdditionalOrigins } func (wm *OIDCApplicationWriteModel) appendChangeOIDCEvent(e *project.OIDCConfigChangedEvent) { @@ -193,6 +195,9 @@ func (wm *OIDCApplicationWriteModel) appendChangeOIDCEvent(e *project.OIDCConfig if e.ClockSkew != nil { wm.ClockSkew = *e.ClockSkew } + if e.AdditionalOrigins != nil { + wm.AdditionalOrigins = *e.AdditionalOrigins + } } func (wm *OIDCApplicationWriteModel) Query() *eventstore.SearchQueryBuilder { @@ -229,6 +234,7 @@ func (wm *OIDCApplicationWriteModel) NewChangedEvent( idTokenRoleAssertion, idTokenUserinfoAssertion bool, clockSkew time.Duration, + additionalOrigins []string, ) (*project.OIDCConfigChangedEvent, bool, error) { changes := make([]project.OIDCConfigChanges, 0) var err error @@ -272,6 +278,9 @@ func (wm *OIDCApplicationWriteModel) NewChangedEvent( if wm.ClockSkew != clockSkew { changes = append(changes, project.ChangeClockSkew(clockSkew)) } + if !reflect.DeepEqual(wm.AdditionalOrigins, additionalOrigins) { + changes = append(changes, project.ChangeAdditionalOrigins(additionalOrigins)) + } if len(changes) == 0 { return nil, false, nil } diff --git a/internal/command/project_application_oidc_test.go b/internal/command/project_application_oidc_test.go index f4079603b..b590cf6cb 100644 --- a/internal/command/project_application_oidc_test.go +++ b/internal/command/project_application_oidc_test.go @@ -151,7 +151,8 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) { true, true, true, - time.Second*1), + time.Second*1, + []string{"https://sub.test.ch"}), ), }, uniqueConstraintsFromEventConstraint(project.NewAddApplicationUniqueConstraint("app", "project1")), @@ -180,6 +181,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) { IDTokenRoleAssertion: true, IDTokenUserinfoAssertion: true, ClockSkew: time.Second * 1, + AdditionalOrigins: []string{"https://sub.test.ch"}, }, resourceOwner: "org1", }, @@ -206,6 +208,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) { IDTokenRoleAssertion: true, IDTokenUserinfoAssertion: true, ClockSkew: time.Second * 1, + AdditionalOrigins: []string{"https://sub.test.ch"}, State: domain.AppStateActive, Compliance: &domain.Compliance{}, }, @@ -382,7 +385,8 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) { true, true, true, - time.Second*1), + time.Second*1, + []string{"https://sub.test.ch"}), ), ), ), @@ -408,6 +412,7 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) { IDTokenRoleAssertion: true, IDTokenUserinfoAssertion: true, ClockSkew: time.Second * 1, + AdditionalOrigins: []string{"https://sub.test.ch"}, }, resourceOwner: "org1", }, @@ -451,7 +456,8 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) { true, true, true, - time.Second*1), + time.Second*1, + []string{"https://sub.test.ch"}), ), ), expectPush( @@ -487,6 +493,7 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) { IDTokenRoleAssertion: false, IDTokenUserinfoAssertion: false, ClockSkew: time.Second * 2, + AdditionalOrigins: []string{"https://sub.test.ch"}, }, resourceOwner: "org1", }, @@ -512,6 +519,7 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) { IDTokenRoleAssertion: false, IDTokenUserinfoAssertion: false, ClockSkew: time.Second * 2, + AdditionalOrigins: []string{"https://sub.test.ch"}, Compliance: &domain.Compliance{}, State: domain.AppStateActive, }, @@ -645,7 +653,8 @@ func TestCommandSide_ChangeOIDCApplicationSecret(t *testing.T) { true, true, true, - time.Second*1), + time.Second*1, + []string{"https://sub.test.ch"}), ), ), expectPush( @@ -695,6 +704,7 @@ func TestCommandSide_ChangeOIDCApplicationSecret(t *testing.T) { IDTokenRoleAssertion: true, IDTokenUserinfoAssertion: true, ClockSkew: time.Second * 1, + AdditionalOrigins: []string{"https://sub.test.ch"}, State: domain.AppStateActive, }, }, diff --git a/internal/command/project_converter.go b/internal/command/project_converter.go index 220911c50..2aee9bb5c 100644 --- a/internal/command/project_converter.go +++ b/internal/command/project_converter.go @@ -51,6 +51,7 @@ func oidcWriteModelToOIDCConfig(writeModel *OIDCApplicationWriteModel) *domain.O IDTokenRoleAssertion: writeModel.IDTokenRoleAssertion, IDTokenUserinfoAssertion: writeModel.IDTokenUserinfoAssertion, ClockSkew: writeModel.ClockSkew, + AdditionalOrigins: writeModel.AdditionalOrigins, } } diff --git a/internal/domain/application_oidc.go b/internal/domain/application_oidc.go index dc3b14470..fd67b9c6f 100644 --- a/internal/domain/application_oidc.go +++ b/internal/domain/application_oidc.go @@ -4,6 +4,7 @@ import ( "strings" "time" + http_util "github.com/caos/zitadel/internal/api/http" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v1/models" ) @@ -43,6 +44,7 @@ type OIDCApp struct { IDTokenRoleAssertion bool IDTokenUserinfoAssertion bool ClockSkew time.Duration + AdditionalOrigins []string State AppState } @@ -119,7 +121,7 @@ const ( ) func (a *OIDCApp) IsValid() bool { - if a.ClockSkew > time.Second*5 || a.ClockSkew < time.Second*0 { + if a.ClockSkew > time.Second*5 || a.ClockSkew < time.Second*0 || !a.OriginsValid() { return false } grantTypes := a.getRequiredGrantTypes() @@ -135,6 +137,15 @@ func (a *OIDCApp) IsValid() bool { return true } +func (a *OIDCApp) OriginsValid() bool { + for _, origin := range a.AdditionalOrigins { + if !http_util.IsOrigin(origin) { + return false + } + } + return true +} + func (a *OIDCApp) getRequiredGrantTypes() []OIDCGrantType { grantTypes := make([]OIDCGrantType, 0) implicit := false diff --git a/internal/domain/application_oidc_test.go b/internal/domain/application_oidc_test.go index b2897764b..63aee9159 100644 --- a/internal/domain/application_oidc_test.go +++ b/internal/domain/application_oidc_test.go @@ -1,9 +1,10 @@ package domain import ( - "github.com/caos/zitadel/internal/eventstore/v1/models" "testing" "time" + + "github.com/caos/zitadel/internal/eventstore/v1/models" ) func TestApplicationValid(t *testing.T) { @@ -160,6 +161,20 @@ func TestApplicationValid(t *testing.T) { }, result: true, }, + { + name: "invalid oidc application: invalid origin", + args: args{ + app: &OIDCApp{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + AppID: "AppID", + AppName: "Name", + ResponseTypes: []OIDCResponseType{OIDCResponseTypeCode, OIDCResponseTypeIDToken, OIDCResponseTypeIDTokenToken}, + GrantTypes: []OIDCGrantType{OIDCGrantTypeAuthorizationCode, OIDCGrantTypeImplicit}, + AdditionalOrigins: []string{"https://test.com/test"}, + }, + }, + result: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/project/model/application_view.go b/internal/project/model/application_view.go index 37db1ebc2..20bfc2062 100644 --- a/internal/project/model/application_view.go +++ b/internal/project/model/application_view.go @@ -30,6 +30,7 @@ type ApplicationView struct { ComplianceProblems []string DevMode bool OriginAllowList []string + AdditionalOrigins []string AccessTokenType OIDCTokenType IDTokenRoleAssertion bool AccessTokenRoleAssertion bool diff --git a/internal/project/repository/view/model/application.go b/internal/project/repository/view/model/application.go index 5a5a3a836..4440c10ec 100644 --- a/internal/project/repository/view/model/application.go +++ b/internal/project/repository/view/model/application.go @@ -45,6 +45,7 @@ type ApplicationView struct { ComplianceProblems pq.StringArray `json:"-" gorm:"column:compliance_problems"` DevMode bool `json:"devMode" gorm:"column:dev_mode"` OriginAllowList pq.StringArray `json:"-" gorm:"column:origin_allow_list"` + AdditionalOrigins pq.StringArray `json:"additionalOrigins" gorm:"column:additional_origins"` AccessTokenType int32 `json:"accessTokenType" gorm:"column:access_token_type"` AccessTokenRoleAssertion bool `json:"accessTokenRoleAssertion" gorm:"column:access_token_role_assertion"` IDTokenRoleAssertion bool `json:"idTokenRoleAssertion" gorm:"column:id_token_role_assertion"` @@ -79,6 +80,7 @@ func ApplicationViewToModel(app *ApplicationView) *model.ApplicationView { ComplianceProblems: app.ComplianceProblems, DevMode: app.DevMode, OriginAllowList: app.OriginAllowList, + AdditionalOrigins: app.AdditionalOrigins, AccessTokenType: model.OIDCTokenType(app.AccessTokenType), AccessTokenRoleAssertion: app.AccessTokenRoleAssertion, IDTokenRoleAssertion: app.IDTokenRoleAssertion, @@ -213,6 +215,11 @@ func (a *ApplicationView) setOriginAllowList() error { allowList = append(allowList, origin) } } + for _, origin := range a.AdditionalOrigins { + if !http_util.IsOriginAllowed(allowList, origin) { + allowList = append(allowList, origin) + } + } a.OriginAllowList = allowList return nil } diff --git a/internal/repository/project/oidc_config.go b/internal/repository/project/oidc_config.go index 2c2996799..acf67ddcb 100644 --- a/internal/repository/project/oidc_config.go +++ b/internal/repository/project/oidc_config.go @@ -3,12 +3,12 @@ package project import ( "context" "encoding/json" - "github.com/caos/zitadel/internal/eventstore" "time" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/repository" ) @@ -39,6 +39,7 @@ type OIDCConfigAddedEvent struct { IDTokenRoleAssertion bool `json:"idTokenRoleAssertion,omitempty"` IDTokenUserinfoAssertion bool `json:"idTokenUserinfoAssertion,omitempty"` ClockSkew time.Duration `json:"clockSkew,omitempty"` + AdditionalOrigins []string `json:"additionalOrigins,omitempty"` } func (e *OIDCConfigAddedEvent) Data() interface{} { @@ -68,6 +69,7 @@ func NewOIDCConfigAddedEvent( idTokenRoleAssertion bool, idTokenUserinfoAssertion bool, clockSkew time.Duration, + additionalOrigins []string, ) *OIDCConfigAddedEvent { return &OIDCConfigAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( @@ -91,6 +93,7 @@ func NewOIDCConfigAddedEvent( IDTokenRoleAssertion: idTokenRoleAssertion, IDTokenUserinfoAssertion: idTokenUserinfoAssertion, ClockSkew: clockSkew, + AdditionalOrigins: additionalOrigins, } } @@ -124,6 +127,7 @@ type OIDCConfigChangedEvent struct { IDTokenRoleAssertion *bool `json:"idTokenRoleAssertion,omitempty"` IDTokenUserinfoAssertion *bool `json:"idTokenUserinfoAssertion,omitempty"` ClockSkew *time.Duration `json:"clockSkew,omitempty"` + AdditionalOrigins *[]string `json:"additionalOrigins,omitempty"` } func (e *OIDCConfigChangedEvent) Data() interface{} { @@ -238,6 +242,12 @@ func ChangeClockSkew(clockSkew time.Duration) func(event *OIDCConfigChangedEvent } } +func ChangeAdditionalOrigins(additionalOrigins []string) func(event *OIDCConfigChangedEvent) { + return func(e *OIDCConfigChangedEvent) { + e.AdditionalOrigins = &additionalOrigins + } +} + func OIDCConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { e := &OIDCConfigChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), diff --git a/migrations/cockroach/V1.43__additional_origins.sql b/migrations/cockroach/V1.43__additional_origins.sql new file mode 100644 index 000000000..0aac4c474 --- /dev/null +++ b/migrations/cockroach/V1.43__additional_origins.sql @@ -0,0 +1,3 @@ +ALTER TABLE auth.applications ADD COLUMN additional_origins TEXT ARRAY; +ALTER TABLE authz.applications ADD COLUMN additional_origins TEXT ARRAY; +ALTER TABLE management.applications ADD COLUMN additional_origins TEXT ARRAY; \ No newline at end of file diff --git a/proto/zitadel/app.proto b/proto/zitadel/app.proto index 20d9093a4..312d3adbd 100644 --- a/proto/zitadel/app.proto +++ b/proto/zitadel/app.proto @@ -65,7 +65,7 @@ message AppNameQuery { message OIDCConfig { repeated string redirect_uris = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "[\"console.zitadel.ch/authorized\"]"; + example: "[\"https://console.zitadel.ch/auth/callback\"]"; description: "Callback URI of the authorization request where the code or tokens will be sent to"; } ]; @@ -103,7 +103,7 @@ message OIDCConfig { ]; repeated string post_logout_redirect_uris = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "[\"console.zitadel.ch/logout\"]"; + example: "[\"https://console.zitadel.ch/logout\"]"; description: "ZITADEL will redirect to this link after a successful logout"; } ]; @@ -154,6 +154,18 @@ message OIDCConfig { // max: "5s"; } ]; + repeated string additional_origins = 18 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[\"https://console.zitadel.ch/auth/callback\"]"; + description: "additional origins (other than the redirect_uris) from where the api can be used"; + } + ]; + repeated string allowed_origins = 19 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[\"https://console.zitadel.ch/auth/callback\"]"; + description: "all allowed origins from where the api can be used"; + } + ]; } enum OIDCResponseType { diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index 83f7c470f..f8d241298 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -2953,6 +2953,7 @@ message AddOIDCAppRequest { bool id_token_role_assertion = 13; bool id_token_userinfo_assertion = 14; google.protobuf.Duration clock_skew = 15 [(validate.rules).duration = {gte: {}, lte: {seconds: 5}}]; + repeated string additional_origins = 16; } message AddOIDCAppResponse { @@ -3023,6 +3024,7 @@ message UpdateOIDCAppConfigRequest { bool id_token_role_assertion = 12; bool id_token_userinfo_assertion = 13; google.protobuf.Duration clock_skew = 14 [(validate.rules).duration = {gte: {}, lte: {seconds: 5}}]; + repeated string additional_origins = 15; } message UpdateOIDCAppConfigResponse {