3627 Commits

Author SHA1 Message Date
Fabienne Bühler
febf410d80
docs: Update customer portal docs/screenshots (#9604)
# Which Problems Are Solved

With the recent updates of our customer portal design, our onboarding
guide and customer portal docs were outdated.

# How the Problems Are Solved

- Updated screenshots of customer portal
- Updated screenshots of onboarding in management console
- Updated quickstarts with changes that have been made in the onbaording

---------

Co-authored-by: Maximilian <mpa@zitadel.com>
2025-03-25 18:20:49 +01:00
Livio Spring
57bfecf7f7
fix(actions): correctly handle api.v1.appendUserGrant (#9598)
# Which Problems Are Solved

It was not possible to use the `api.v1.appendUserGrant` function in the
`postCreation` trigger action as documented.

# How the Problems Are Solved

- Correctly initialize the javascript / Goja function
- Added `projectID` and `projectGrantID` (as documented), but kept
`projectId` and `projectGrantId` (for backwards compatibility) when
mapping the object in the `appendUserGrant` function

# Additional Changes

None

# Additional Context

- A customer reached out to support regarding this issue.
- requires back port to 2.70.x
2025-03-25 11:07:54 +00:00
Iraq
596970cc7e
chore: updating go to 1.24 (#9507)
# Which Problems Are Solved

Updating go to 1.24

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
2025-03-25 07:01:29 +00:00
Livio Spring
e7c7f9b800
fix: correct event type for permission removed (#9626)
# Which Problems Are Solved

When we recently changed some permission for the `SYSTEM_OWNER` role on
QA, we noticed that there we multiple `permission.added` even when we
removed specific permissions.

# How the Problems Are Solved

Fixed the event type when removing permissions.

# Additional Changes

None

# Additional Context

Noticed when rolling out some changes on QA
2025-03-24 17:00:44 +00:00
Livio Spring
54e513f312
fix(console): pass verification code for phone verification (#9616)
# Which Problems Are Solved

While testing totally unrelated issues, I noticed that the phone
verification in Console didn't work anymore.

# How the Problems Are Solved

Pass the verification `code` entered by the user to the API.

# Additional Changes

None

# Additional Context

probably relates to https://github.com/zitadel/zitadel/pull/9312
2025-03-24 16:10:47 +01:00
Livio Spring
c2c02492b9
chore: update dependencies (#9614)
# Which Problems Are Solved

Multiple dependencies used by the Zitadel backend are outdated.

# How the Problems Are Solved

Update all direct dependencies (apart from the following two) to the
latest version:
- github.com/go-webauthn/webauthn: see
https://github.com/zitadel/zitadel/issues/9615
- github.com/nicksnyder/go-i18n/v2 (v2.5.0 / 2.5.1 prevent the use of
reserved keys such as `description`:
https://github.com/nicksnyder/go-i18n/releases/tag/v2.5.0)

# Additional Changes

None

# Additional Context

None
2025-03-24 12:06:35 +02:00
Tim Möhlmann
c3258ecf78
chore(deps): upgrade go mods from zitadel organization (#9601)
# Which Problems Are Solved

Outdated dependencies foir packages developed by Zitadel.
Some of them included important security updates from sub-dependencies.

# How the Problems Are Solved

Upgrade all packages under `github.com/zitadel/*` to the latest released
version.

# Additional Changes

- The `github.com/superseriousbusiness/exifremove` was removed from
Github. We copied the cached go mod code to
https://github.com/zitadel/exifremove and use this module now.

# Additional Context

- Related to https://github.com/zitadel/zitadel/issues/9422
- Closes https://github.com/zitadel/zitadel/issues/9443

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-24 06:03:24 +00:00
Elio Bischof
103b190af7
docs(self-hosting): use postgres for deployment docs (#9571)
# Which Problems Are Solved

The Kubernetes and Knative deployment docs suggest to depend on
CockroachDB installations even though we sunset the CockroachDB support
with the upcoming major version. This can be annoying for users who
create new environments using CockroachDB.

# How the Problems Are Solved

- The Kubernetes deployment is removed and points to examples in the
chart repo directy. This removes redundancies that are prone to getting
outdated without notice.

- The Knative deployment uses commands to deploy a PostgreSQL
StatefulSet instead of a CockroachDB StatefulSet. The DB command from
the Knative Tutorial is used, as users are likely to be familiar with
the tutorials configuration already. The static Kubernetes YAML files
for the DB as well as for the Zitadel Knative service are removed
altogether, as they are prone to getting outdated without notice and
don't serve any purpose.

# Additional Changes

- The outdated and boring video guide for Knative is removed.
- The Knative configuration is changed, so the first-time login becomes
easier which improves DevX.
- The current docker compose file doesn't work, this PR fixes it and
upgrades the used Postgres to v17.

# Additional Context

- Closes https://github.com/zitadel/zitadel-charts/issues/322
- Replaces https://github.com/zitadel/zitadel/pull/9540

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-03-21 15:49:37 +00:00
Ramon
8b1b9cbb98
fix: allow native applications to use https:// on loopback redirect addresses (#9073)
# Which Problems Are Solved

- The current validation for native redirect URIs does not allow HTTPS
loopback addresses.

# How the Problems Are Solved

- Enhanced the validation logic to permit HTTPS loopback addresses,
ensuring that developers can use these addresses without encountering
validation errors.
- Updated zitadel/oidc to latest version

# Additional Context

- Closes #4091
- This pr need to be closed first in our OIDC lib:
https://github.com/zitadel/oidc/pull/691

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-21 13:55:16 +00:00
Miro Trisc
e4c12864e5
feat(crypto): support md5 salted for imported password hashes (#9596)
# Which Problems Are Solved

Allow verification of imported salted passwords hashed with plain md5.

# How the Problems Are Solved

- Upgrade passwap to
[v0.7.0](https://github.com/zitadel/passwap/releases/tag/v0.7.0)
- Add md5salted as a new verifier option in `defaults.yaml`

# Additional Changes

- go version and libraries updated  (required by passkey v0.7.0)
- secrets.md verifiers updated  
- configuration verifiers updated 
- added MD5salted and missing MD5Plain to test cases
2025-03-21 12:25:52 +00:00
Harsha Reddy
dc64e35128
feat: Make service name configurable for Metrics and Tracing (#9563)
# Which Problems Are Solved

The service name is hardcoded in the metrics code. Making the service
name to be configurable helps when running multiple instances of
Zitadel.

The defaults remain unchanged, the service name will be defaulted to
ZITADEL.

# How the Problems Are Solved

Add a config option to override the name in defaults.yaml and pass it
down to the corresponding metrics or tracing module (google or otel)

# Additional Changes
NA

# Additional Context
NA
2025-03-20 09:35:54 +00:00
Faey
833e654a07
feat(actions): Add refresh token to post authentication action context (#9493)
# Which Problems Are Solved

- Refresh Tokens issued by third party authentication providers are lost

# How the Problems Are Solved

- Allows the existing post authentication action to capture the refresh
token

# Additional Changes

- Docs updated to reflect the new property

# Additional Context

- Partially addresses #7851 by allowing the refresh token to be
captured.

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
2025-03-20 09:00:36 +00:00
Stefan Benz
352fa6aa6f
fix: milestone multiple results per instance domain instead of primary instance domain (#9564)
# Which Problems Are Solved

The milestones query returns multiple results for every milestone for
every instance domain.

# How the Problems Are Solved

Corrected where condition on milestone query.

# Additional Changes

None

# Additional Context

None

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-20 07:57:36 +00:00
Stefan Benz
5486ef2627
test: correct sorting of scim list users integration tests (#9568)
# Which Problems Are Solved

SCIM integration test failed sometimes, as ListUsers with usernames-sort
was not reliable if the asserted list is not sorted as well.

# How the Problems Are Solved

Sort the list of results in the sorted integration tests.

# Additional Changes

None

# Additional Context

Relates to
https://github.com/zitadel/zitadel/actions/runs/13922326003/job/38960759621
2025-03-20 07:05:01 +00:00
Stefan Benz
5ca76af779
test: correct notifications integration test with eventual consistency (#9569)
# Which Problems Are Solved

Quota notification integration test failed sometimes due to eventual
consistency issues, which resulted in calls which should have been
counted to the quota not being added. This resulted in flaky integration
tests as the expected API calls to be limited were executed normally.

# How the Problems Are Solved

As there is no API call to query the currently applied Quota, there was
a sleep added as a last effort, to give some time that the event gets
processed into the projection.

# Additional Changes

None

# Additional Context

Related to
https://github.com/zitadel/zitadel/actions/runs/13922326003/job/38959595055

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-20 07:47:19 +01:00
Maximilian
988146b2ad
fix: sidebar imports (#9589)
# Which Problems Are Solved

Running local development of the docs didn't work due to errors with
sidebar imports.

# How the Problems Are Solved

The imports held the sidebar items in a "default" object. Changed the
imports

# Additional Changes

removed some comments
2025-03-19 18:21:41 +02:00
Max Peintner
83108d1dc3
fix(console): Implement generic feature toggle (#9516)
This PR implements a component which is used to render the feature
settings in a generic way.
All features besides`loginV2` and `improvedPerformance` are rendered.

Note: The feature flags are not autogenerated as the console needs
descriptions for the respective features and there are multiple types
where additional fields like text input is required

Closes #9090

---------

Co-authored-by: conblem <mail@conblem.me>
2025-03-19 15:52:09 +00:00
Ramon
b418ea75bb
feat: create human user v2 page (#9506)
# Which Problems Are Solved
Allows users to be created using the V2 User API

# How the Problems Are Solved
I added a seperate V2 create user page with the new code using the new
apis.

# Additional Changes
I did some refactorings arround our interceptors as they used an
obselete syntax.
The password complexity form takes the Buf definitions.

# Additional Context
- Closes #9430

---------

Co-authored-by: Max Peintner <peintnerm@gmail.com>
2025-03-19 13:27:59 +01:00
Iraq
11c9be3b8d
chore: updating projections.idp_templates6 to projections.idp_templates7 (#9517)
# Which Problems Are Solved

This was left out as part of
https://github.com/zitadel/zitadel/pull/9292

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

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
2025-03-18 16:23:12 +01:00
Livio Spring
f1f500d0e7
chore: use crdb 24.3 (#9558)
# Which Problems Are Solved

E2E tests in pipelines started to fail randomly. While debugging it, i
noticed that we use the `latest` tag of cockroach's docker image. They
tagged 25.1 as latest yesterday.

# How the Problems Are Solved

Since we drop support for CRDB with version 3 as there are anyway
multiple issues with various versions, I pinned the docker image tag to
`latest-v24.3`.

# Additional Changes

None

# Additional Context

relates to https://github.com/zitadel/zitadel/actions/runs/13917603587
and https://github.com/zitadel/zitadel/actions/runs/13904928050
2025-03-18 10:52:38 +01:00
Stefan Benz
6cd5e717a4
chore: correct integration tests for query endpoints eventual consistent (#9554)
# Which Problems Are Solved

Integration tests for OIDC service failed irregularly.

# How the Problems Are Solved

Add eventual consistent checks for querying endpoints to the integration
tests for the OIDC service.

# Additional Changes

None

# Additional Context

None
2025-03-18 08:16:48 +01:00
Harsha Reddy
599850e7e8
fix: reduce cardinality in metrics and tracing for unknown paths (#9523)
# Which Problems Are Solved
Zitadel should not record 404 response counts of unknown paths (check
`/debug/metrics`).
This can lead to high cardinality on metrics endpoint and in traces.

```
GOOD http_server_return_code_counter_total{method="GET",otel_scope_name="",otel_scope_version="",return_code="200",uri="/.well-known/openid-configuration"} 2
GOOD http_server_return_code_counter_total{method="GET",otel_scope_name="",otel_scope_version="",return_code="200",uri="/oauth/v2/keys"} 2
BAD http_server_return_code_counter_total{method="GET",otel_scope_name="",otel_scope_version="",return_code="404",uri="/junk"} 2000
```

After
```
GOOD http_server_return_code_counter_total{method="GET",otel_scope_name="",otel_scope_version="",return_code="200",uri="/.well-known/openid-configuration"} 2
GOOD http_server_return_code_counter_total{method="GET",otel_scope_name="",otel_scope_version="",return_code="200",uri="/oauth/v2/keys"} 2
```

# How the Problems Are Solved

This PR makes sure, that any unknown path is recorded as `UNKNOWN_PATH`
instead of the actual path.

# Additional Changes

N/A

# Additional Context

On our production instance, when a penetration test was run, it caused
our metric count to blow up to many thousands due to Zitadel recording
404 response counts.

Next nice to have steps, remove 404 timer recordings which serve no
purpose

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Livio Spring <livio@zitadel.com>
2025-03-17 17:37:59 +01:00
Kenta Yamaguchi
d57fa819cb
chore: Replace deprecated io/ioutil functions with recommended alternatives (#9542)
# Which Problems Are Solved

- The `io/ioutil` package was deprecated in Go 1.16.  
  - Reference: https://go.dev/doc/go1.16#ioutil  

# How the Problems Are Solved

- Replaced deprecated functions with their recommended alternatives:  
  - `ioutil.ReadFile` → `os.ReadFile`  
  - `ioutil.ReadAll` → `io.ReadAll`  
  - `ioutil.NopCloser` → `io.NopCloser`
2025-03-17 13:17:14 +00:00
Livio Spring
19f022e1cf
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
2025-03-17 11:13:24 +00:00
Kenta Yamaguchi
9767519db6
chore: Update contrib.rocks link in README.md (#9543)
# Which Problems Are Solved

- The current contrib.rocks link (`https://contrib.rocks`) does not
directly preview the contributor graph for the zitadel/zitadel
repository.

# How the Problems Are Solved

- Updated the contrib.rocks link to
`https://contrib.rocks/preview?repo=zitadel/zitadel`, which directly
shows the contributor graph for this repository.
2025-03-17 10:59:19 +00:00
Elio Bischof
9bbc3c48fc
docs: show proxy link only once (#9537)
# Which Problems Are Solved

The reverse proxy docs have too many links to the third party proxy
provider. This is noisy and might result in unintentional redirects.
![image
(1)](https://github.com/user-attachments/assets/3127f3bc-a6e1-47c5-a565-4f68ce1650d3)


# How the Problems Are Solved

The link to the proxy provider is only shown on the first occurence of
the provider name instead of all occurences.
2025-03-14 11:52:09 +01:00
Livio Spring
61c4b1c3fd
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
2025-03-14 06:05:45 +00:00
Silvan
e36f402e09
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
 ```
2025-03-13 16:50:23 +01:00
Stefan Benz
5eb3a543e8
fix: add permission check for saml request query (#9520) 2025-03-12 21:53:16 +01:00
Livio Spring
d527a1c824
feat(console): specify login UI for SAML apps (#9486)
# Which Problems Are Solved

Users were not yet able to specify (and test) the new login UI or
self-hosted login UI for SAML applications through Console.

# How the Problems Are Solved

Added the configuration for SAML apps (as already available for OIDC) in
Console.

# Additional Changes

None

# Additional Context

- closes #9354
2025-03-12 12:37:43 +00:00
Silvan
b578137139
fix(eventstore): optimise query hints for event filters (#9497) 2025-03-12 09:44:06 +00:00
Livio Spring
ed697bbd69
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
2025-03-11 14:19:09 +00:00
Livio Spring
e6ce1af003
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
2025-03-11 11:14:18 +00:00
Elio Bischof
bae45ee159
docs(cloud login v2): use default login url (#9477)
# Which Problems Are Solved

We configured the default base URL for the hosted v2 login to
`/ui/v2/login`. However, the docs still instruct readers to configure
the URL explicitly. This is unneccesary mental overhead and a risk of
self-DOS due to typos.

# How the Problems Are Solved

The docs instruct readers to not configure the base URL in order to use
the default.

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-03-07 15:52:23 +00:00
Livio Spring
ead9fde16a
docs: improve api guidelines (#9478)
# Which Problems Are Solved

The API guidelines were not completely accurate on how we want to check
permissions.

# How the Problems Are Solved

Made the description clearer and added examples.

# Additional Changes

Improved the error code example as initially intended in #9340
and added notes about the `limits` for listing resources.

# Additional Context

popped up in PR review of https://github.com/zitadel/zitadel/pull/9445
2025-03-07 14:19:09 +00:00
Max Peintner
27b319bd98
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
2025-03-07 09:51:39 +00:00
Silvan
92f0cf018f
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
2025-03-06 06:26:33 +00:00
Iraq
3c57e325f7
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>
2025-03-05 21:48:20 +00:00
Max Peintner
a82f5805b6
fix(login): improve webauthn error handling (#9474)
This PR improves error handling around webauthn functions in the login.
2025-03-05 14:47:48 +00:00
Iraq
b0fa974419
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>
2025-03-05 11:21:23 +01:00
Mateusz Wolanowski
007c96d54a
feat: add Romanian language support (#9388)
# Which Problems Are Solved

- Lack of support for the Romanian language in the application.

# How the Problems Are Solved

- Added translations for the Romanian language

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-03-04 17:09:21 +00:00
Stefan Benz
0c87a96e2c
feat: actions v2 for functions (#9420)
# Which Problems Are Solved

Actions v2 are not executed in different functions, as provided by the
actions v1.

# How the Problems Are Solved

Add functionality to call actions v2 through OIDC and SAML logic to
complement tokens and SAMLResponses.

# Additional Changes

- Corrected testing for retrieved intent information
- Added testing for IDP types
- Corrected handling of context for issuer in SAML logic

# Additional Context

- Closes #7247 
- Dependent on https://github.com/zitadel/saml/pull/97
- docs for migration are done in separate issue:
https://github.com/zitadel/zitadel/issues/9456

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-03-04 11:09:30 +00: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