3874 Commits

Author SHA1 Message Date
Livio Spring
5aaaaa2398 fix(login): cache scripts and other assets correctly (#9551)
# Which Problems Are Solved

Scripts and other assets for the hosted login UI are served with a
public cache with `max-age` and `s-maxage`. After changing scripts or
assets, old versions might be still used as they might be cached locally
or in a shared cache (CDN, proxy, ...). This can lead to unwanted
behaviour or even errors.

# How the Problems Are Solved

To ensure the correct file is served a query parameter with the build
time is added to the assets filename dynamically. (`?v=2025-03-17...`)

# Additional Changes

None

# Additional Context

- relates to #9485
- requires backport to at least 2.70.x

(cherry picked from commit 19f022e1cf)
2025-03-17 17:39:43 +01:00
Livio Spring
9277e2b706 fix(console): allow management of metadata of users of other organizations again (#9490)
# Which Problems Are Solved

With the recent change in Console to use the User V2 API
(https://github.com/zitadel/zitadel/pull/9312), some functionality still
needs to call the management API, which requires the organization
context. The context was not passed anymore, leading to error in cases
where the calling user (e.g. an IAM_OWNER) was not part of the same
organization.

# How the Problems Are Solved

Added an interceptor to provide the `x-zitadel-orgid` header for the new
management client.

# Additional Changes

None

# Additional Context

- closes #9488

(cherry picked from commit 61c4b1c3fd)
2025-03-17 17:39:38 +01:00
Silvan
205229f0d1 fix(perf): simplify eventstore queries by removing or in projection handlers (#9530)
# Which Problems Are Solved

[A recent performance
enhancement]((https://github.com/zitadel/zitadel/pull/9497)) aimed at
optimizing event store queries, specifically those involving multiple
aggregate type filters, has successfully improved index utilization.
While the query planner now correctly selects relevant indexes, it
employs [bitmap index
scans](https://www.postgresql.org/docs/current/indexes-bitmap-scans.html)
to retrieve data.

This approach, while beneficial in many scenarios, introduces a
potential I/O bottleneck. The bitmap index scan first identifies the
required database blocks and then utilizes a bitmap to access the
corresponding rows from the table's heap. This subsequent "bitmap heap
scan" can result in significant I/O overhead, particularly when queries
return a substantial number of rows across numerous data pages.

## Impact:

Under heavy load or with queries filtering for a wide range of events
across multiple aggregate types, this increased I/O activity may lead
to:

- Increased query latency.
- Elevated disk utilization.
- Potential performance degradation of the event store and dependent
systems.

# How the Problems Are Solved

To address this I/O bottleneck and further optimize query performance,
the projection handler has been modified. Instead of employing multiple
OR clauses for each aggregate type, the aggregate and event type filters
are now combined using IN ARRAY filters.

Technical Details:

This change allows the PostgreSQL query planner to leverage [index-only
scans](https://www.postgresql.org/docs/current/indexes-index-only-scans.html).
By utilizing IN ARRAY filters, the database can efficiently retrieve the
necessary data directly from the index, eliminating the need to access
the table's heap. This results in:

* Reduced I/O: Index-only scans significantly minimize disk I/O
operations, as the database avoids reading data pages from the main
table.
* Improved Query Performance: By reducing I/O, query execution times are
substantially improved, leading to lower latency.

# Additional Changes

- rollback of https://github.com/zitadel/zitadel/pull/9497

# Additional Information

## Query Plan of previous query

```sql
SELECT
    created_at, event_type, "sequence", "position", payload, creator, "owner", instance_id, aggregate_type, aggregate_id, revision
FROM
    eventstore.events2
WHERE
    instance_id = '<INSTANCE_ID>'
    AND (
        (
            instance_id = '<INSTANCE_ID>'
            AND "position" > <POSITION>
            AND aggregate_type = 'project'
            AND event_type = ANY(ARRAY[
                                'project.application.added'
                                ,'project.application.changed'
                                ,'project.application.deactivated'
                                ,'project.application.reactivated'
                                ,'project.application.removed'
                                ,'project.removed'
                                ,'project.application.config.api.added'
                                ,'project.application.config.api.changed'
                                ,'project.application.config.api.secret.changed'
                ,'project.application.config.api.secret.updated'
                                ,'project.application.config.oidc.added'
                                ,'project.application.config.oidc.changed'
                                ,'project.application.config.oidc.secret.changed'
                ,'project.application.config.oidc.secret.updated'
                                ,'project.application.config.saml.added'
                                ,'project.application.config.saml.changed'
                        ])
        ) OR (
            instance_id = '<INSTANCE_ID>'
            AND "position" > <POSITION>
            AND aggregate_type = 'org'
            AND event_type = 'org.removed'
        ) OR (
            instance_id = '<INSTANCE_ID>'
            AND "position" > <POSITION>
            AND aggregate_type = 'instance'
            AND event_type = 'instance.removed'
        )
    )
    AND "position" > 1741600905.3495
    AND "position" < (
        SELECT
            COALESCE(EXTRACT(EPOCH FROM min(xact_start)), EXTRACT(EPOCH FROM now()))
        FROM
            pg_stat_activity
        WHERE
            datname = current_database()
            AND application_name = ANY(ARRAY['zitadel_es_pusher_', 'zitadel_es_pusher', 'zitadel_es_pusher_<INSTANCE_ID>'])
            AND state <> 'idle'
    )
ORDER BY "position", in_tx_order LIMIT 200 OFFSET 1;
```

```
Limit  (cost=120.08..120.09 rows=7 width=361) (actual time=2.167..2.172 rows=0 loops=1)
   Output: events2.created_at, events2.event_type, events2.sequence, events2."position", events2.payload, events2.creator, events2.owner, events2.instance_id, events2.aggregate_type, events2.aggregate_id, events2.revision, events2.in_tx_order
   InitPlan 1
     ->  Aggregate  (cost=2.74..2.76 rows=1 width=32) (actual time=1.813..1.815 rows=1 loops=1)
           Output: COALESCE(EXTRACT(epoch FROM min(s.xact_start)), EXTRACT(epoch FROM now()))
           ->  Nested Loop  (cost=0.00..2.74 rows=1 width=8) (actual time=1.803..1.805 rows=0 loops=1)
                 Output: s.xact_start
                 Join Filter: (d.oid = s.datid)
                 ->  Seq Scan on pg_catalog.pg_database d  (cost=0.00..1.07 rows=1 width=4) (actual time=0.016..0.021 rows=1 loops=1)
                       Output: d.oid, d.datname, d.datdba, d.encoding, d.datlocprovider, d.datistemplate, d.datallowconn, d.dathasloginevt, d.datconnlimit, d.datfrozenxid, d.datminmxid, d.dattablespace, d.datcollate, d.datctype, d.datlocale, d.daticurules, d.datcollversion, d.datacl
                       Filter: (d.datname = current_database())
                       Rows Removed by Filter: 4
                 ->  Function Scan on pg_catalog.pg_stat_get_activity s  (cost=0.00..1.63 rows=3 width=16) (actual time=1.781..1.781 rows=0 loops=1)
                       Output: s.datid, s.pid, s.usesysid, s.application_name, s.state, s.query, s.wait_event_type, s.wait_event, s.xact_start, s.query_start, s.backend_start, s.state_change, s.client_addr, s.client_hostname, s.client_port, s.backend_xid, s.backend_xmin, s.backend_type, s.ssl, s.sslversion, s.sslcipher, s.sslbits, s.ssl_client_dn, s.ssl_client_serial, s.ssl_issuer_dn, s.gss_auth, s.gss_princ, s.gss_enc, s.gss_delegation, s.leader_pid, s.query_id
                       Function Call: pg_stat_get_activity(NULL::integer)
                       Filter: ((s.state <> 'idle'::text) AND (s.application_name = ANY ('{zitadel_es_pusher_,zitadel_es_pusher,zitadel_es_pusher_<INSTANCE_ID>}'::text[])))
                       Rows Removed by Filter: 49
   ->  Sort  (cost=117.31..117.33 rows=8 width=361) (actual time=2.167..2.168 rows=0 loops=1)
         Output: events2.created_at, events2.event_type, events2.sequence, events2."position", events2.payload, events2.creator, events2.owner, events2.instance_id, events2.aggregate_type, events2.aggregate_id, events2.revision, events2.in_tx_order
         Sort Key: events2."position", events2.in_tx_order
         Sort Method: quicksort  Memory: 25kB
         ->  Bitmap Heap Scan on eventstore.events2  (cost=84.92..117.19 rows=8 width=361) (actual time=2.088..2.089 rows=0 loops=1)
               Output: events2.created_at, events2.event_type, events2.sequence, events2."position", events2.payload, events2.creator, events2.owner, events2.instance_id, events2.aggregate_type, events2.aggregate_id, events2.revision, events2.in_tx_order
               Recheck Cond: (((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = 'project'::text) AND (events2.event_type = ANY ('{project.application.added,project.application.changed,project.application.deactivated,project.application.reactivated,project.application.removed,project.removed,project.application.config.api.added,project.application.config.api.changed,project.application.config.api.secret.changed,project.application.config.api.secret.updated,project.application.config.oidc.added,project.application.config.oidc.changed,project.application.config.oidc.secret.changed,project.application.config.oidc.secret.updated,project.application.config.saml.added,project.application.config.saml.changed}'::text[])) AND (events2."position" > <POSITION>) AND (events2."position" > 1741600905.3495) AND (events2."position" < (InitPlan 1).col1)) OR ((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = 'org'::text) AND (events2.event_type = 'org.removed'::text) AND (events2."position" > <POSITION>) AND (events2."position" > 1741600905.3495) AND (events2."position" < (InitPlan 1).col1)) OR ((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = 'instance'::text) AND (events2.event_type = 'instance.removed'::text) AND (events2."position" > <POSITION>) AND (events2."position" > 1741600905.3495) AND (events2."position" < (InitPlan 1).col1)))
               ->  BitmapOr  (cost=84.88..84.88 rows=8 width=0) (actual time=2.080..2.081 rows=0 loops=1)
                     ->  Bitmap Index Scan on es_projection  (cost=0.00..75.44 rows=8 width=0) (actual time=2.016..2.017 rows=0 loops=1)
                           Index Cond: ((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = 'project'::text) AND (events2.event_type = ANY ('{project.application.added,project.application.changed,project.application.deactivated,project.application.reactivated,project.application.removed,project.removed,project.application.config.api.added,project.application.config.api.changed,project.application.config.api.secret.changed,project.application.config.api.secret.updated,project.application.config.oidc.added,project.application.config.oidc.changed,project.application.config.oidc.secret.changed,project.application.config.oidc.secret.updated,project.application.config.saml.added,project.application.config.saml.changed}'::text[])) AND (events2."position" > <POSITION>) AND (events2."position" > 1741600905.3495) AND (events2."position" < (InitPlan 1).col1))
                     ->  Bitmap Index Scan on es_projection  (cost=0.00..4.71 rows=1 width=0) (actual time=0.016..0.016 rows=0 loops=1)
                           Index Cond: ((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = 'org'::text) AND (events2.event_type = 'org.removed'::text) AND (events2."position" > <POSITION>) AND (events2."position" > 1741600905.3495) AND (events2."position" < (InitPlan 1).col1))
                     ->  Bitmap Index Scan on es_projection  (cost=0.00..4.71 rows=1 width=0) (actual time=0.045..0.045 rows=0 loops=1)
                           Index Cond: ((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = 'instance'::text) AND (events2.event_type = 'instance.removed'::text) AND (events2."position" > <POSITION>) AND (events2."position" > 1741600905.3495) AND (events2."position" < (InitPlan 1).col1))
 Query Identifier: 3194938266011254479
 Planning Time: 1.295 ms
 Execution Time: 2.832 ms
```

## Query Plan of new query

```sql
SELECT
    created_at, event_type, "sequence", "position", payload, creator, "owner", instance_id, aggregate_type, aggregate_id, revision
FROM
    eventstore.events2
WHERE
    instance_id = '<INSTANCE_ID>'
    AND "position" > <POSITION>
    AND aggregate_type = ANY(ARRAY['project', 'instance', 'org'])
    AND event_type = ANY(ARRAY[
        'project.application.added'
        ,'project.application.changed'
        ,'project.application.deactivated'
        ,'project.application.reactivated'
        ,'project.application.removed'
        ,'project.removed'
        ,'project.application.config.api.added'
        ,'project.application.config.api.changed'
        ,'project.application.config.api.secret.changed'
        ,'project.application.config.api.secret.updated'
        ,'project.application.config.oidc.added'
        ,'project.application.config.oidc.changed'
        ,'project.application.config.oidc.secret.changed'
        ,'project.application.config.oidc.secret.updated'
        ,'project.application.config.saml.added'
        ,'project.application.config.saml.changed'
        ,'org.removed'
        ,'instance.removed'
    ])
    AND "position" < (
        SELECT
            COALESCE(EXTRACT(EPOCH FROM min(xact_start)), EXTRACT(EPOCH FROM now()))
        FROM
            pg_stat_activity
        WHERE
            datname = current_database()
            AND application_name = ANY(ARRAY['zitadel_es_pusher_', 'zitadel_es_pusher', 'zitadel_es_pusher_<INSTANCE_ID>'])
            AND state <> 'idle'
    )
ORDER BY "position", in_tx_order LIMIT 200 OFFSET 1;
```

```
Limit  (cost=293.34..293.36 rows=8 width=361) (actual time=4.686..4.689 rows=0 loops=1)
   Output: events2.created_at, events2.event_type, events2.sequence, events2."position", events2.payload, events2.creator, events2.owner, events2.instance_id, events2.aggregate_type, events2.aggregate_id, events2.revision, events2.in_tx_order
   InitPlan 1
     ->  Aggregate  (cost=2.74..2.76 rows=1 width=32) (actual time=1.717..1.719 rows=1 loops=1)
           Output: COALESCE(EXTRACT(epoch FROM min(s.xact_start)), EXTRACT(epoch FROM now()))
           ->  Nested Loop  (cost=0.00..2.74 rows=1 width=8) (actual time=1.658..1.659 rows=0 loops=1)
                 Output: s.xact_start
                 Join Filter: (d.oid = s.datid)
                 ->  Seq Scan on pg_catalog.pg_database d  (cost=0.00..1.07 rows=1 width=4) (actual time=0.026..0.028 rows=1 loops=1)
                       Output: d.oid, d.datname, d.datdba, d.encoding, d.datlocprovider, d.datistemplate, d.datallowconn, d.dathasloginevt, d.datconnlimit, d.datfrozenxid, d.datminmxid, d.dattablespace, d.datcollate, d.datctype, d.datlocale, d.daticurules, d.datcollversion, d.datacl
                       Filter: (d.datname = current_database())
                       Rows Removed by Filter: 4
                 ->  Function Scan on pg_catalog.pg_stat_get_activity s  (cost=0.00..1.63 rows=3 width=16) (actual time=1.628..1.628 rows=0 loops=1)
                       Output: s.datid, s.pid, s.usesysid, s.application_name, s.state, s.query, s.wait_event_type, s.wait_event, s.xact_start, s.query_start, s.backend_start, s.state_change, s.client_addr, s.client_hostname, s.client_port, s.backend_xid, s.backend_xmin, s.backend_type, s.ssl, s.sslversion, s.sslcipher, s.sslbits, s.ssl_client_dn, s.ssl_client_serial, s.ssl_issuer_dn, s.gss_auth, s.gss_princ, s.gss_enc, s.gss_delegation, s.leader_pid, s.query_id
                       Function Call: pg_stat_get_activity(NULL::integer)
                       Filter: ((s.state <> 'idle'::text) AND (s.application_name = ANY ('{zitadel_es_pusher_,zitadel_es_pusher,zitadel_es_pusher_<INSTANCE_ID>}'::text[])))
                       Rows Removed by Filter: 42
   ->  Sort  (cost=290.58..290.60 rows=9 width=361) (actual time=4.685..4.685 rows=0 loops=1)
         Output: events2.created_at, events2.event_type, events2.sequence, events2."position", events2.payload, events2.creator, events2.owner, events2.instance_id, events2.aggregate_type, events2.aggregate_id, events2.revision, events2.in_tx_order
         Sort Key: events2."position", events2.in_tx_order
         Sort Method: quicksort  Memory: 25kB
         ->  Index Scan using es_projection on eventstore.events2  (cost=0.70..290.43 rows=9 width=361) (actual time=4.616..4.617 rows=0 loops=1)
               Output: events2.created_at, events2.event_type, events2.sequence, events2."position", events2.payload, events2.creator, events2.owner, events2.instance_id, events2.aggregate_type, events2.aggregate_id, events2.revision, events2.in_tx_order
               Index Cond: ((events2.instance_id = '<INSTANCE_ID>'::text) AND (events2.aggregate_type = ANY ('{project,instance,org}'::text[])) AND (events2.event_type = ANY ('{project.application.added,project.application.changed,project.application.deactivated,project.application.reactivated,project.application.removed,project.removed,project.application.config.api.added,project.application.config.api.changed,project.application.config.api.secret.changed,project.application.config.api.secret.updated,project.application.config.oidc.added,project.application.config.oidc.changed,project.application.config.oidc.secret.changed,project.application.config.oidc.secret.updated,project.application.config.saml.added,project.application.config.saml.changed,org.removed,instance.removed}'::text[])) AND (events2."position" > <POSITION>) AND (events2."position" < (InitPlan 1).col1))
 Query Identifier: -8254550537132386499
 Planning Time: 2.864 ms
 Execution Time: 5.414 ms
 ```

(cherry picked from commit e36f402e09)
2025-03-13 16:51:46 +01:00
Silvan
e770569413 fix(eventstore): optimise query hints for event filters (#9497)
(cherry picked from commit b578137139)
2025-03-12 16:05:03 +01:00
Livio Spring
a47f4a30fa fix(OIDC): back channel logout work for custom UI (#9487)
# Which Problems Are Solved

When using a custom / new login UI and an OIDC application with
registered BackChannelLogoutUI, no logout requests were sent to the URI
when the user signed out.
Additionally, as described in #9427, an error was logged:
`level=error msg="event of type *session.TerminateEvent doesn't
implement OriginEvent"
caller="/home/runner/work/zitadel/zitadel/internal/notification/handlers/origin.go:24"`

# How the Problems Are Solved

- Properly pass `TriggerOrigin` information to session.TerminateEvent
creation and implement `OriginEvent` interface.
- Implemented `RegisterLogout` in `CreateOIDCSessionFromAuthRequest` and
`CreateOIDCSessionFromDeviceAuth`, both used when interacting with the
OIDC v2 API.
- Both functions now receive the `BackChannelLogoutURI` of the client
from the OIDC layer.

# Additional Changes

None

# Additional Context

- closes #9427

(cherry picked from commit ed697bbd69)
2025-03-12 16:05:00 +01:00
Livio Spring
5ad33e717b fix(token exchange): properly return an error if membership is missing (#9468)
# Which Problems Are Solved

When requesting a JWT (`urn:ietf:params:oauth:token-type:jwt`) to be
returned in a Token Exchange request, ZITADEL would panic if the `actor`
was not granted the necessary permission.

# How the Problems Are Solved

Properly check the error and return it.

# Additional Changes

None

# Additional Context

- closes #9436

(cherry picked from commit e6ce1af003)
2025-03-12 16:04:57 +01:00
Max Peintner
6256908181 fix(login): passkey setup when pressing "Enter" key on login form (#9485)
# Which Problems Are Solved

When registering passkeys or u2f methods as second factor, some users
pressed the "Enter" key, rather than clicking the submit button. This
method has bypassed the execution of the device registration and
encoding scripts, resulting in the form being submitted without the
necessary encoded values.

# How the Problems Are Solved

This PR ensures that device registration is always executed and the
required information are submitted in the form regardless of pressing
"Enter" or clicking the button.

# Additional Changes

None

# Additional Context

- closes #6592
- closes #2910

(cherry picked from commit 27b319bd98)
2025-03-12 16:04:54 +01:00
Silvan
e82e53bd45 fix(cmd): clarify notification config handling (#9459)
# Which Problems Are Solved

If configuration `notifications.LegacyEnabled` is set to false when
using cockroachdb as a database Zitadel start does not work and prints
the following error: `level=fatal msg="unable to start zitadel"
caller="github.com/zitadel/zitadel/cmd/start/start_from_init.go:44"
error="can't scan into dest[0]: cannot scan NULL into *string"`

# How the Problems Are Solved

The combination of the setting and cockraochdb are checked and a better
error is provided to the user.

# Additional Context

- introduced with https://github.com/zitadel/zitadel/pull/9321

(cherry picked from commit 92f0cf018f)
2025-03-06 07:41:17 +01:00
Iraq
1c121ec230 fix(permission): sql error in cmd/setup/49/01-permitted_orgs_function.sql (#9465)
# Which Problems Are Solved

SQL error in `cmd/setup/49/01-permitted_orgs_function.sql`

# How the Problems Are Solved

Updating `cmd/setup/49/01-permitted_orgs_function.sql`

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9461

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
(cherry picked from commit 3c57e325f7)
2025-03-06 07:41:17 +01:00
Max Peintner
52bb9ca3a5 fix(login): improve webauthn error handling (#9474)
This PR improves error handling around webauthn functions in the login.

(cherry picked from commit a82f5805b6)
2025-03-06 07:41:17 +01:00
Iraq
122b5f3e0e fix(actions): Linking external account doesn't trigger flow "External Authentication" on "Post Authentication" on first login (#9397)
# Which Problems Are Solved

When logging in using exeternal idp to Zitadel using SAML with action
setup to override existing Zitadel account attributes (first name/last
name/display name ect) with that of external linked idp account as
described here:
https://zitadel.com/docs/guides/integrate/identity-providers/azure-ad-saml#add-action-to-map-user-attributes,
does not happen until the next time the user logs in using the external
idp

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9133

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
Co-authored-by: Livio Spring <livio.a@gmail.com>
(cherry picked from commit b0fa974419)
2025-03-06 07:41:16 +01:00
Livio Spring
bc019a3447 Merge branch 'main' into next 2025-03-04 13:46:48 +01:00
Livio Spring
e399d90f6f fix: correct required permissions on admin APIs
# Which Problems Are Solved

ZITADEL's Admin API, intended for managing ZITADEL instances, contains 12 HTTP endpoints that are unexpectedly accessible to authenticated ZITADEL users who are not ZITADEL managers. The most critical vulnerable endpoints relate to LDAP configuration:
- /idps/ldap
- /idps/ldap/{id}

By accessing these endpoints, unauthorized users could:
- Modify ZITADEL's instance LDAP settings, redirecting all LDAP login attempts to a malicious server, effectively taking over user accounts.
- Expose the original LDAP server's password, potentially compromising all user accounts.

The following endpoints are also affected by IDOR vulnerabilities, potentially allowing unauthorized modification of instance settings such as languages, labels, and templates:
- /idps/templates/_search
- /idps/templates/{id}
- /policies/label/_activate
- /policies/label/logo
- /policies/label/logo_dark
- /policies/label/icon
- /policies/label/icon_dark
- /policies/label/font
- /text/message/passwordless_registration/{language}
- /text/login/{language}

Please checkout https://github.com/zitadel/zitadel/security/advisories/GHSA-f3gh-529w-v32x for more information.

# How the Problems Are Solved

- Required permission have been fixed (only instance level allowed)

# Additional Changes

None

# Additional Context

- resolves https://github.com/zitadel/zitadel/security/advisories/GHSA-f3gh-529w-v32x

(cherry picked from commit d9d8339813)
2025-03-04 12:13:45 +01:00
Livio Spring
c6a9665b2b fix: prevent panic when retrieving session by id in internal calls (#9442)
# Which Problems Are Solved

#9110 introduced more possibilities to search for "own" sessions. Due to
this the permission checks for retrieving a session had to be updated
accordingly. Internal calls, such as retrieving them for sending
notifications do not require a permission, but the code was not properly
adjusted and thus could lead to panics.

# How the Problems Are Solved

- Properly handled (do not require) permission check for internal only
calls when retrieving the session by id.

# Additional Changes

None

# Additional Context

- needs backports to 2.68.x, 2.69.x, 2.70.x
- closes zitadel/devops#117

(cherry picked from commit 4e1868e9bb)
2025-03-04 12:13:11 +01:00
Livio Spring
d9d8339813 Merge commit from fork 2025-03-04 08:49:02 +01:00
Fabienne Bühler
a5bc68fdad fix: add session roles to iam owner (#9413)
# Which Problems Are Solved

Currently I am not able to run the new login with a service account with
an IAM_OWNER role.
As the role is missing some permissions which the LOGIN_CLIENT role does
have

# How the Problems Are Solved

Added session permissions to the IAM_OWNER

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-04 06:41:06 +00:00
Thatcher
25c1d4b55f docs: Clarify how to add the users' organization claim (#9441)
I looked _several times_ to find how to add the organization name or ID
to the JWT. but kept overlooking this.

The claim `urn:zitadel:iam:user:resourceowner` claim adds the users'
organization. But because the word organization was missing from the
description, it was very much non-obvious.

This fix proposes a clarification of the description to clarify this.

# Which Problems Are Solved
- It is hard to find how to add the organization name or ID to the JWT.
but kept overlooking this.

# How the Problems Are Solved

- This patch proposes a clarification of the description to clarify that
by users `resourceowner`. we mean org.

# Additional Context

- This changes documentation only.

Co-authored-by: Fabienne Bühler <fabienne@zitadel.com>
2025-03-03 17:29:23 +01:00
Max Peintner
9f0d933bf6 docs: update oidc-playground link (#8529)
The new OIDC playground is deployed on
https://zitadel.com/oidc-playground.
This PR updates the relative links in the docs

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-03 13:54:00 +00:00
Livio Spring
4e1868e9bb fix: prevent panic when retrieving session by id in internal calls (#9442)
# Which Problems Are Solved

#9110 introduced more possibilities to search for "own" sessions. Due to
this the permission checks for retrieving a session had to be updated
accordingly. Internal calls, such as retrieving them for sending
notifications do not require a permission, but the code was not properly
adjusted and thus could lead to panics.

# How the Problems Are Solved

- Properly handled (do not require) permission check for internal only
calls when retrieving the session by id.

# Additional Changes

None

# Additional Context

- needs backports to 2.68.x, 2.69.x, 2.70.x
- closes zitadel/devops#117
2025-03-03 11:24:52 +01:00
Ramon
b0f70626c8 fix: load metadata using user service (#9429)
# Which Problems Are Solved
- #9382 "When I log in and get to my user profile page, I get an empty
error message at the top:"

# How the Problems Are Solved
load metadata using user service

# Additional Changes
- The roles observable returns an empty array instead of never emiting
- Small refactorings in app.component.ts because at first I thought the
errors stems from there.
- Added withLatestFromSynchronousFix RXJS operator because
withLatestFrom has confusing behavior when used in synchronous contexts.
Why this operator is needed is described here:
https://github.com/ReactiveX/rxjs/issues/7068

# Additional Context
- Closes #9382
2025-03-03 09:24:55 +01:00
Livio Spring
4df3b6492c chore: API guidelines (#9340)
# Which Problems Are Solved

There were no guideline to how design future APIs and their endpoints.
The V3 documentation was to specific and targeted towards internal
stakeholders.
This PR is intended as base and kept to the minimum. If more details or
additional guideline or rules are needed, they will be added in the
future.

# How the Problems Are Solved

- Removed the V3 description and corresponding examples.
- Provided general guideline for the design of APIs, which includes the
structure, naming, versioning, error handling and more.

# Additional Changes

None

# Additional Context

closes #9184

---------

Co-authored-by: Maximilian <mpa@zitadel.com>
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-02-27 11:30:39 +00:00
Silvan
444f682e25 refactor(notification): use new queue package (#9360)
# Which Problems Are Solved

The recently introduced notification queue have potential race conditions.

# How the Problems Are Solved

Current code is refactored to use the queue package, which is safe in
regards of concurrency.

# Additional Changes

- the queue is included in startup
- improved code quality of queue

# Additional Context

- closes https://github.com/zitadel/zitadel/issues/9278
2025-02-27 11:49:12 +01:00
Ramon
83614562a2 fix: Create Human V1 (#9425)
# Which Problems Are Solved
- Correctly load Avatar on first load

# How the Problems Are Solved
- The Avatar issue was mostly due to how we resolved the current user, I
changed this behaviour

# Additional Changes
- Removed V2 create human code till seperate page is finished
- Remove Console Use V2 API feature flag from features page (till new
page is added)

# Additional Context
- Partially fixes #9382
- This will get implemented next week
https://github.com/zitadel/zitadel/issues/9382#issuecomment-2681347477
2025-02-27 09:31:48 +01:00
Kenta Yamaguchi
3c471944c2 chore(i18n): add ORG_USER_SELF_MANAGER (#9392)
# Which Problems Are Solved

The i18n element `ORG_USER_SELF_MANAGER` is missing a translation.

# How the Problems Are Solved

Added translations for `ORG_USER_SELF_MANAGER` in each language.

Please note that the translations were generated using Copilot, so they
may not be entirely accurate (I'm only confident that they are correct
for English and Japanese). I appreciate any corrections or improvements.

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-02-27 06:50:40 +00:00
Kenta Yamaguchi
696b00e329 chore(i18n): add ORG_SETTINGS_MANAGER (#9393)
# Which Problems Are Solved

The i18n element `ORG_SETTINGS_MANAGER` is missing a translation.

# How the Problems Are Solved

Added translations for `ORG_SETTINGS_MANAGER` in each language.

Please note that the translations were generated using Copilot, so they
may not be entirely accurate (I'm only confident that they are correct
for English and Japanese). I appreciate any corrections or improvements.
2025-02-27 06:26:53 +00:00
Tim Möhlmann
e670b9126c fix(permissions): chunked synchronization of role permission events (#9403)
# Which Problems Are Solved

Setup fails to push all role permission events when running Zitadel with
CockroachDB. `TransactionRetryError`s were visible in logs which finally
times out the setup job with `timeout: context deadline exceeded`

# How the Problems Are Solved

As suggested in the [Cockroach documentation](timeout: context deadline
exceeded), _"break down larger transactions"_. The commands to be pushed
for the role permissions are chunked in 50 events per push. This
chunking is only done with CockroachDB.

# Additional Changes

- gci run fixed some unrelated imports
- access to `command.Commands` for the setup job, so we can reuse the
sync logic.

# Additional Context

Closes #9293

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-02-26 16:06:50 +00:00
Elio Bischof
77499ce603 docs(login,v2): describe cloud usage (#9404)
# Which Problems Are Solved

Users don't have the information that and how they can use the new login
without customization on their Zitadel cloud domain.

# How the Problems Are Solved

The How-to is described alongside customized deployment with Vercel
how-to.

This section is changed:
https://docs-git-docs-login-v2-cloud-zitadel.vercel.app/docs/guides/integrate/login/hosted-login#step-by-step-guide

# Additional Context

- Closes https://github.com/zitadel/DevOps/issues/98

---------

Co-authored-by: Fabienne Bühler <fabienne@zitadel.com>
2025-02-26 16:46:42 +01:00
Fabienne Bühler
4375c065b2 docs: add fast api example (#9418)
# Which Problems Are Solved

The community implemented an example for integrating fastAPI with
Zitadel.
So far this example has not been listed.

# How the Problems Are Solved

The example is now listed
Disclaimer is added, that some of the examples are not maintained by us
2025-02-26 14:54:52 +00:00
Elio Bischof
75a30229c1 docs: update rate limit policy (#9405)
# Which Problems Are Solved

The rate limit policy doesn't match the actually applied rate limits.

# How the Problems Are Solved

The rate limit policy is updated.

# Additional Conext

- https://github.com/caos/infra/pull/1141

---------

Co-authored-by: Florian Forster <florian@zitadel.com>
2025-02-26 14:20:21 +00:00
Silvan
1ce68a562b docs(benchmarks): v2.70.0 (#9416)
# Which Problems Are Solved

No benchmarks for v2.70.0 were provided so far.

# How the Problems Are Solved

Benchmarks added

# Additional changes

- it's now possible to plot multiple charts, one chart per `metric_name`
2025-02-26 14:03:20 +00:00
KevinRSI
70bddceda8 fix(user fields): missing creationDate in details (#9250)
# Which Problems Are Solved

The `creationDate` property on user search V2 endpoint was missing

# How the Problems Are Solved

Added property in v2 `object.proto` and in the function creating the
details on each call

# Additional Changes
- none
# Additional Context
closes #8552

---------

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
2025-02-26 13:00:04 +00:00
Livio Spring
8f88c4cf5b feat: add PKCE option to generic OAuth2 / OIDC identity providers (#9373)
# Which Problems Are Solved

Some OAuth2 and OIDC providers require the use of PKCE for all their
clients. While ZITADEL already recommended the same for its clients, it
did not yet support the option on the IdP configuration.

# How the Problems Are Solved

- A new boolean `use_pkce` is added to the add/update generic OAuth/OIDC
endpoints.
- A new checkbox is added to the generic OAuth and OIDC provider
templates.
- The `rp.WithPKCE` option is added to the provider if the use of PKCE
has been set.
- The `rp.WithCodeChallenge` and `rp.WithCodeVerifier` options are added
to the OIDC/Auth BeginAuth and CodeExchange function.
- Store verifier or any other persistent argument in the intent or auth
request.
- Create corresponding session object before creating the intent, to be
able to store the information.
- (refactored session structs to use a constructor for unified creation
and better overview of actual usage)

Here's a screenshot showing the URI including the PKCE params:


![use_pkce_in_url](https://github.com/zitadel/zitadel/assets/30386061/eaeab123-a5da-4826-b001-2ae9efa35169)

# Additional Changes

None.

# Additional Context

- Closes #6449
- This PR replaces the existing PR (#8228) of @doncicuto. The base he
did was cherry picked. Thank you very much for that!

---------

Co-authored-by: Miguel Cabrerizo <doncicuto@gmail.com>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
2025-02-26 12:20:47 +00:00
MAHANTH-wq
32ec7d0aa9 feat(\internal): sorting column on ListIAMMembersRequest (#9203)
# Which Problems Are Solved


SortingColumn functionality on system API ListIAMMembers

SortingColumn functionality on admin API ListIAMMembers

# How the Problems Are Solved

I have added enum MemberFieldColumnName in` member.proto `file ,
consists of names of the columns on which the request can be sorted.
    MEMBER_FIELD_NAME_UNSPECIFIED = 0;
    MEMBER_FIELD_NAME_USER_ID=1;
    MEMBER_FIELD_NAME_CREATION_DATE = 2;
    MEMBER_FIELD_NAME_CHANGE_DATE=3;
    MEMBER_FIELD_NAME_USER_RESOURCE_OWNER=4
I have added field Sorting Column for ListIAMMembersRequest in`
system.proto` file. I have added field Sorting Column for
ListIAMMembersRequest in` admin.proto` file.
I have modified ListIAMMembersRequestToQuery function in file
`internal/api/grpc/system/instance_converter.go `to include sorting
column in the query.SearchRequest{}.
I have modified ListIAMMembersRequestToQuery function in file
`internal/api/grpc/admin/iam_member_converter.go ` to include sorting
column in the query.SearchRequest{}.

# Additional Changes

Replace this example text with a concise list of additional changes that
this PR introduces, that are not directly solving the initial problem
but are related.
For example:
- The docs explicitly describe that the property XY is mandatory
- Adds missing translations for validations.

# Additional Context

Replace this example with links to related issues, discussions, discord
threads, or other sources with more context.
Use the Closing #issue syntax for issues that are resolved with this PR.
- Closes https://github.com/zitadel/zitadel/issues/5063
- Discussion #xxx
- Follow-up for PR #xxx
-
https://discordapp.com/channels/927474939156643850/1329872809488416789/1329872809488416789

---------

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
2025-02-26 11:48:51 +01:00
Max Peintner
6379d6a0ed docs(typescript-login): cleanup proxy and environment setup (#9406)
This PR removes the need to set the service user id as environment
variable.

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-02-25 06:50:07 +00:00
Livio Spring
911200aa9b feat(api): allow Device Authorization Grant using custom login UI (#9387)
# Which Problems Are Solved

The OAuth2 Device Authorization Grant could not yet been handled through
the new login UI, resp. using the session API.
This PR adds the ability for the login UI to get the required
information to display the user and handle their decision (approve with
authorization or deny) using the OIDC Service API.

# How the Problems Are Solved

- Added a `GetDeviceAuthorizationRequest` endpoint, which allows getting
the `id`, `client_id`, `scope`, `app_name` and `project_name` of the
device authorization request
- Added a `AuthorizeOrDenyDeviceAuthorization` endpoint, which allows to
approve/authorize with the session information or deny the request. The
identification of the request is done by the `device_authorization_id` /
`id` returned in the previous request.
- To prevent leaking the `device_code` to the UI, but still having an
easy reference, it's encrypted and returned as `id`, resp. decrypted
when used.
- Fixed returned error types for device token responses on token
endpoint:
- Explicitly return `access_denied` (without internal error) when user
denied the request
  - Default to `invalid_grant` instead of `access_denied`
- Explicitly check on initial state when approving the reqeust
- Properly handle done case (also relates to initial check) 
- Documented the flow and handling in custom UIs (according to OIDC /
SAML)

# Additional Changes

- fixed some typos and punctuation in the corresponding OIDC / SAML
guides.
- added some missing translations for auth and saml request

# Additional Context

- closes #6239

---------

Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2025-02-25 07:33:13 +01:00
Iraq
f2e82d57ac fix: adding code to test ListUsers with and without permission_check_v2 flag set (#9383)
# Which Problems Are Solved

Enhancing `v2/ListUsers()` tests by adding code to run all test with and
without `permission_check_v2` flag set

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9356

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
2025-02-24 16:29:51 +00:00
Ramon
70234289cf fix: v2 user console errors (#9386)
# Which Problems Are Solved

- Fixed filtering in overview
- Only get users from current organization
- Use V2 api to get auth user

# How the Problems Are Solved

Added the organization filter to the List queries
Get current User ID from ID Token to get auth user by id

# Additional Changes

Refactored the UserList

# Additional Context
- Closes #9382
2025-02-21 14:57:09 +01:00
Iraq
9aad207ee4 fix(permissions): return current user when calling ListUsers() when user does not have permissions (#9374)
# Which Problems Are Solved

When running `ListUsers()` with no permissions, the calling user shoud
be returned

# How the Problems Are Solved

Added additional clause to SQL search statement 

# Additional Changes

n/a

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9355

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
2025-02-20 15:39:48 +00:00
Stefan Benz
93466055ee test: add sink functionality for idp intents (#9116)
# Which Problems Are Solved

New integration tests can't use command side to simulate successful
intents.

# How the Problems Are Solved

Add endpoints to only in integration tests available sink to create
already successful intents.

# Additional Changes

None

# Additional Context

Closes #8557

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-02-20 13:27:20 +01:00
Kenta Yamaguchi
9b35b98cae fix(i18n): add some missing elements in Japanese (#9353)
# Which Problems Are Solved

Some i18n elements are not translated in Japanese yet.

# How the Problems Are Solved

Add some missing i18n elements to `console/src/assets/i18n/ja.json`,
`internal/api/ui/login/static/i18n/ja.yaml`, and
`internal/static/i18n/ja.yaml`.

More details are following:
- `console/src/assets/i18n/ja.json`
  - `POLICY.PRIVATELABELING.BACKGROUNDCOLOR`
  - `POLICY.PRIVATELABELING.PRIMARYCOLOR`
  - `POLICY.PRIVATELABELING.WARNCOLOR`
  - `POLICY.PRIVATELABELING.FONTCOLOR`
  - `POLICY.LOGIN_TEXTS.MESSAGE_TEXTS.TYPES.IU`
  - `IDP.CREATE.APPLE.TITLE`
  - `IDP.CREATE.APPLE.DESCRIPTION`
  - `IDP.CREATE.SAML.TITLE`
  - `IDP.CREATE.SAML.DESCRIPTION`
  - `IDP.APPLE.TEAMID`
  - `IDP.APPLE.KEYID`
  - `IDP.APPLE.PRIVATEKEY`
  - `IDP.APPLE.UPDATEPRIVATEKEY`
  - `IDP.APPLE.UPLOADPRIVATEKEY`
  - `IDP.KEYMAXSIZEEXCEEDED`
  - `IDP.SAML.METADATAXML`
  - `IDP.SAML.METADATAURL`
  - `IDP.SAML.BIDNING`
  - `IDP.SAML.SIGNEDREQUEST`
  - `IDP.SAML.NAMEIDFORMAT`
  - `IDP.SAML.TRANSIENTMAPPINGATTRIBUTENAME`
  - `IDP.SAML.TRANSIENTMAPPINGATTRIBUTENAME_DESC`
  - `SMTP.LIST.DIALOG.TEST_TITLE`
  - `SMTP.LIST.DIALOG.TEST_DESCRIPTION`
  - `SMTP.LIST.DIALOG.TEST_EMAIL`
  - `SMTP.LIST.DIALOG.TEST_RESULT`
- `internal/api/ui/login/static/i18n/ja.yaml`
  - `LDAP.Title`
  - `LDAP.Description`
  - `LDAP.LoginNameLabel`
  - `LDAP.PasswordLabel`
  - `LDAP.NextButtonText`
  - `PasswordChange.Footer`
  - `Footer.SupportEmail`
  - `Errors.User.AlreadyExists`
  - `Errors.User.Profile.NotFound`
  - `Errors.User.Profile.NotChanged`
  - `Errors.User.Profile.Empty`
  - `Errors.User.Profile.FirstNameEmpty`
  - `Errors.User.Profile.LastNameEmpty`
  - `Errors.User.Profile.IDMissing`
  - `Errors.User.Email.NotFound`
  - `Errors.User.Email.Invalid`
  - `Errors.User.Email.AlreadyVerified`
  - `Errors.User.Email.NotChanged`
  - `Errors.User.Email.Empty`
  - `Errors.User.Email.IDMissing`
  - `Errors.User.Phone.NotFound`
  - `Errors.User.Phone.Invalid`
  - `Errors.User.Phone.AlreadyVerified`
  - `Errors.User.Phone.Empty`
  - `Errors.User.Phone.NotChanged`
  - `Errors.User.Address.NotFound`
  - `Errors.User.Address.NotChanged`
  - `Errors.User.Username.AlreadyExists`
  - `Errors.User.Username.Reserved`
  - `Errors.User.Username.Empty`
  - `Errors.Org.LoginPolicy.RegistrationNotAllowed`
- `internal/static/i18n/ja.yaml`
  - `Errors.SMSConfig.NotExternalVerification`
  - `Errors.User.Profile.Empty`
  - `Errors.User.Profile.FirstNameEmpty`
  - `Errors.User.Profile.LastNameEmpty`
  - `Errors.User.Email.Empty`
  - `Errors.User.Email.IDMissing`
  - `Errors.User.Phone.Empty`
  - `Errors.User.Phone.NotChanged`
  - `Errors.User.Username.Empty`
  - `Errors.Org.LabelPolicy.NotFound`
  - `Errors.Org.LabelPolicy.NotChanged`
  - `EventTypes.project.application.oidc.key.added`
  - `EventTypes.project.application.oidc.key.removed`

# Additional Changes

- Change some order of the elements in `internal/static/i18n/ja.yaml`
  - `EventTypes.user.human.password.change.sent`
  - `EventTypes.user.human.password.hash.updated`
- Remove an element which is not used in the `us.yaml` from
`internal/static/i18n/ja.yaml`
  - `EventTypes.user.phone.removed`
- Correct a translation in `internal/static/i18n/ja.yaml`
  - `EventTypes.user.human.password.change.sent`
2025-02-19 12:51:53 +00:00
Livio Spring
dff9ce7257 Merge branch 'main' into next 2025-02-18 11:47:51 +01:00
Iraq
5bbb953ffb feat(ldap): adding root ca option to ldap config (#9292)
# Which Problems Are Solved

Adding ability to add a root CA to LDAP configs

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/7888

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
2025-02-18 10:06:50 +00:00
Fabienne Bühler
d7332d1ac4 docs: remove user schema and user api documentation from v3 api version (#9358)
# Which Problems Are Solved

Due to other priorities we decided to push the implementation of user
schema back in the roadmap.
As the feature is not yet complete and can't be tested/used, the API
Docs V3 for user schema and user lead to confusion.

# How the Problems Are Solved

I removed the api docs for user schema and user v3 from the sidenav for
the moment

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-02-18 07:11:52 +00:00
Ramon
3042bbb993 feat: Use V2 API's in Console (#9312)
# Which Problems Are Solved
Solves #8976

# Additional Changes
I have done some intensive refactorings and we are using the new
@zitadel/client package for GRPC access.

# Additional Context
- Closes #8976

---------

Co-authored-by: Max Peintner <peintnerm@gmail.com>
2025-02-17 19:25:46 +01:00
Stefan Benz
ad225836d5 chore: deprecated skip-dirs move to exclude-dirs (#9370)
Moved the deprecated skip-dirs option to the exclude-dirs
2025-02-17 16:06:55 +00:00
Iraq
0cb0380826 feat: updating eventstore.permitted_orgs sql function (#9309)
# Which Problems Are Solved

Performance issue for GRPC call `zitadel.user.v2.UserService.ListUsers`
due to lack of org filtering on `ListUsers`

# Additional Context

Replace this example with links to related issues, discussions, discord
threads, or other sources with more context.
Use the Closing #issue syntax for issues that are resolved with this PR.
- Closes https://github.com/zitadel/zitadel/issues/9191

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2025-02-17 11:55:28 +02:00
Fabienne Bühler
7c96dcd9a2 docs: update readme with features and new login gif (#9357)
# Which Problems Are Solved

SCIM 2.0 Server was not listed in the readme of Zitadel
New Login was not listed

# How the Problems Are Solved

Added scim 2.0 as a feature to the list
Added new login, including a gif to showcase
2025-02-14 10:48:16 +00:00
Tim Möhlmann
92265dca21 fix(setup): use template for in_tx_order type (#9346)
# Which Problems Are Solved

Systems running with PostgreSQL before Zitadel v2.39 are likely to have
a wrong type for the `in_tx_order` column in the `eventstore.event2`
table. The migration at the time used the `event_sequence` as default
value without typecast, which results in a `bigint` type for that
column. However, when creating the table from scratch, we explicitly
specify the type to be `integer`.

Starting from Zitadel v2.67 we use a Pl/PgSQL function to push events.
The function requires the types from `eventstore.events2` to the same as
the `select` destinations used in the function. In the function
`in_tx_order` is also expected to by of `integer` type.

CochroachDB systems are not affected because `bigint` is an alias to the
`int` type. In other words, CockroachDB uses `int8` when specifying type
`int`. Therefore the types already match.

# How the Problems Are Solved

Retrieve the actual column type currently in use. A template is used to
assign the type to the `ordinality` column returned as `in_tx_order`.

# Additional Changes

- Detailed logging on migration failure

# Additional Context

- Closes #9180

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
(cherry picked from commit bcc6a689fa)
2025-02-13 17:15:36 +01:00
Livio Spring
464a4718df fix(oidc / login v2): always us login v2 if x-zitadel-login-client header is sent (#9336)
# Which Problems Are Solved

As reported in #9311, even when providing a `x-zitadel-login-client`
header, the auth request would be created as hosted login UI / V1
request.
This is due to a change introduced with #9071, where the login UI
version can be specified using the app configuration.
The configuration set to V1 was not considering if the header was sent.

# How the Problems Are Solved

- Check presence of `x-zitadel-login-client` before the configuration.
Use later only if no header is set.

# Additional Changes

None

# Additional Context

- closes #9311
- needs back ports to 2.67.x, 2.68.x and 2.69.x

(cherry picked from commit e7a73eb6b1)
2025-02-13 17:11:56 +01:00
Stefan Benz
49de5c61b2 feat: saml application configuration for login version (#9351)
# Which Problems Are Solved

OIDC applications can configure the used login version, which is
currently not possible for SAML applications.

# How the Problems Are Solved

Add the same functionality dependent on the feature-flag for SAML
applications.

# Additional Changes

None

# Additional Context

Closes #9267
Follow up issue for frontend changes #9354

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-02-13 16:03:05 +00:00