mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-29 18:42:15 +00:00
6fa5c0e662756d34b933a4eedc4a1ab8da72e596
169
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6fa5c0e662 |
Merge commit from fork
* feat(login): add shared enrollment authorization guard Introduce assertSessionAuthorizedForEnrollment, a single gate that decides whether a session may enroll a new authenticator: it requires a verified primary factor (password, passkey or IDP) on a non-expired session, or, for onboarding, a user with no auth methods plus a prior user-verification check. This mirrors the gate previously inlined only in registerPasskeyLink, which is refactored to reuse the shared helper. It is the foundation for gating the remaining credential-enrollment entry points (GHSA-45f2-5q3r-xgg6). Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(login): require authentication before WebAuthn/U2F enrollment addU2F and verifyU2F registered a credential for any session that resolved to a user id, including a bare identify-only session created by merely submitting a login name. An unauthenticated attacker who knew a victim's login name could therefore attach an attacker-controlled authenticator to the victim's account and then complete a login as the victim. Both actions now run assertSessionAuthorizedForEnrollment before registering or verifying, so an unauthenticated session is rejected and no credential is persisted. GHSA-45f2-5q3r-xgg6 Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(login): require authentication before TOTP/OTP enrollment verifyTOTP and the otp/<method>/set page activated a TOTP/OTP factor for any session with a user id, and the u2f/set page rendered the registration form without an authorization check. An identify-only session could thus enroll a second factor on a victim's account. Gate all of them with assertSessionAuthorizedForEnrollment. The setup pages now render the unknown-context/error state instead of enrolling when the session is not authorized. Also guard the method value in the OTP set page, since the added guard branch removes the control-flow narrowing the previous throw provided. GHSA-45f2-5q3r-xgg6 Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(login): require authentication before legacy (V1) passwordless enrollment The V1 passwordless registration handlers began and verified passwordless setup for any auth request that carried a user id, without checking that a first factor had been verified. An unauthenticated attacker could submit a victim's login name and then POST directly to the passwordless prompt/init endpoints to plant an attacker-controlled passkey, then log in as the victim. Add passwordlessSetupAllowed / CheckPasswordlessSetupAllowed, which permit enrollment only for a legitimate onboarding user (PasswordlessInitRequired) or an auth request whose first factor is already verified, and call it before BeginPasswordlessSetup and VerifyPasswordlessSetup. The verify path is also bound to authReq.UserID instead of the attacker-controllable form field, so a credential cannot be redirected onto a different account. The init-code (mail/onboarding) path is unchanged. GHSA-45f2-5q3r-xgg6 Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(login): remove never-active legacy (V1) authReq passwordless setup path Supersedes the runtime gate added in the previous commit. Maintainer review (Livio, the original author) and investigation confirmed the auth-request based passwordless *setup* path in the legacy login was a never-active leftover: - The passwordless prompt page (passwordless_prompt.html) has no submit button and no script; it only tells the user to complete setup via the emailed link (the PasswordlessButtonText/NextButtonText/SkipButtonText i18n keys are unused). - Legitimate onboarding for a PasswordlessInitRequired user goes through the emailed init-code flow (authReq == nil, BeginPasswordlessInitCodeSetup / VerifyPasswordlessInitCodeSetup), which is untouched. - The authReq branch (handlePasswordlessPrompt -> BeginPasswordlessSetup / VerifyPasswordlessSetup) was reachable only by a crafted direct POST — the GHSA-45f2-5q3r-xgg6 attack. Rather than gate the dead path, remove it entirely, eliminating the attack surface: - delete handlePasswordlessPrompt and the POST /login/passwordless/prompt route (keep renderPasswordlessPrompt: the informational "use your emailed link" page for PasswordlessRegistrationPromptStep), - make renderPasswordlessRegistration / checkPasswordlessRegistration use only the init-code path, - drop the now-unused AuthRequestRepo.BeginPasswordlessSetup / VerifyPasswordlessSetup (and the interface decls) and the passwordlessPromptUrl template helper; the underlying HumanAddPasswordlessSetup / HumanHumanPasswordlessSetup commands remain (used by the auth-API self-service and the v2 passkey APIs). A crafted POST to /login/passwordless/init carrying an authRequestID but no valid code now falls through to the init-code path and fails. GHSA-45f2-5q3r-xgg6 Co-Authored-By: Claude Opus 4.8 <[email protected]> * check for userverified true as well, cleanup return message --------- Co-authored-by: Claude Opus 4.8 <[email protected]> Co-authored-by: Max Peintner <[email protected]> |
||
|
|
3e94047da7 |
fix(login): redirect to external IdP after domain discovery regardless of registration policy (#12369)
Closes #12021 Closes #12023 # Which Problems Are Solved When a user entered an email on the login page and domain discovery resolved the correct organization, the login flow failed to redirect to the configured external IdP. Instead it returned a "user not found" error or showed the registration page. This happened because the "user not found" decision tree in `sendLoginname` only attempted an IdP redirect when `allowLocalAuthentication` was disabled. If local auth was enabled but `allowRegister` was `false`, the IdP check was skipped entirely. # How the Problems Are Solved Combined the IdP redirect logic into a single block that triggers when either local authentication is disabled **or** domain discovery resolved an organization. The registration policy (`allowRegister`) now only affects local account creation and no longer gates external IdP authentication. --------- Co-authored-by: Copilot Autofix powered by AI <[email protected]> Co-authored-by: Livio Spring <[email protected]> |
||
|
|
56f4798ed3 |
Merge commit from fork
* add mfa check to session validity check * change session check to check for already set up mfa methods * lint * improve naming * test changes * cleanup continueWithSession fcn |
||
|
|
6bd46c5fb6 |
feat(login): idp userAction oneof (#12433)
Closes #11369 # Which Problems Are Solved During SSO login with an external IdP, Actions v2 lets you manipulate the `RetrieveIdentityProviderIntent` response to shape the user that ZITADEL creates or updates. There was an inconsistency between the two flows: - **First login (user does not exist):** the response carried an `addHumanUser` object (mirroring the deprecated `AddHumanUser` API), which **does** allow setting user `metadata`. - **Subsequent logins (user exists):** the response carried an `updateHumanUser` object (mirroring the deprecated `UpdateHumanUser` API), which does **not** support metadata. As a result, actions could set metadata when creating a user but not when updating one. Customers doing SSO attribute mapping had to make a separate `SetUserMetadata` call on every subsequent login — extra latency and a non-atomic update. The proto/backend already gained a non-deprecated `user_action` oneof (`create_user` → `CreateUserRequest`, `update_user` → `UpdateUserRequest`, both supporting metadata), but the login app was still reading the deprecated flat fields, so the new capability was unreachable from the frontend. # How the Problems Are Solved Migrate the login app's IDP intent handler to consume the new `user_action` oneof, with a fallback to the deprecated fields so older API responses keep working during the transition. - **`zitadel.ts`** — added `createUser` / `updateUser` client wrappers calling the non-deprecated `UserService.CreateUser` / `UserService.UpdateUser` endpoints. - **`idp-intent.ts`** — added three helpers, each preferring `user_action` and falling back to `add_human_user` / `update_human_user`: - `resolveCreateUser` — flat read view for org resolution, required-field checks, and registration-form pre-fill. - `buildCreateUserRequest` — passes the action's `CreateUserRequest` through and injects the resolved `organizationId`; maps the deprecated flat payload into the nested shape on fallback. - `buildUpdateUserRequest` — builds an `UpdateUserRequest` **including metadata** (the fix); deliberately syncs only profile/email/phone/metadata (not username) to preserve existing auto-update behavior and avoid invalidating sessions. - Rewired all handlers (`handleUserExists`, `handleAutoLinking`, `handleAutoCreation`, `handleManualCreation`, `resolveOrganizationForUser`) to use these, and switched auto-create to read `CreateUserResponse.id`. - **Tests** — updated mocks/assertions to the new request shapes and added two cases exercising the `user_action` oneof with metadata (create + update). 817/817 login unit tests pass; no new type errors. # Additional Changes Updated the Actions v2 guide `guides/integrate/actions/testing-response-manipulation.mdx` (the unreleased/`latest` docs) to reflect the new response shape: - Go handler example now manipulates `resp.GetCreateUser()` / `resp.GetUpdateUser()` and appends `user.Metadata`, demonstrating metadata on both flows. - Both JSON payloads switched from `addHumanUser` to the nested `createUser` shape (`human.profile`, `human.email`, `human.idpLinks`, top-level `metadata`). - Added a Callout explaining first-login → `createUser` vs. existing-user → `updateUser`, that both support metadata, and that `addHumanUser`/`updateHumanUser` are deprecated. - Updated the claim-mapping debugging section to the new `createUser.human.profile.givenName` path. Versioned snapshots (`v4.12`/`v4.13`/`v4.14`) were intentionally left unchanged, as they document releases where the old API was correct. --------- Co-authored-by: gayathri <[email protected]> |
||
|
|
1e09b4fc19 |
feat(login): hu translations + I18n consistency v2 (#12447)
# Which Problems Are Solved Fixes i18n consistency and adds HU translations for login v2 # How the Problems Are Solved - Updated i18n files and added hu.json - Moved all translations to v2-default.json --------- Co-authored-by: Dobos Zoltán <[email protected]> Co-authored-by: Liam Neville <[email protected]> |
||
|
|
051506b5bb |
fix(login): prevent crash on a stale session cookie (#12423)
<!-- Please inform yourself about the contribution guidelines on submitting a PR here: https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr. Take note of how PR/commit titles should be written and replace the template texts in the sections below. Don't remove any of the sections. It is important that the commit history clearly shows what is changed and why. Important: By submitting a contribution you agree to the terms from our Licensing Policy as described here: https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions. --> # Which Problems Are Solved The `sessions` cookie lifetime is independent of Zitadel's server-side session validity, so a cookie can reference an invalid session. In that case `getSession` throws `not_found` (QUERY-SFeaa). - `loadMostRecentSession` lets that error propagate instead of treating it as "no session", crashing the server render of every page that calls it without its own guard. - Most visibly, the "forgot password" flow landing on `/password/set` throws `[not_found] Session does not exist (QUERY-SFeaa)` (gRPC code 5, HTTP 404) and fails to render. - 12 of the 16 call sites are unguarded and share this crash. # How the Problems Are Solved Catch the error in `loadMostRecentSession` and return `undefined`, unifying "cookie references a dropped session" with the existing "no cookie" case. Every call site already handles an undefined session, either with a graceful fallback or by throwing its own explicit error. ```ts return getSession({ serviceConfig, sessionId: recent.id, sessionToken: recent.token }) .then((resp: GetSessionResponse) => resp.session) .catch((error) => { console.warn("[Session] Could not load most recent session", error); return undefined; }); ``` All `loadMostRecentSession` call sites — **Previous** = behaviour when the cookie referenced an invalid session; **Change** = what this PR does to that call site: | # | Call site | Change in this PR | Previous behaviour (invalid session) | New behaviour | |---|-----------|-------------------|--------------------------------------|---------------| | — | `lib/session.ts` — `loadMostRecentSession` | **Added `.catch` → `undefined`** (core fix) | Threw `not_found` to caller | Resolves to `undefined` | | 1 | `password/set/page.tsx` | none | **Crash** (the reported bug) | Falls back to login-name flow | | 2 | `password/change/page.tsx` | none | **Crash** | `undefined` → `failedLoading` alert if no user | | 3 | `passkey/set/page.tsx` | none | **Crash** | `undefined` → `userId` fallback / `unknownContext` | | 4 | `otp/[method]/page.tsx` | none | **Crash** | `undefined` → `unknownContext` alert | | 5 | `otp/[method]/set/page.tsx` | none | **Crash** (raw `ConnectError`) | `undefined` → own `throw "No session found"` | | 6 | `mfa/page.tsx` | none | **Crash** | `undefined` → `verify.noResults` alert | | 7 | `mfa/set/page.tsx` | none | **Crash** (raw `ConnectError`) | `undefined` → own `throw "Could not get user id from session"` | | 8 | `authenticator/set/page.tsx` | none | **Crash** (raw `ConnectError`) | `undefined` → own throw / `unknownContext` | | 9 | `signedin/page.tsx` | none | **Crash** | `undefined` → renders with `loginName` fallback | | 10 | `u2f/set/page.tsx` | none | **Crash** | `undefined` → `unknownContext` alert | | 11 | `u2f/page.tsx` | none | **Crash** | `undefined` → renders on `loginName` | | 12 | `lib/server/verify.ts` — `verifyTOTP` | none | **Crash** (raw `ConnectError`) | `undefined` → own `throw "No user id found in session."` | | 13 | `password/page.tsx` | **Removed redundant `try/catch`** | Caught locally → `undefined` | `undefined` — unchanged | | 14 | `verify/page.tsx` | **Removed redundant `.catch`** ¹ | Caught locally → `undefined` | `undefined` — unchanged | | 15 | `verify/success/page.tsx` | **Removed redundant `.catch`** | Caught locally → `undefined` | `undefined` — unchanged | | 16 | `passkey/page.tsx` | **Removed redundant `.catch`** (login-name path) | Caught locally → `undefined` | `undefined` — unchanged | Rows 1–12 were unguarded and crashed; the central change fixes them. Rows 13–16 already handled the error locally. # Additional Changes - This makes the four callers that wrapped the call in their own try/catch or `.catch` redundant, so remove that now-dead handling (password, verify, verify/success, passkey). - Add unit tests covering `loadMostRecentSession`: no cookie, success, and the stale-cookie rejection path. ¹ `verify/page.tsx`'s `.catch` also eagerly fetched `loginSettings`; that is already covered by the page's own lazy fetch, so behaviour is unchanged (one cosmetic edge case under `ignoreUnknownUsernames` with both `userId` and `loginName` present — no functional impact). # Additional Context - Session *expiry* alone does not trigger this: expired rows are not removed from the session projection, so `getSession` still returns them. The `not_found` specifically means the session was **removed** server-side (logout, admin/API termination, or a user/org/instance cascade) while the browser still held the cookie. - Mirrors the pattern upstream already applies inline in `verify/page.tsx` (*"ignore error, as we might not have a session yet"*), lifted to the shared function. - **Related issue (not in this PR):** the sibling `loadSessionById` helpers on the `?sessionId=` path (`passkey`, `otp`, `mfa`, `mfa/set`, `signedin`, `authenticator/set`, `u2f`) call `getSession` directly and share the same defect. Lower practical exposure (short-lived in-flow URLs; a clean logout clears the cookie), so a follow-up PR should lift those into a shared `loadSessionById` in `lib/session.ts`. - Prior art: upstream added an equivalent guard to verify/page.tsx in #11130, but the other call sites were never given the same treatment — this PR resolves that inconsistency at the source. Error trace: ``` {"level":"error","message":"⨯ Error [ConnectError]: [not_found] Session does not exist (QUERY-SFeaa)\n at R (.next/server/chunks/ssr/_0uqqxk7._.js:3:25490)\n at <unknown> (.next/server/chunks/ssr/_0uqqxk7._.js:3:26477)\n at next (.next/server/chunks/ssr/_0uqqxk7._.js:3:68112)\n at async (.next/server/chunks/ssr/_0uqqxk7._.js:10:31326)\n at async (.next/server/chunks/ssr/_0uqqxk7._.js:10:33734)\n at async Object.unary (.next/server/chunks/ssr/_0uqqxk7._.js:3:66838)\n at async Object.getSession (.next/server/chunks/ssr/_0uqqxk7._.js:3:72371)\n at async o (.next/server/chunks/ssr/[root-of-the-server]__0msfcq_._.js:1:7440) {\n rawMessage: 'Session does not exist (QUERY-SFeaa)',\n code: 5,\n metadata: Headers {\n 'accept-encoding': 'gzip',\n 'alt-svc': 'h3=\":443\"; ma=2592000',\n 'content-length': '240',\n 'content-type': 'application/json',\n date: 'Wed, 08 Jul 2026 09:06:09 GMT',\n 'strict-transport-security': 'max-age=63072000; includeSubDomains; preload',\n vary: 'Origin',\n },\n details: [\n {\n type: 'zitadel.v1.ErrorDetail',\n value: [Uint8Array],\n debug: [Object]\n }\n ],\n cause: undefined,\n httpStatus: 404,\n isUserError: true,\n digest: '634020356'\n}","timestamp":"2026-07-08T09:06:09.969Z"} ``` --------- Co-authored-by: Copilot Autofix powered by AI <[email protected]> Co-authored-by: Marco A. <[email protected]> Co-authored-by: Liam Neville <[email protected]> |
||
|
|
aa76c3be27 |
fix(login): keep submit button disabled/loading during password set r… (#12429)
<!-- Please inform yourself about the contribution guidelines on submitting a PR here: https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr. Take note of how PR/commit titles should be written and replace the template texts in the sections below. Don't remove any of the sections. It is important that the commit history clearly shows what is changed and why. Important: By submitting a contribution you agree to the terms from our Licensing Policy as described here: https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions. --> # Which Problems Are Solved - On Login V2 after a user sets their password during the invite or reset-password flows and clicks continue, there is a few seconds delay before the redirect occurs because no loading spinner is visible on the button during this delay users assume nothing happened and click continue again. - Clicking the button again starts a duplicate form submission. Since the first request was already fired the second request triggers an error right before the redirect from the first request completion creating a bad user experience # How the Problems Are Solved - Kept the `loading` state active `true` throughout the lifeline of the request which includes the 2-second database consistency delay and the subsequent `sendPassword` verification request. - Added `setLoading(false)` calls only in early-return error handling blocks and at the end of the redirection flow ensuring the button remains disabled and shows the spinner until the redirect happens. # Additional Changes - None # Additional Context - Solves #12416 Co-authored-by: Max Peintner <[email protected]> |
||
|
|
8b9d3637fd |
chore(deps): bump the go_modules group across 2 directories with 1 update (#12393)
Bumps the go_modules group with 1 update in the /apps/login/acceptance/idp/saml directory: [golang.org/x/crypto](https://github.com/golang/crypto). Bumps the go_modules group with 1 update in the /apps/login/acceptance/samlsp directory: [golang.org/x/crypto](https://github.com/golang/crypto). Updates `golang.org/x/crypto` from 0.36.0 to 0.52.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/crypto/commit/a1c0d9929856c8aba2b31f079340f00578eda803"><code>a1c0d99</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/crypto/commit/3c7c86938f4541c333d506f719388d9c42d4763d"><code>3c7c869</code></a> ssh: fix deadlock on unexpected channel responses</li> <li><a href="https://github.com/golang/crypto/commit/533fb3f7e4a5ae23f69d1837cd851d35ff5b76ce"><code>533fb3f</code></a> ssh: fix source-address critical option bypass</li> <li><a href="https://github.com/golang/crypto/commit/abbc44d451a6f9236a2bbd26cbcd4d0fec473da3"><code>abbc44d</code></a> ssh: fix incorrect operator order</li> <li><a href="https://github.com/golang/crypto/commit/e052873987615dc96fe67607a9a6adb76311344f"><code>e052873</code></a> ssh: fix infinite loop on large channel writes due to integer overflow</li> <li><a href="https://github.com/golang/crypto/commit/b61cf853a89d82cad68da5e12a6beca2116f8456"><code>b61cf85</code></a> ssh: enforce user presence verification for security keys</li> <li><a href="https://github.com/golang/crypto/commit/9c2cd33e8d96a96133fd6ff732510ebba539c2bd"><code>9c2cd33</code></a> ssh: enforce strict limits on DSA key parameters</li> <li><a href="https://github.com/golang/crypto/commit/890731877d85f71cfdc9554e7a27fec4684fc4c4"><code>8907318</code></a> ssh: reject RSA keys with excessively large moduli</li> <li><a href="https://github.com/golang/crypto/commit/ffd87b4878fa98ca2908ec534e1a410bf095a35e"><code>ffd87b4</code></a> ssh: fix panic when authority callbacks are nil</li> <li><a href="https://github.com/golang/crypto/commit/4e7a7384ecbc8d519f6f4c11b36fa9d761fc8946"><code>4e7a738</code></a> ssh: fix deadlock on unexpected global responses</li> <li>Additional commits viewable in <a href="https://github.com/golang/crypto/compare/v0.36.0...v0.52.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/crypto` from 0.36.0 to 0.52.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/crypto/commit/a1c0d9929856c8aba2b31f079340f00578eda803"><code>a1c0d99</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/crypto/commit/3c7c86938f4541c333d506f719388d9c42d4763d"><code>3c7c869</code></a> ssh: fix deadlock on unexpected channel responses</li> <li><a href="https://github.com/golang/crypto/commit/533fb3f7e4a5ae23f69d1837cd851d35ff5b76ce"><code>533fb3f</code></a> ssh: fix source-address critical option bypass</li> <li><a href="https://github.com/golang/crypto/commit/abbc44d451a6f9236a2bbd26cbcd4d0fec473da3"><code>abbc44d</code></a> ssh: fix incorrect operator order</li> <li><a href="https://github.com/golang/crypto/commit/e052873987615dc96fe67607a9a6adb76311344f"><code>e052873</code></a> ssh: fix infinite loop on large channel writes due to integer overflow</li> <li><a href="https://github.com/golang/crypto/commit/b61cf853a89d82cad68da5e12a6beca2116f8456"><code>b61cf85</code></a> ssh: enforce user presence verification for security keys</li> <li><a href="https://github.com/golang/crypto/commit/9c2cd33e8d96a96133fd6ff732510ebba539c2bd"><code>9c2cd33</code></a> ssh: enforce strict limits on DSA key parameters</li> <li><a href="https://github.com/golang/crypto/commit/890731877d85f71cfdc9554e7a27fec4684fc4c4"><code>8907318</code></a> ssh: reject RSA keys with excessively large moduli</li> <li><a href="https://github.com/golang/crypto/commit/ffd87b4878fa98ca2908ec534e1a410bf095a35e"><code>ffd87b4</code></a> ssh: fix panic when authority callbacks are nil</li> <li><a href="https://github.com/golang/crypto/commit/4e7a7384ecbc8d519f6f4c11b36fa9d761fc8946"><code>4e7a738</code></a> ssh: fix deadlock on unexpected global responses</li> <li>Additional commits viewable in <a href="https://github.com/golang/crypto/compare/v0.36.0...v0.52.0">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/zitadel/zitadel/network/alerts). </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
bc9333aef9 |
chore: update npm dependencies (#12375)
# Which Problems Are Solved - npm dependencies across the monorepo are behind current patch/minor releases. - Transitive dependencies are pinned to older versions by parent packages (karma, nx, @changesets/cli, etc.). - Console build fails after the Angular toolchain update because `angular.json` references assets outside the workspace root. # How the Problems Are Solved - Bumps `@angular/*` to `^21.2.17` in console. - Bumps `js-yaml` to `^4.2.0` in docs. - Bumps `concurrently` to `^10.0.3` in login. - Adds pnpm overrides for transitive deps that cannot be bumped directly (ws, undici, minimatch, esbuild, dompurify, qs, and others). # Additional Changes - Removes 10 overrides that are no longer needed after parent packages resolve to newer versions. - Updates 4 existing overrides (`tar`, `js-yaml`, `dompurify`, `brace-expansion`) to match current upstream ranges. - 2 low-severity findings remain via the abandoned `raw-loader` package in docs (peer dep resolution; no upstream fix without replacing `raw-loader`). - Fixes console build: replaced the `angular.json` asset glob `../apps/docs/public/img/tech` with a `prebuild` script that copies tech images into `src/assets/docs/img/tech`. **Verify at runtime that tech images on project grant / integration pages still load.** # Additional Context - Overrides remain where parent packages still pin older transitive versions. - The `angular.json` asset path issue predates this PR (not introduced by the Angular bump). --------- Co-authored-by: Livio Spring <[email protected]> |
||
|
|
1beabed8cf |
fix(login): preserve org domain suffix through account chooser navigation (#12304)
Closes #12024 # Which Problems Are Solved When the login flow is started with an `urn:zitadel:iam:org:domain:primary:{domain}` scope, the resolved domain suffix is lost if the user navigates through the account chooser (e.g. clicking "Use another account"). This causes the login to fail with "User not found" because the organization can no longer be resolved. Additionally, the `hideLoginNameSuffix` branding setting was never respected by the login app. # How the Problems Are Solved - Forward the `orgDomain` parameter through `gotoAccounts()` and the `/accounts` page, so it survives navigation to `/loginname` — the same way `organization` and `requestId` are already forwarded. - Respect `BrandingSettings.hideLoginNameSuffix`: when enabled, the `@domain.com` suffix is hidden from the input UI but still used internally for user search. --------- Co-authored-by: Livio Spring <[email protected]> |
||
|
|
e6aaea563e |
fix(login): migrate legacy Tailwind v4 opacity utilities and fix checkbox contrast color (#12360)
# Which Problems Are Solved 1. **Secondary button hover effect** was rendering a solid white/gray background instead of a subtle transparent overlay. The legacy `bg-opacity-*` utility (e.g. `hover:bg-gray-500 hover:bg-opacity-20`) doesn't compose with `bg-*` in Tailwind v4 — the opacity is ignored, leaving a solid color. The same issue affected `ring-opacity-*` and `border-opacity-*` across other components. 2. **Checkbox checkmark color** was hardcoded to white (`fill='white'` in the SVG), ignoring the theme's primary contrast color. On themes with a light primary color, the white checkmark was invisible. # How the Problems Are Solved 1. Migrated all legacy opacity utilities to the Tailwind v4 slash syntax: - `hover:bg-gray-500 hover:bg-opacity-20` → `hover:bg-gray-500/20` - `ring-primary-light-500 ring-opacity-60` → `ring-primary-light-500/60` - `focus:ring-opacity-50` + `focus:ring-indigo-200` → `focus:ring-indigo-200/50` - Removed redundant `border-opacity-20` where `border-black/10` was already applied 2. Replaced the static `background-image` checkbox SVG with a `mask-image` + `::after` pseudo-element approach. The checkmark color now uses `var(--theme-light-primary-contrast-500)` / `var(--theme-dark-primary-contrast-500)`, so it dynamically follows the theme's contrast color. --------- Co-authored-by: Livio Spring <[email protected]> |
||
|
|
92ea32a34d |
fix(login): use correct requestId with oidc_ prefix in Prompt.LOGIN + loginHint flow (#12376)
Closes #11946 # Which Problems Are Solved - OIDC redirect is broken when `Prompt.LOGIN` + `loginHint` is used — the user lands on `/signedin` instead of being redirected to the OIDC client's callback URL (fixes #11946) # How the Problems Are Solved - In `handleOIDCFlowInitiation`, the `Prompt.LOGIN` + `loginHint` code path was passing `authRequest.id` (raw ID without `oidc_` prefix) to `sendLoginname`. Without the prefix, `completeFlowOrGetUrl` does not recognize the flow as OIDC and falls through to the "Regular flow" path, redirecting to `/signedin` instead of calling `createCallback`. Fixed by using the `requestId` parameter which already carries the `oidc_` prefix. # Additional Changes - Standardized all request ID references in `handleOIDCFlowInitiation` to consistently use the `requestId` parameter instead of reconstructing it with `` `oidc_${authRequest.id}` ``. This eliminates the inconsistency that caused the bug and prevents similar issues in the future. - Removed a redundant `if (authRequest.id)` guard in the LDAP redirect path, since `requestId` is always present as a required parameter. - Added regression tests verifying that `sendLoginname` receives the `requestId` with the `oidc_` prefix in the `Prompt.LOGIN` + `loginHint` code path. |
||
|
|
f32acbfd24 |
fix(login): redirect to loginname instead of empty accounts page when org scope filters all sessions (#12346)
Closes #11914 # Which Problems Are Solved When an OIDC auth request includes an organization scope (`urn:zitadel:iam:org:id:{id}` or `urn:zitadel:iam:org:domain:primary:{domain}`), users with existing browser sessions from *other* organizations were shown an empty Account Selection page with no selectable accounts. The only option was to click "Add another account", adding a confusing and unnecessary extra step. This happened because the `/login` route checked `sessions.length` (all browser sessions, unfiltered) to decide whether to enter the "reuse existing session" branch. Inside that branch, `findValidSession` correctly filtered by organization and returned no match — but the fallback redirected to `/accounts`, which also filters by org and rendered empty. # How the Problems Are Solved Before deciding to redirect to `/accounts`, pre-filter sessions by the requested organization using the same logic already used by the accounts page and `findValidSession`. If no sessions are eligible for the target organization, redirect directly to `/loginname` instead. This applies to both the **default prompt** and **`prompt=select_account`** branches. For `select_account`, this matches the behavior of major OIDC providers like Google and Microsoft, which skip the account chooser and go straight to the login input when there are no sessions to select from. The OIDC spec describes `select_account` as enabling selection "amongst multiple accounts that they might have current sessions for" — showing an empty picker serves no purpose. --------- Co-authored-by: Copilot Autofix powered by AI <[email protected]> |
||
|
|
782133dbc7 |
fix(login): improve error handling for user registration (#12338)
# Which Problems Are Solved When the registerUser server action failed during registration, all errors from addHumanUser, createSessionWithRetry, and getUserByID propagated as uncaught exceptions to the client component's generic catch block, which always showed the same "Could not register user" message. This made it impossible to distinguish between user creation failures, session creation failures, and user lookup failures — both for end users and in server logs. # How the Problems Are Solved Added .catch() handlers on the three gRPC calls in registerUser that log the actual error and return null, allowing the existing null-check guard clauses to return step-specific error messages (couldNotCreateUser, couldNotCreateSession, userNotFound) through handleServerActionResponse. This gives users more specific feedback and provides server-side logging to narrow down the root cause of flaky signup failures. |
||
|
|
4dc89b499f |
fix(login): allow custom protocols for native apps again (#12332)
# Which Problems Are Solved - Native apps (mobile/desktop) use custom protocol schemes (e.g. `myapp://callback`, `io.zitadel.app://auth`) as OAuth/OIDC redirect URIs. The previous redirect-safety check in the login UI only allowed `http:`/`https:` absolute URLs, so these custom-scheme callbacks were wrongly rejected and native app login flows were broken. - Even for valid external redirects, `router.push()` triggers an RSC prefetch `fetch()` that is blocked by the CSP `connect-src 'self'` directive for non-same-origin URLs, so navigation to external/custom-protocol targets failed. - SAML and OIDC callback URLs returned from the backend were not consistently validated before being used for redirects/POSTs across the various flow entry points. # How the Problems Are Solved - Reworked `isSafeRedirectUri` to use `@braintree/sanitize-url` instead of a strict `http/https`-only allowlist. Custom protocol schemes are now permitted, while dangerous schemes (`javascript:`, `data:`, plus an explicit block of `file:`, `blob:`, `about:`) are still rejected. - Added `isExternalUrl` helper to distinguish internal relative paths (`/...`) from external/custom-protocol targets. - In `handleServerActionResponse`, external/custom-protocol redirects now navigate via `window.location.href` (full navigation) instead of `router.push()`, avoiding the CSP-blocked RSC prefetch. Internal paths continue to use `router.push()`. - Added consistent redirect-URI validation for SAML and OIDC callbacks across all relevant entry points (`oidc.ts`, `saml.ts`, `server/flow-initiation.ts` including the `prompt=none` path, and the SAML `samlData` POST case), blocking unsafe URLs with a clear warning and error response. # Additional Changes - Added `@braintree/sanitize-url` (`^7.1.2`) dependency to `apps/login` (`package.json` / `pnpm-lock.yaml`). - Added unit tests for `isExternalUrl` covering relative paths, absolute HTTP/HTTPS URLs, custom protocol schemes, and protocol-relative URLs. - Annotated the intentional `window.location.href` navigation with a CodeQL suppression comment, documenting that the URL is validated by `isSafeRedirectUri` beforehand. - Minor formatting cleanup in `console` JWT provider component. # Additional Context - This restores behavior that previously worked for native apps but regressed when redirect validation was tightened to `http`/`https` only. --------- Co-authored-by: Max Peintner <[email protected]> |
||
|
|
f9995ee39c |
fix: increase performance of ListUser by login name ignore case (#12350)
# Which Problems Are Solved Login v2 uses the `users.v2.ListUsers`-endpoint to get a user by login name. This query had an inefficient `WHERE`-clause. # How the Problems Are Solved Update the view and use a specific clause for this query. # Additional information Added in https://github.com/zitadel/zitadel/pull/10475 --------- Co-authored-by: Marco A. <[email protected]> Co-authored-by: Livio Spring <[email protected]> |
||
|
|
3a18cef281 |
fix: prevent double triggering of verification emails (#11995)
# Which Problems Are Solved This fixes a critical bug where initial verification emails (or invite codes) were occasionally sent twice, invalidating the first code and confusing users. Previously, the initial verification email was triggered via a `send=true` URL parameter executing inside a frontend useEffect exactly when the `/verify` page mounted. This was fragile and prone to race conditions caused by component remounts or partial hydration. # How the Problems Are Solved - Removed `send=true` from URL state and ripped out the doSend effect in `VerifyForm.tsx`. - Shifted execution strictly to the Next.js server. The email is now automatically dispatched via await `initialSendVerification(...)` during the POST requests (acting over `sendLoginname`, `register`, `password`, `passkeys`, and `idp`). - The login flow is now idempotent and robust against unintended frontend re-renders. - Refactored `checkEmailVerification()` to be async and updated the associated unit-test coverage (all tests passing). |
||
|
|
14874d6546 |
fix(login): Prevent IDP auto-creation failure when name fields are missing (#11070)
# Which Problems Are Solved
When using IDP auto-creation, the addHuman() call would fail if the IDP
didn't provide required profile fields (givenName or familyName),
resulting in a poor user experience.
# How the Problems Are Solved
Added validation before auto-creation to check if required profile
fields are present. If givenName or familyName is missing, users are now
redirected to the complete-registration page where they can manually
provide the missing information.
- Added profile field validation in CASE 4 (auto-creation) of
processIDPCallback
- Redirect to /idp/{provider}/complete-registration when required fields
are missing
- Pre-fill any available user data in the registration form
---------
Co-authored-by: David Skewis <[email protected]>
Co-authored-by: Florian Forster <[email protected]>
|
||
|
|
2397247925 |
fix(login): improve contrast of IDP processing message (#12309)
# Which Problems Are Solved This improves the contrast of the “Processing authentication...” message shown while Login V2 processes the IDP authentication flow. The previous style used text-gray-600 without a dark-mode variant. This color is hard-coded in the component and is not affected by the branding colors, so users may see low contrast depending on the active theme/background. This PR updates the message text to use a higher-contrast light/dark color pair. --------- Co-authored-by: Max Peintner <[email protected]> Co-authored-by: Max Peintner <[email protected]> |
||
|
|
76fd6d859d |
Merge commit from fork
* fix: ensure external user's email is verified before auto-linking * fix linking |
||
|
|
239620f112 |
fix(login): center text for generic IDP buttons without icons (#12211)
Closes #12182 # Which Problems Are Solved Generic IDP buttons (OIDC, SAML, LDAP, JWT) used pl-20 to approximate icon offset alignment, but since they have no icon, the text appeared misaligned compared to branded IDPs (Google, Microsoft, Apple). # How the Problems Are Solved Replaced the left-padding hack with centered text so generic IDP names display cleanly within the button. before: <img width="392" height="290" alt="Screenshot 2026-05-28 at 12 03 21" src="https://github.com/user-attachments/assets/64c4e8eb-caec-4742-b61c-e3b0c5093dd7" /> after: <img width="392" height="289" alt="Screenshot 2026-05-28 at 12 07 27" src="https://github.com/user-attachments/assets/d1faf1f4-0aab-475f-8801-15b461e15da4" /> |
||
|
|
f691851d32 | Merge commit from fork | ||
|
|
e94d4c3986 |
feat(crypto): FIPS 140-3 compliant build and runtime checks (#12233)
# Which Problems Are Solved Enable FIPS 140-3 compliant build. # How the Problems Are Solved - Add runtime config validation, if the FIPS flag is enabled fail the application when a non-compliant hasher is used, or throw a warning when a legacy verifier is used - Add a build matrix for FIPS certified build: - Go binary is built with `GOFIPS140=certified` - Login container uses a separate base: [ubi9](https://catalog.redhat.com/en/software/containers/ubi9/ubi/615bcf606feffc5384e8452e) from redhat which provides a FIPS certified OpenSSL (used by NodeJS TLS stack) - Non-FIPS images where already pushed to both Github Container Registry and Google Artifact Repository (GAR). Fips images are only pushed to the GAR. - Tag versions are suffixed `-fips`. So on release the following images will be additionally available: ``` europe-docker.pkg.dev/zitadel-common/zitadel-repo/zitadel-login:vX.Y.Z-fips europe-docker.pkg.dev/zitadel-common/zitadel-repo/zitadel:vX.Y.Z-fips-debug europe-docker.pkg.dev/zitadel-common/zitadel-repo/zitadel:vX.Y.Z-fips ``` # Other changes - Bumb Go toolchain. At least v1.25.10 is required for a GOFIPS140=certified setting. # Additional Context - Closes https://github.com/zitadel/zitadel/issues/4335 - Build [test run](https://github.com/zitadel/zitadel/actions/runs/27253916052) pushing FIPS and non-FIPS images |
||
|
|
fdafb95a63 |
fix(login): load custom font from branding settings and allow in CSP (#12279)
Closes #11200 # Which Problems Are Solved Custom fonts uploaded via the branding/label policy were not supported. # How the Problems Are Solved - The login now correctly applies the branding settings, based on the organization context - Use the absolute `fontUrl` from the branding API directly in the `@font-face` `src`, matching how logo and icon assets are already loaded via absolute URLs. - Add the Zitadel service URL to the `font-src` CSP directive so the browser permits loading the cross-origin font. # Additional Changes - Updated CSP tests to reflect the new `font-src` behavior. |
||
|
|
4459a1380c |
fix(login): accept IDP sessions on passkey registration (#12275)
# Which Problems Are Solved The local `isSessionValid` in `passkeys.ts` only checked `password` and `webAuthN` factors, so sessions authenticated via an external IDP (`intent` factor) were treated as invalid. This caused a "You have to authenticate" error when redirecting to `/passkey/set` after IDP login. # How the Problems Are Solved Added `session.factors.intent.verifiedAt` to the validity check, consistent with the canonical `isSessionValid` in `session.ts`. |
||
|
|
b27fdfc28c |
chore: update dependencies (#12242)
# Which Problems Are Solved Fixes multiple high-severity Dependabot alerts for transitive dependencies (axios, protobufjs, systeminformation, tmp, fast-uri, @babel/plugin-transform-modules-systemjs). # How the Problems Are Solved **Direct dependency updates:** - `@opentelemetry/*` 0.217 → 0.218 in login (new otlp-transformer dropped protobufjs as direct dep) - `posthog-js` 1.374 → 1.380 in console (dropped the OpenTelemetry/protobufjs chain entirely) **pnpm overrides** for remaining transitive deps that can't be updated via their parents (all pulled by the gRPC stack, Cypress, karma, nx, or ajv): - `axios` → ≥1.17.0 (prototype pollution, proxy bypass) - `protobufjs` → ≥7.5.7 / ≥8.0.2 (code injection, prototype pollution, DoS) - `systeminformation` → ≥5.31.6 (command injection) - `tmp` → ≥0.2.6 (path traversal) - `fast-uri` → ≥3.1.2 (path traversal, host confusion) **Benchmark:** refreshed `package-lock.json` to resolve @babel and fast-uri alerts. |
||
|
|
cdc6c43d09 |
fix: update dependencies (#12216)
# Which Problems Are Solved Fixes open vulnerabilities # How the Problems Are Solved Updated npm/js dependencies across console, new login v2, and docs Based on https://github.com/zitadel/zitadel/pull/12164 --------- Co-authored-by: conblem <[email protected]> Co-authored-by: Livio Spring <[email protected]> |
||
|
|
fc6e2a0f05 |
fix(login): retry logic for session creation after registration on NotFound (#12189)
After user registration, the backend projections may not be up to date
yet when the Login UI immediately tries to create a session. This
results in a `QUERY-Dfbg2` ("User could not be found") error even though
the user was created successfully.
This adds retry logic with backoff (500ms/1s/2s, up to 3 attempts)
around `createSessionAndUpdateCookie` in the registration flow. Only
`NotFound` errors are retried — other errors are thrown immediately.
Closes #12173
---------
Co-authored-by: Livio Spring <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
|
||
|
|
404c23834a |
fix(login): redirect to email verification when forced MFA has no visible factors (#12060)
# Which Problems Are Solved When MFA is enforced with only Email OTP as a second factor, new users hit a dead end on the MFA setup screen. The `ChooseSecondFactorToSetup` component hides Email OTP when `emailVerified` is `false`, and if email verification was skipped earlier in the flow (e.g. `EMAIL_VERIFICATION` env not set to `"true"`), no MFA options are visible and the user cannot proceed. # How the Problems Are Solved In the MFA setup server component (`mfa/set/page.tsx`), before rendering, detect when forced MFA has no visible second factors because all configured factors require verification the user hasn't completed. When Email OTP is configured but the user's email is unverified, redirect to `/verify` with `send=true` so a verification code is sent immediately. After the user verifies their email, the existing flow in `verify.ts` calls `checkMFAFactors` which redirects back to `/mfa/set` — where Email OTP is now visible since `emailVerified` is `true`. The redirect pattern follows the existing precedent in `authenticator/set/page.tsx`. # Additional Changes None # Additional Context - Closes #11536 --------- Co-authored-by: Max Peintner <[email protected]> |
||
|
|
96b3f3dd35 |
fix(login): apply custom request headers from environment variable in proxy (#12144)
Closes #12125 # Which Problems Are Solved The proxy middleware (proxy.ts) did not apply `CUSTOM_REQUEST_HEADERS` to rewritten requests (/.well-known/*, /oauth/*, /oidc/*, etc.). When `ZITADEL_API_URL` points to an internal service name, the Host header on proxied requests remained the internal name instead of the configured public domain, causing Errors.Instance.NotFound. # How the Problems Are Solved The other two outgoing request paths — the connectRPC transport and the security-settings fetch — already applied these headers. This adds the same applyCustomHeaders() call to the proxy path. Co-authored-by: Ramon <[email protected]> |
||
|
|
64737bfedf |
chore: deps update (#12114)
<!-- Please inform yourself about the contribution guidelines on submitting a PR here: https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr. Take note of how PR/commit titles should be written and replace the template texts in the sections below. Don't remove any of the sections. It is important that the commit history clearly shows what is changed and why. Important: By submitting a contribution you agree to the terms from our Licensing Policy as described here: https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions. --> # Which Problems Are Solved Outdated depdencies # How the Problems Are Solved This PR mostly just updates our NPM depdencies to the newest feature releases. The UUID package was update to version 14, the changelog only includes changes to the supported node version. # Additional Changes Replace tsx for some scripts in the docs. --------- Co-authored-by: Livio Spring <[email protected]> Co-authored-by: Max Peintner <[email protected]> |
||
|
|
942c959d09 |
fix(login): resolve localized legal links in signup (#11913)
# Which Problems Are Solved
- Login V2 signup does not resolve the `{{.Lang}}` placeholder in ToS,
Privacy Policy, and help links.
- Clicking those links on the registration page can open URL-encoded
placeholders like `%7B%7B.Lang%7D%7D` instead of the active
language-specific page.
# How the Problems Are Solved
- Adds a small login utility to resolve `{{.Lang}}` placeholders against
the active Login V2 locale.
- Updates the signup legal acceptance component to use the resolved
links before rendering them.
- Applies the same resolution to the optional help link shown alongside
the legal acceptance text.
# Additional Changes
- Adds unit tests for the link placeholder resolver.
- Adds a component test covering localized ToS, Privacy Policy, and help
links on the signup page.
# Additional Context
- Closes #11907
---------
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Max Peintner <[email protected]>
Co-authored-by: Max Peintner <[email protected]>
|
||
|
|
b1c8781516 |
fix(login): lru-cache compatibility, improve session error handling (#12099)
# Which Problems Are Solved - Logo and heading overlap on login pages due to a -mb-4 negative margin on the logo container - The /login route returns a 500 when `listSessions` fails (e.g. stale session cookies), because loadSessions has no error handling. - The proxy logs `"fetch() returned undefined"` because `fetchIframeOrigins` returns undefined, which lru-cache's forceFetch treats as a fetch failure. # How the Problems Are Solved - Remove `-mb-4` from the logo container in DynamicTheme. - Wrap `loadSessions` in a try/catch — failures fall through as empty sessions instead of crashing. - Return `null` instead of `undefined` from `fetchIframeOrigins` so lru-cache caches it normally. --------- Co-authored-by: Livio Spring <[email protected]> Co-authored-by: conblem <[email protected]> |
||
|
|
de98c6edb8 |
fix(login): ClassifiedConnectError breaking ConnectError instanceof checks (#12022)
# Which Problems Are Solved 1. SSL/TLS handshake failures on Cloud Run (middleware self-loopback) PR #11903 changed the middleware (proxy.ts) to fetch security settings via fetch(origin + "/security") on every request, including non-proxy routes like /login. On Cloud Run, this self-loopback goes through the Google Front End (GFE) load balancer, causing intermittent SSL routines::record layer failure errors that were tenant-consistent. 2. The ClassifiedConnectError introduced in #11926 set this.name = "ClassifiedConnectError", which broke ConnectError's custom Symbol.hasInstance duck-typing check (v.name === "ConnectError"). This caused ConnectError.from() inside the connectRPC transport's abort handler to re-wrap classified errors as new ConnectError instances with Code.Unknown — losing the original gRPC error code and all classification metadata. # How the Problems Are Solved Middleware: eliminate self-loopback fetch: - Replaced the fetch(origin + "/security") self-loopback with a direct fetch to ZITADEL_API_URL using the Connect protocol (POST + JSON), bypassing the load balancer entirely - Security settings are cached in-memory with a 1-hour TTL per instance host - Extracted the fetching/caching logic into src/lib/server/security-settings.ts Removed the now-unused /security API route (src/app/security/route.ts) - CSP headers with iframe origins are now applied to all routes without any loopback Error classification interceptor: fixed - Keep this.name = "ConnectError" in ClassifiedConnectError so the duck-typing Symbol.hasInstance check passes - The branded Symbol.for check via isClassifiedError() still correctly distinguishes the subclass - Remove redundant Object.setPrototypeOf call (the super constructor already handles it via new.target) - Replace remaining instanceof ConnectError checks with isClassifiedError() in setUserPassword and checkSessionAndSetPassword |
||
|
|
dd9dcf9f72 |
feat(console): improve org search performance in create project grant page #11121 (#12057)
<!-- Please inform yourself about the contribution guidelines on submitting a PR here: https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr. Take note of how PR/commit titles should be written and replace the template texts in the sections below. Don't remove any of the sections. It is important that the commit history clearly shows what is changed and why. Important: By submitting a contribution you agree to the terms from our Licensing Policy as described here: https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions. --> # Which Problems Are Solved When creating a new Project Grant in the Zitadel console, the UI becomes extremely sluggish/unusable. The issue appears tied to the organization search dropdown attempting to load a very large dataset. # How the Problems Are Solved The refactored `SearchOrgAutocompleteComponent` uses server side filtering and ondemand loading using infinite scrolling. This makes sure on a subset of organizations is ever loaded on the client. # Additional Changes - Added tailwindcss for easier styling - Removed build warnings - Removed some of the SCSS syntax warnings # Additional Context - Closes #11121 --------- Co-authored-by: Max Peintner <[email protected]> |
||
|
|
a28ee63b02 | feat(login): add ZITADEL_API_AWAITINITIALCONN support (#12032) | ||
|
|
7d231b43d4 |
fix(login): replace custom SWR cache with lru-cache (#11945)
# Which Problems Are Solved
The in-memory SWR promiseCache in zitadel.ts used keys like
getBrandingSettings-${org} that had no instance identifier. In
multi-tenant mode, where a single Next.js process serves multiple
instances, an instance A's cached settings without org context
(branding, languages, settings, etc.) could be served to Instance B
request without org context. The cache now additionally is bound to 100
entries by default (configurable via maxSize in `API_CACHE_CONFIG`).
When capacity is exceeded, expired entries are swept first
It additionally replaces the hand-rolled PromiseCache (Map-based, FIFO
eviction) with lru-cache, leveraging its built-in fetchMethod for
stale-while-revalidate, request deduplication, and true LRU eviction.
# How the Problems Are Solved
Added an instanceCacheKey() helpe that prefixes every cache key with
serviceConfig.instanceHost in addition to the org context if available.
---------
Co-authored-by: Ramon <[email protected]>
|
||
|
|
ecea44329a | fix(login): load SSL_CERT_DIR certificates without requiring hashed filenames (#12029) | ||
|
|
9135ff4b36 |
chore(deps): bump the go_modules group across 2 directories with 1 update (#11982)
Bumps the go_modules group with 1 update in the /apps/login/acceptance/idp/oidc directory: [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose). Bumps the go_modules group with 1 update in the /apps/login/acceptance/oidcrp directory: [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose). Updates `github.com/go-jose/go-jose/v4` from 4.0.5 to 4.1.4 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/go-jose/go-jose/releases">github.com/go-jose/go-jose/v4's releases</a>.</em></p> <blockquote> <h2>v4.1.3</h2> <p>This release drops Go 1.23 support as that Go release is no longer supported. With that, we can drop <code>x/crypto</code> and no longer have any external dependencies in go-jose outside of the standard library!</p> <p>This release fixes a bug where a critical b64 header was ignored if in an unprotected header. It is now rejected instead of ignored.</p> <h2>What's Changed</h2> <ul> <li>Remove Go 1.23 support by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/205">go-jose/go-jose#205</a></li> <li>Reject JWS with an unprotected critical b64 header by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/210">go-jose/go-jose#210</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/go-jose/go-jose/compare/v4.1.2...v4.1.3">https://github.com/go-jose/go-jose/compare/v4.1.2...v4.1.3</a></p> <h2>v4.1.2</h2> <h2>What's Changed</h2> <p>go-jose v4.1.2 improves some documentation, errors, and removes the only 3rd-party dependency.</p> <ul> <li>Update go-jose documentation by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/198">go-jose/go-jose#198</a></li> <li>Remove dependency on testify by <a href="https://github.com/wardviaene"><code>@wardviaene</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/197">go-jose/go-jose#197</a></li> <li>Improve error message for invalid private keys by <a href="https://github.com/ProjectMutilation"><code>@ProjectMutilation</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/195">go-jose/go-jose#195</a></li> <li>JWK unsupported error when unmarshalling by <a href="https://github.com/fprojetto"><code>@fprojetto</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/191">go-jose/go-jose#191</a></li> <li>Add JSONWebKey type to makeJWERecipient by <a href="https://github.com/alvarolivie"><code>@alvarolivie</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/200">go-jose/go-jose#200</a></li> <li>testutils/assert: remove True, Nil, NotNil by <a href="https://github.com/jsha"><code>@jsha</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/202">go-jose/go-jose#202</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/wardviaene"><code>@wardviaene</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/197">go-jose/go-jose#197</a></li> <li><a href="https://github.com/fprojetto"><code>@fprojetto</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/191">go-jose/go-jose#191</a></li> <li><a href="https://github.com/alvarolivie"><code>@alvarolivie</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/200">go-jose/go-jose#200</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/go-jose/go-jose/compare/v4.1.1...v4.1.2">https://github.com/go-jose/go-jose/compare/v4.1.1...v4.1.2</a></p> <h2>v4.1.1</h2> <h2>What's Changed</h2> <ul> <li>Drop go-cmp dependency by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/186">go-jose/go-jose#186</a></li> <li>jws: improve performance and allocations for ParseSignedCompact by <a href="https://github.com/drakkan"><code>@drakkan</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/188">go-jose/go-jose#188</a></li> <li>Add missing quote to unknown curve message <a href="https://redirect.github.com/go-jose/go-jose/issues/170">#170</a> by <a href="https://github.com/sudhanvaghebbale"><code>@sudhanvaghebbale</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/189">go-jose/go-jose#189</a></li> <li>Fix incorrect validation by <a href="https://github.com/ProjectMutilation"><code>@ProjectMutilation</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/192">go-jose/go-jose#192</a></li> <li>Restore Go 1.23 compatibility by <a href="https://github.com/anuraaga"><code>@anuraaga</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/193">go-jose/go-jose#193</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/drakkan"><code>@drakkan</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/188">go-jose/go-jose#188</a></li> <li><a href="https://github.com/sudhanvaghebbale"><code>@sudhanvaghebbale</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/189">go-jose/go-jose#189</a></li> <li><a href="https://github.com/ProjectMutilation"><code>@ProjectMutilation</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/192">go-jose/go-jose#192</a></li> <li><a href="https://github.com/anuraaga"><code>@anuraaga</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/193">go-jose/go-jose#193</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/go-jose/go-jose/compare/v4.1.0...v4.1.1">https://github.com/go-jose/go-jose/compare/v4.1.0...v4.1.1</a></p> <h2>v4.1.0</h2> <h2>What's Changed</h2> <ul> <li>Document <code>signatureAlgorithms</code> argument by <a href="https://github.com/tgeoghegan"><code>@tgeoghegan</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/163">go-jose/go-jose#163</a></li> <li>Add custom error for unsupported JWS signature algorithms by <a href="https://github.com/beautifulentropy"><code>@beautifulentropy</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/181">go-jose/go-jose#181</a></li> <li>use stdlib pbkdf2 package on go 1.24 by <a href="https://github.com/kruskall"><code>@kruskall</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/180">go-jose/go-jose#180</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/go-jose/go-jose/commit/0e59876635f3dbf46d7b5e97b52bb75a3f96e7d9"><code>0e59876</code></a> Merge commit from fork</li> <li><a href="https://github.com/go-jose/go-jose/commit/ddffdbcec8bdadea8e02a20bdf19239878228215"><code>ddffdbc</code></a> Bump actions/checkout from 5 to 6 (<a href="https://redirect.github.com/go-jose/go-jose/issues/213">#213</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/5348b9a4ba4559d2266b5af89fb5353cd1a5360a"><code>5348b9a</code></a> Reject JWS with an unprotected critical b64 header (<a href="https://redirect.github.com/go-jose/go-jose/issues/210">#210</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/9153a5e4549c95e97a84e41e6375dc90eac54241"><code>9153a5e</code></a> Bump actions/setup-python from 5 to 6 (<a href="https://redirect.github.com/go-jose/go-jose/issues/208">#208</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/2126e17f8791f6a234e63b2e4e8cb9fac8605c3a"><code>2126e17</code></a> Bump actions/setup-go from 5 to 6 (<a href="https://redirect.github.com/go-jose/go-jose/issues/209">#209</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/9860c65054c4821d1e7c22200422b04181f58ebc"><code>9860c65</code></a> Bump actions/checkout from 4 to 5 (<a href="https://redirect.github.com/go-jose/go-jose/issues/206">#206</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/14239fdb15b88e1c42e41621ef24f1112cf31b5a"><code>14239fd</code></a> Remove Go 1.23 support (<a href="https://redirect.github.com/go-jose/go-jose/issues/205">#205</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/a16e15813482ca5e9a679b7f5bb42ddfae616d43"><code>a16e158</code></a> Update CI to run on Go 1.24 and 1.25 (<a href="https://redirect.github.com/go-jose/go-jose/issues/204">#204</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/a1565a41aa008ae6545e0f50a636d254de5b4596"><code>a1565a4</code></a> testutils/assert: remove True, Nil, NotNil (<a href="https://redirect.github.com/go-jose/go-jose/issues/202">#202</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/3a80e136a96e747bf44049414eadc02828df4d33"><code>3a80e13</code></a> jwe: accept non-pointer JSONWebKey in Recipient (<a href="https://redirect.github.com/go-jose/go-jose/issues/200">#200</a>)</li> <li>Additional commits viewable in <a href="https://github.com/go-jose/go-jose/compare/v4.0.5...v4.1.4">compare view</a></li> </ul> </details> <br /> Updates `github.com/go-jose/go-jose/v4` from 4.0.5 to 4.1.4 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/go-jose/go-jose/releases">github.com/go-jose/go-jose/v4's releases</a>.</em></p> <blockquote> <h2>v4.1.3</h2> <p>This release drops Go 1.23 support as that Go release is no longer supported. With that, we can drop <code>x/crypto</code> and no longer have any external dependencies in go-jose outside of the standard library!</p> <p>This release fixes a bug where a critical b64 header was ignored if in an unprotected header. It is now rejected instead of ignored.</p> <h2>What's Changed</h2> <ul> <li>Remove Go 1.23 support by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/205">go-jose/go-jose#205</a></li> <li>Reject JWS with an unprotected critical b64 header by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/210">go-jose/go-jose#210</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/go-jose/go-jose/compare/v4.1.2...v4.1.3">https://github.com/go-jose/go-jose/compare/v4.1.2...v4.1.3</a></p> <h2>v4.1.2</h2> <h2>What's Changed</h2> <p>go-jose v4.1.2 improves some documentation, errors, and removes the only 3rd-party dependency.</p> <ul> <li>Update go-jose documentation by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/198">go-jose/go-jose#198</a></li> <li>Remove dependency on testify by <a href="https://github.com/wardviaene"><code>@wardviaene</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/197">go-jose/go-jose#197</a></li> <li>Improve error message for invalid private keys by <a href="https://github.com/ProjectMutilation"><code>@ProjectMutilation</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/195">go-jose/go-jose#195</a></li> <li>JWK unsupported error when unmarshalling by <a href="https://github.com/fprojetto"><code>@fprojetto</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/191">go-jose/go-jose#191</a></li> <li>Add JSONWebKey type to makeJWERecipient by <a href="https://github.com/alvarolivie"><code>@alvarolivie</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/200">go-jose/go-jose#200</a></li> <li>testutils/assert: remove True, Nil, NotNil by <a href="https://github.com/jsha"><code>@jsha</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/202">go-jose/go-jose#202</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/wardviaene"><code>@wardviaene</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/197">go-jose/go-jose#197</a></li> <li><a href="https://github.com/fprojetto"><code>@fprojetto</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/191">go-jose/go-jose#191</a></li> <li><a href="https://github.com/alvarolivie"><code>@alvarolivie</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/200">go-jose/go-jose#200</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/go-jose/go-jose/compare/v4.1.1...v4.1.2">https://github.com/go-jose/go-jose/compare/v4.1.1...v4.1.2</a></p> <h2>v4.1.1</h2> <h2>What's Changed</h2> <ul> <li>Drop go-cmp dependency by <a href="https://github.com/mcpherrinm"><code>@mcpherrinm</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/186">go-jose/go-jose#186</a></li> <li>jws: improve performance and allocations for ParseSignedCompact by <a href="https://github.com/drakkan"><code>@drakkan</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/188">go-jose/go-jose#188</a></li> <li>Add missing quote to unknown curve message <a href="https://redirect.github.com/go-jose/go-jose/issues/170">#170</a> by <a href="https://github.com/sudhanvaghebbale"><code>@sudhanvaghebbale</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/189">go-jose/go-jose#189</a></li> <li>Fix incorrect validation by <a href="https://github.com/ProjectMutilation"><code>@ProjectMutilation</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/192">go-jose/go-jose#192</a></li> <li>Restore Go 1.23 compatibility by <a href="https://github.com/anuraaga"><code>@anuraaga</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/193">go-jose/go-jose#193</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/drakkan"><code>@drakkan</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/188">go-jose/go-jose#188</a></li> <li><a href="https://github.com/sudhanvaghebbale"><code>@sudhanvaghebbale</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/189">go-jose/go-jose#189</a></li> <li><a href="https://github.com/ProjectMutilation"><code>@ProjectMutilation</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/192">go-jose/go-jose#192</a></li> <li><a href="https://github.com/anuraaga"><code>@anuraaga</code></a> made their first contribution in <a href="https://redirect.github.com/go-jose/go-jose/pull/193">go-jose/go-jose#193</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/go-jose/go-jose/compare/v4.1.0...v4.1.1">https://github.com/go-jose/go-jose/compare/v4.1.0...v4.1.1</a></p> <h2>v4.1.0</h2> <h2>What's Changed</h2> <ul> <li>Document <code>signatureAlgorithms</code> argument by <a href="https://github.com/tgeoghegan"><code>@tgeoghegan</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/163">go-jose/go-jose#163</a></li> <li>Add custom error for unsupported JWS signature algorithms by <a href="https://github.com/beautifulentropy"><code>@beautifulentropy</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/181">go-jose/go-jose#181</a></li> <li>use stdlib pbkdf2 package on go 1.24 by <a href="https://github.com/kruskall"><code>@kruskall</code></a> in <a href="https://redirect.github.com/go-jose/go-jose/pull/180">go-jose/go-jose#180</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/go-jose/go-jose/commit/0e59876635f3dbf46d7b5e97b52bb75a3f96e7d9"><code>0e59876</code></a> Merge commit from fork</li> <li><a href="https://github.com/go-jose/go-jose/commit/ddffdbcec8bdadea8e02a20bdf19239878228215"><code>ddffdbc</code></a> Bump actions/checkout from 5 to 6 (<a href="https://redirect.github.com/go-jose/go-jose/issues/213">#213</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/5348b9a4ba4559d2266b5af89fb5353cd1a5360a"><code>5348b9a</code></a> Reject JWS with an unprotected critical b64 header (<a href="https://redirect.github.com/go-jose/go-jose/issues/210">#210</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/9153a5e4549c95e97a84e41e6375dc90eac54241"><code>9153a5e</code></a> Bump actions/setup-python from 5 to 6 (<a href="https://redirect.github.com/go-jose/go-jose/issues/208">#208</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/2126e17f8791f6a234e63b2e4e8cb9fac8605c3a"><code>2126e17</code></a> Bump actions/setup-go from 5 to 6 (<a href="https://redirect.github.com/go-jose/go-jose/issues/209">#209</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/9860c65054c4821d1e7c22200422b04181f58ebc"><code>9860c65</code></a> Bump actions/checkout from 4 to 5 (<a href="https://redirect.github.com/go-jose/go-jose/issues/206">#206</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/14239fdb15b88e1c42e41621ef24f1112cf31b5a"><code>14239fd</code></a> Remove Go 1.23 support (<a href="https://redirect.github.com/go-jose/go-jose/issues/205">#205</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/a16e15813482ca5e9a679b7f5bb42ddfae616d43"><code>a16e158</code></a> Update CI to run on Go 1.24 and 1.25 (<a href="https://redirect.github.com/go-jose/go-jose/issues/204">#204</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/a1565a41aa008ae6545e0f50a636d254de5b4596"><code>a1565a4</code></a> testutils/assert: remove True, Nil, NotNil (<a href="https://redirect.github.com/go-jose/go-jose/issues/202">#202</a>)</li> <li><a href="https://github.com/go-jose/go-jose/commit/3a80e136a96e747bf44049414eadc02828df4d33"><code>3a80e13</code></a> jwe: accept non-pointer JSONWebKey in Recipient (<a href="https://redirect.github.com/go-jose/go-jose/issues/200">#200</a>)</li> <li>Additional commits viewable in <a href="https://github.com/go-jose/go-jose/compare/v4.0.5...v4.1.4">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/zitadel/zitadel/network/alerts). </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
17f49323dd |
fix(login): preserve OIDC request context during email verification (#11990)
# Which Problems Are Solved When a user needed to verify their email during an OIDC login flow, the requestId was lost, preventing the flow from completing with a redirect back to the relying party. # How the Problems Are Solved In `sendVerification()`, the session cookie lookup used `"loginName" in command` to decide whether to fall back to `user.preferredLoginName`. Since the `loginName` property key always exists in the command object (even when its value is undefined), the fallback was never triggered. This caused the lookup to search for loginName === undefined, finding no session — and ultimately redirecting to a dead-end success page. - /authenticator/set redirect: Added missing requestId to the URL params when redirecting users who need to set up a primary auth method. - /verify/success page: Added a "Continue" button that re-enters the login flow with requestId preserved, handling the edge case where no session cookie exists (e.g. email link opened in a different browser). |
||
|
|
5abb51c263 |
chore: deps update (#11981)
# Which Problems Are Solved After merging #11968 and rechecking the dependabot alerts there are still some issues leftover. # How the Problems Are Solved This pr makes overrides for vulnerable transitive depdencies to force update to safe versions. It also upgrades the next.js version in the docs and I also ran `pnpm update` once more. # Additional Changes Removed the mochaawesome dependency is this is not really needed and seems unmaintained. # Additional Context - Precursor: #11968 |
||
|
|
f803ea8298 |
feat(login): add Portuguese (pt) translations for Login V2 (#11897)
## What does this PR do? Adds complete **Portuguese (pt)** locale translations for the Login V2 interface, making it the 14th supported language. ### Problem The Login V2 component currently supports 13 languages but does not include Portuguese — one of the most spoken languages in the world (~260M native speakers). This was reported in #11782. ### What we found - The Login V2 translations are stored as JSON files under `apps/login/locales/` - Available languages are registered in the `LANGS` array in `apps/login/src/lib/i18n.ts` - Portuguese (`pt.json`) was missing from both the locales directory and the `LANGS` array ### What we did 1. Created `apps/login/locales/pt.json` with complete Portuguese translations for all login screens (loginname, password, register, MFA, passkeys, OTP, sessions, errors, etc.) 2. Added `{ name: "Português", code: "pt" }` to the `LANGS` array in `apps/login/src/lib/i18n.ts` ### Translation methodology - Based on the existing `en.json` and `es.json` as reference - Follows Brazilian Portuguese (pt-BR) conventions, which is understood by all Portuguese-speaking countries - All keys translated — no fallbacks to English needed ### Files changed | File | Change | |------|--------| | `apps/login/locales/pt.json` | **New** — Complete Portuguese translations | | `apps/login/src/lib/i18n.ts` | **Modified** — Added `pt` entry to `LANGS` array | ### Testing We built and deployed this change from source (tag v4.12.1) to a production Zitadel instance: - ✅ Portuguese appears in the language dropdown - ✅ All login screens display correct Portuguese translations - ✅ Language selection persists across pages - ✅ OIDC flow works correctly with Portuguese selected - ✅ No build warnings or errors related to the translation Closes #11782 Co-authored-by: rofilho <[email protected]> |
||
|
|
0945195f68 |
chore: deps update (#11968)
# Which Problems Are Solved This pr updates major and minor dependencies and is the first step on getting our dependabot alerts cut down. # How the Problems Are Solved Depedency updates across the board eg: - Upgrade Angular to v21 - Upgrade next.js to v16.2 - Upgrade tailwind to v4 in the login - Upgrade vitest to v4 in the login This is an uncompleted list refer to the changed files for a full overview of all the updates. # Additional Changes Migrated all control flow in the console to the modern control flow syntax. Fixed the dependsOn setting for the @zitadel/login:test-unit nx target. # Additional Context - Closes https://github.com/zitadel/zitadel/issues/11274 --------- Co-authored-by: Max Peintner <[email protected]> |
||
|
|
891c7473ca |
fix(login): invite flow instead of email verification for users with no primary method, improve sending behaviour (#11837)
Closes #10929 # Which Problems Are Solved When a human user without a primary authentication method enters their email on the login screen, the login historically auto-sent an email code (send=true) and redirected them to the `/verify` flow. If the user was newly created via the API and already received an initial verify-email, navigating to the login page would trigger a new invite code, silently invalidating the code they received in their first email. Additionally instead of resending the same type of email (invitation) a regular email verification mail was sent # How the Problems Are Solved - Resend an invitation email instead of a email verification if a user has no method set (still in invitation state) - Conditional Code Sending: Updated `loginname.ts` to check `humanUser?.email?.isVerified`. We only auto-send a new code (`send=true`) if the user's email is already verified. Unverified users will be redirected with `send=false`, allowing them to safely enter the code they already have. - UI State Fix: Fixed an issue in `verify/page.tsx` where the send URL parameter was being checked directly as a string ("false" is truthy). By using the properly evaluated doSend boolean, the "Code Sent" alert now correctly hides itself when a new code is not explicitly sent. - Translation Updates: Refined the codeSent messaging across all locales to specify "A new code has been sent..." to provide better context to the user when they do explicitly request a resend. |
||
|
|
140f07e60b | feat(login): simplify login client auth and support PKCS#1 keys (#11888) | ||
|
|
ec0bd5790f |
fix(login): respect branding themeMode for theme toggle, fix CSP (#11903)
Closes #11721 # Which Problems Are Solved The login app now correctly handles the themeMode from branding settings: - Hide toggle when themeMode is LIGHT or DARK — the theme is forced, users cannot switch - Show 3-option toggle (light / system / dark) when themeMode is AUTO or UNSPECIFIED # How the Problems Are Solved - Introduced a `BrandingContext` to pass `themeMode` from `ThemeWrapper` down to `ThemeSwitch` # Additional Changes - removed the CSP from next.config.ts to prevent a precedency issue where the CSP was actually not applied |
||
|
|
604d5cb0a9 |
fix(login): prevent duplicate email-code verification issue (#11893)
<!-- Please inform yourself about the contribution guidelines on submitting a PR here: https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr. Take note of how PR/commit titles should be written and replace the template texts in the sections below. Don't remove any of the sections. It is important that the commit history clearly shows what is changed and why. Important: By submitting a contribution you agree to the terms from our Licensing Policy as described here: https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions. --> # Which Problems Are Solved - With Login V2 and EMAIL_VERIFICATION=true, opening the verify page with send=true can trigger email code generation twice. - The second code invalidates the first one, so users may receive two emails where the first code is always invalid. - This causes failed verification attempts and blocks onboarding for affected users. # How the Problems Are Solved - Removed side-effectful email-code sending from direct server component execution path. - Ensured code sending is executed only once in a safe server-side flow, so React Server Component re-fetches do not generate additional codes. - Kept verify flow behavior intact while preventing duplicate code invalidation. # Additional Changes - Added/updated logic around the verify flow to make repeated render/re-fetch paths idempotent for email-code sending. - Improved reliability of the Login V2 email verification step under App Router navigation behavior. # Additional Context Fixes #11857 - Tested manually with Login V2 and EMAIL_VERIFICATION=true by completing a new user registration flow to /verify?send=true. - Verified that only one verification email is sent and the first received code is valid (no duplicate invalidating code generated). Related bug report with reproduction details: [https://github.com/zitadel/zitadel/issues/11857](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) --------- Co-authored-by: Max Peintner <[email protected]> |
||
|
|
9bab764796 |
fix(login): add OIDC/SAML requestId to resend invite / resend email code (#11927)
# Which Problems Are Solved This fixes an issue where resending a code for invite flow did not have the same context it was initially created for # How the Problems Are Solved by passing down thre requestId, the context is preserved though a resend |
||
|
|
ff4aae7b3f |
fix(login): improve error classification (#11926)
Closes #11923 # Which Problems Are Solved Client-side gRPC errors (e.g. NotFound, InvalidArgument, PermissionDenied) were being surfaced as HTTP 500 Internal Server Errors, causing false SRE alerts and poor UI feedback. # How the Problems Are Solved - New transport interceptor (`error-classification.ts`): Automatically enriches every ConnectError with httpStatus and isUserError metadata via a `ClassifiedConnectError` wrapper - Route handler protection (`route.ts`, `flow-initiation.ts`): Catches classified errors from `getAuthRequest` / `getSAMLRequest` and returns correct HTTP status codes instead of 500 - Type safety: Replaced all magic number error.code === 9 checks with typed Code.FailedPrecondition + instanceof ConnectError across `oidc.ts`, `saml.ts`, `password.ts`, `zitadel.ts` - Classification-aware logging (`session.ts`): Client/user errors log at warn level, server errors at error level - Observability (`otel.ts`): Spans now include error.is_user_error and http.status_code attributes for alert filtering # Additional Changes Gitignore `next-env.d.ts`: This file is auto-generated by Next.js on every next dev and next build invocation. The two modes write slightly different import paths (.next/dev/types/ vs .next/types/), which causes git diff --exit-code to fail in CI whenever a developer runs next dev locally before committing. Since Next.js regenerates it automatically, there's no need to track it --------- Co-authored-by: Ramon <[email protected]> Co-authored-by: Copilot <[email protected]> |
||
|
|
a864434b4b |
feat(login): update to nextjs 16, improve caching, change default colors (#11629)
# Which Problems Are Solved Updated the project to use the latest versions of Next.js and React, and implemented a SWR caching strategy for key settings API calls to improve performance. Adjusted configuration to ensure compatibility with Next.js 16. # How the Problems Are Solved - Updated next to 16.1.6, react & react-dom to 19.2.4, and next-intl to 4.8.3. - Implemented `API_CACHE_ENABLED` and `API_CACHE_CONFIG` (replacing deprecated unstable_cacheLife) for: - getBrandingSettings - getSecuritySettings - getPasswordComplexitySettings - getLoginSettings ... - Updated default theme colors from blue to a more neutral black and white # Additional changes - Updated login docker image to node 24 --------- Co-authored-by: Ramon <[email protected]> |