Commit Graph

48 Commits

Author SHA1 Message Date
Mertcan GÖKGÖZ
e7ec430dbc feat(i18n): add Turkish translation file (#10922)
Add complete Turkish (tr.json) translation for authentication UI,
including login, registration, password management, MFA setup

# Which Problems Are Solved
- Turkish language support is missing in the authentication UI
- Turkish-speaking users cannot use the application in their native
language

# How the Problems Are Solved
- Added complete Turkish (tr.json) translation file for the
authentication UI
- Translated all authentication-related strings including login,
registration, password management, MFA setup, error messages, and user
verification flows
- Technical terms (Passkey, SSO, LDAP, IDP, etc.) are kept in English
for consistency

# Additional Changes
- None

# Additional Context
- Closes #10851
- This translation follows the same structure as the existing en.json
file
- All user-facing strings in the authentication flow are now available
in Turkish

Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Gayathri Vijayan <66356931+grvijayan@users.noreply.github.com>
2025-10-27 08:11:01 +00:00
Ramon
16b21569db fix(login): improve duration undefined check (#10949)
# Which Problems Are Solved
In the login we often check if a GRPC Duration is not defined however it
can also be set to 0. Using the API it's possible to set the password
check lifetime to zero which broke the login v2.

# How the Problems Are Solved
Also check if the GRPC Duration seconds field is not 0

# Additional Context
- May help if the issue here is actually accidentally setting password
lifetime check to 0 using the API #10865

Co-authored-by: Max Peintner <max@caos.ch>
2025-10-27 09:03:32 +01:00
Elio Bischof
b080ed8884 chore: release tarballs (#10956)
# Which Problems Are Solved

This PR makes sure that the tarballs containing the API binary and the
standalone login are separately downloadable from the release pages
again.

# How the Problems Are Solved

Because the `Pack` workflow uploads a single GitHub artifact containing
all tarballs since #10571, we download this artifact so that it
correctly unpacks into the correct folder structure configured in
`.releaserc.js`

The changes are tested [with this action
run](https://github.com/eliobischof/zitadel/actions/runs/18745783976),
which [created this
release](https://github.com/eliobischof/zitadel/releases/tag/v1.0.0-release-archives.5).

# Additional Changes

- The term `standalone` is removed from the login tarball, as it should
be clear that it is a standalone build.
- The go builds and the login archiving are less verbose
- The pipelines go versions are pinned to *v1.25*, a minor above the
minimally required go version *v1.24.0* described in the go.mod file.
This makes sure that we build using newer patches for security and
performance.

# Additional Context

- The archives weren't published anymore since #10571 
- Closes #10896

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-10-23 20:08:24 +02:00
Max Peintner
d10be4c09a fix(login): send invite codes only for users with unverified email (#10943)
# Which Problems Are Solved

When a user with no authentication methods attempted to log in, the
system always set `invite=true` in the verification flow, regardless of
whether their email was already verified. This could cause errors when
trying to send invite codes to already initialized users.

# How the Problems Are Solved

Added conditional logic to determine whether to send an invite code
based on the user's email verification status:

This prevents errors when attempting to send invite codes to users who
have already verified their email and been initialized, while still
properly handling new users who need invitation flows.
2025-10-21 13:44:31 +00:00
Max Peintner
ff869482b1 fix(login): fallback for idp login (#10876)
Closes #10671

# Which Problems Are Solved

Users with password authentication disabled in their organization were
seeing "Username Password not allowed!" error instead of being
redirected to their organization's configured Identity Provider. This
affected domain discovery and multi-tenancy use cases in Login V2.

# How the Problems Are Solved

- Updated `redirectUserToIDP` to accept optional `userId` and
`organization` parameters
- Added fallback logic to check organization-level IDPs via
`getActiveIdentityProviders`
- Updated all call sites to pass appropriate organization context
- Added test coverage for the fallback behavior

# Additional Changes

- Consolidated duplicate logic by removing
`redirectUserToSingleIDPIfAvailable` function, which is now handled by
the unified `redirectUserToIDP` function
- improved error handling on verification page

---------

Co-authored-by: Ramon <mail@conblem.me>
2025-10-21 11:04:33 +02:00
Max Peintner
2ad5cf141f fix(login): Add Organization Scoping to IDP Auto-Linking (#10931)
This PR fixes an issue in the IDP auto-linking feature where user
searches were performed globally instead of being scoped to the current
organization context. This could result in IDP links being created for
users in unintended organizations.

# Which Problems Are Solved

When IDP auto-linking was enabled (by email or username), the system
would search for existing users across all organizations instead of
restricting the search to the current organization context.

# How the Problems Are Solved

Added organization scoping to all three auto-linking code paths
2025-10-21 10:56:34 +02:00
kenta yamamoto
27c248fa11 feat(login): add Japanese localization for login frontend app (#10811)
<!--
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

- Japanese users cannot use the Login UI in their native language, as
only other locales (English, German, Italian, Spanish, Polish, Chinese,
Russian, Turkish) are currently supported
- The Login UI language selection does not include Japanese as an option

# How the Problems Are Solved

- Updated the `LANGS` array in `apps/login/src/lib/i18n.ts` to include
Japanese (`{ name: "日本語", code: "ja" }`)
- Enables Japanese language selection in the Login UI through browser
language detection or manual locale setting

# Additional Changes

- No additional changes were necessary as other components (Console,
email notifications, common messages, Go templates) already have
Japanese locale support (`ja.json`/`ja.yaml` files exist)

# Additional Context

- This contribution enhances ZITADEL's internationalization support for
Japanese-speaking users
- The translation follows the same structure and key naming conventions
as existing locale files
- Testing can be performed by setting browser language to Japanese or
using `NEXT_LOCALE=ja` cookie

Co-authored-by: Max Peintner <max@caos.ch>
2025-10-17 14:37:37 +02:00
Max Peintner
00beaf6ddc fix(login): provide a postError redirect url for idp flows (#10883)
# Which Problems Are Solved

Improves the user experience when IDP authentication succeeds but user
creation/linking fails by introducing a `postErrorRedirectUrl` parameter
and dedicated error pages instead of generic error screens.

<img width="580" height="636" alt="Screenshot 2025-10-16 at 09 21 07"
src="https://github.com/user-attachments/assets/db653c8f-b648-4cfe-922a-2f237f3b70b3"
/>

# How the Problems Are Solved

## New Pages
- **`/idp/[provider]/account-not-found`**: Displayed when no user
account exists and creation/linking is not allowed
- **`/idp/[provider]/registration-failed`**: Displayed when user
registration fails due to organization resolution issues

## Flow Improvements
- Added `postErrorRedirectUrl` parameter to track where the IDP flow was
initiated
- Each entry point (loginname, register, idp, authenticator/set)
specifies its own redirect URL
- Users are now redirected to appropriate error pages with clear
messaging instead of generic error screens
- All context (`requestId`, `organization`, `postErrorRedirectUrl`) is
preserved throughout the flow

## Updated Components
- `SignInWithIdp`: Now accepts and passes `postErrorRedirectUrl`
parameter
- `redirectToIdp` server action: Extracts and forwards
`postErrorRedirectUrl` through the IDP flow
- IDP success page: Routes to appropriate error pages based on failure
reason

## i18n
Added new translation keys:
- `idp.accountNotFound.*` - For missing account scenarios
- `idp.registrationFailed.*` - For organization resolution failures
2025-10-16 11:24:54 +02:00
Max Peintner
19b744ca67 fix(login): use default titles for password pages (#10904)
# Which Problems Are Solved

This change shows the default titles for password pages instead of
dynamically showing the user name.

# How the Problems Are Solved

Both pages now show only the translated title text (verify.title and
change.title respectively) instead of falling back to showing the user's
display name.

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-10-16 07:22:27 +02:00
Livio Spring
53dcd0eb0a fix(login): ensure css is served (#10894)
# Which Problems Are Solved

The newest release (v4.3.2) was not serving the `zitadel.css` for the
login anymore. The previous file was served from cache, making it not
directly visible.
The problem was caused due to the CI change (#10571) where the generate
was moved from a makefile to Nx commands, which run in parallel.
Depending on timing, the generated css file might be embedded into the
login or not.

# How the Problems Are Solved

- Configure the commands to run sequentially.

# Additional Changes

none

# Additional Context

- relates to #10571 
- requires backport to v4.x
2025-10-13 06:58:54 +00:00
Elio Bischof
5aa2ca58ca chore: fix vercel build (#10887)
# Which Problems Are Solved

By default, the login redirects in all cases from its
`NEXT_PUBLIC_BASE_PATH` to `NEXT_PUBLIC_BASE_PATH/loginname` now. This
is the expected behavior.

# How the Problems Are Solved

Deployments to Vercel use the `apps/login/.env` file for their defaults.
As the .env file had DEBUG=true, redirects from root to ./loginname were
disabled.
DEBUG=true is not needed anywhere, so it's deleted from the .env file.
2025-10-10 13:38:10 +00:00
Livio Spring
e742d649c8 chore(ci): fix release (#10886)
# Which Problems Are Solved

The new pipeline did not correctly build the release. Console was not
built into the binary. Also there were some pipeline permission errors.

# How the Problems Are Solved

- add `build-console` as dependency to pack binaries
- streamline permissions and only pass necessary into steps

# Additional Changes

none

# Additional Context

- relates to #10571
2025-10-10 13:16:20 +00:00
Max Peintner
434aeb275a feat(login): comprehensive theme system (#10848)
# Which Problems Are Solved

This PR introduces a comprehensive theme customization system for the
login application with responsive behavior and enhanced visual options.

<img width="1122" height="578" alt="Screenshot 2025-08-19 at 09 55 24"
src="https://github.com/user-attachments/assets/cdcc8948-533d-4e13-bf45-fdcc24acfb2b"
/>

# How the Problems Are Solved

##  Features Added

- **🔄 Responsive Layout System**: Automatic switching between
side-by-side and top-to-bottom layouts based on screen size
- **🖼️ Background Image Support**: Custom background images configurable
via environment variables
- **⚙️ Theme Configuration**: Complete theme system with roundness,
spacing, appearance, and layout options
- **📱 Mobile-First Design**: Intelligent layout adaptation for different
screen sizes
- **🎯 Enhanced Typography**: Improved visual hierarchy with larger
titles in side-by-side mode

## 🏗️ Architecture

- **Server-Safe Theme Functions**: Theme configuration accessible on
both server and client
- **SSR-Safe Hooks**: Proper hydration handling for responsive layouts
- **Component Separation**: Clear boundaries between server and client
components
- **Two-Section Layout**: Consistent content structure across all login
pages

## 🔧 Configuration Options

All theme options are configurable via environment variables:

- `NEXT_PUBLIC_THEME_ROUNDNESS`: `edgy` | `mid` | `full`
- `NEXT_PUBLIC_THEME_LAYOUT`: `side-by-side` | `top-to-bottom`
- `NEXT_PUBLIC_THEME_APPEARANCE`: `flat` | `material`
- `NEXT_PUBLIC_THEME_SPACING`: `regular` | `compact`
- `NEXT_PUBLIC_THEME_BACKGROUND_IMAGE`: Custom background image URL

## 📄 Pages Updated

Updated all major login pages to use the new two-section responsive
layout:
- Login name entry
- Password verification
- MFA verification
- User registration
- Account selection
- Device authorization
- Logout confirmation

## 📚 Documentation

- **THEME_ARCHITECTURE.md**: Complete technical documentation of the
theme system
- **THEME_CUSTOMIZATION.md**: User-friendly guide with examples and
troubleshooting

## 🚀 Benefits

- **Better UX**: Responsive design that works seamlessly across all
devices
- **Brand Flexibility**: Easy customization to match any brand identity
- **Maintainable Code**: Clean separation of concerns and
well-documented architecture
- **Future-Proof**: Extensible system for additional theme options


<img width="580" height="680" alt="Screenshot 2025-08-19 at 09 22 23"
src="https://github.com/user-attachments/assets/9de8da37-6d56-4fe9-b337-5d8ad2a3ba59"
/>
<img width="599" height="689" alt="Screenshot 2025-08-19 at 09 23 45"
src="https://github.com/user-attachments/assets/26a30cc7-4017-4f4b-8b87-a49466c42b94"
/>
<img width="595" height="681" alt="Screenshot 2025-08-19 at 09 23 17"
src="https://github.com/user-attachments/assets/a3d31088-4545-4f36-aafe-1aae1253d677"
/>
2025-10-10 10:26:06 +02:00
Elio Bischof
7ba6870baf feat: await initial database connection (#10869)
# Which Problems Are Solved

When Postgres was not ready when the API was started, the API failed
immediately.
This made task orchestration hard, especially in a platform agnostic
way:

- The current health check in the Nx target `@zitadel/api:prod` uses the
timeout command, which is not installed on all platforms and behaves
unpredictably
- The current health check in the Nx target `@zitadel/api:prod` requires
the DB to have been started using `@zitadel/zitadel:db`

# How the Problems Are Solved

- Additional configuration option `Database.Postgres.AwaitInitialConn`
is added and defaults to *0m* for backwards compatibility.
- If a duration is configured, the API retries to ping the database
until it succeeds
- The API sleeps for a second between each ping.
- It emits an info-level log with the error on each try.
- When the configured duration times out before the ping is successful,
the error is returned and the command exits with a failure code.
- When the ping succeeds within the configured duration, the API goes on
with the init, setup or start phase.

# Additional Context

- Relates to internally reported problems with the current DB health
check command
[here](https://zitadel.slack.com/archives/C07EUL5H83A/p1759915009839269?thread_ts=1759912259.410789&cid=C07EUL5H83A)
and
[here](https://zitadel.slack.com/archives/C07EUL5H83A/p1759918324246249?thread_ts=1759912259.410789&cid=C07EUL5H83A).
2025-10-09 11:18:34 +00:00
Max Peintner
64e14de091 feat(login): translations (#10849)
# Which Problems Are Solved

Replace this example text with a concise list of problems that this PR
solves.
For example:
- password complexity requirements have hardcoded English text
- password, loginname, register and verify components have hardcoded
Engilsh error messages/alerts

# How the Problems Are Solved

Replace this example text with a concise list of changes that this PR
introduces.
For example:
- adds i18n for password complexity requirements
- adds i18n for password, loginname, register and verify components
error messages/alerts

# Additional Changes

- small change in code/styles for icons in PasswordComplexity to make
sure that icons keep size

# Additional Context

N.A

---------

Co-authored-by: Adam Kida <122802098+jmblab-adam@users.noreply.github.com>
2025-10-09 11:11:03 +02:00
Wojciech Piekutowski
794054c075 fix(login): fix translation key typo for logout.verifiedAt (#10504)
# Which Problems Are Solved

- login UI was complaining about a missing translation key:
```
Error: MISSING_MESSAGE: logout.verfiedAt (en)
zitadel-login-1               |     at t (.next/server/chunks/1119.js:3:8993)
zitadel-login-1               |     at u (.next/server/chunks/1119.js:3:9149)
zitadel-login-1               |     at v (.next/server/chunks/1119.js:3:10482)
zitadel-login-1               |     at f (.next/server/chunks/2293.js:1:10127) {
zitadel-login-1               |   code: 'MISSING_MESSAGE',
zitadel-login-1               |   originalMessage: 'logout.verfiedAt (en)'
zitadel-login-1               | }
```

# How the Problems Are Solved

- fixes a typo in the translation key name

# Additional Changes

None.

# Additional Context

None.

Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Ramon <mail@conblem.me>
2025-10-09 08:59:22 +00:00
Yann Soubeyrand
3b0ad1e9b6 fix(login): serve UI on both IPv4 and IPv6 (#10554)
# Which Problems Are Solved

Currently, the HTTP server is listening on IPv4 only.

# How the Problems Are Solved

This PR makes it listen on IPv4 and IPv6.

Co-authored-by: Elio Bischof <elio@zitadel.com>
2025-10-08 23:56:43 +02:00
Elio Bischof
f69a6ed4f3 chore: rehaul DevX (#10571)
# Which Problems Are Solved

Replaces Turbo by Nx and lays the foundation for the next CI
improvements. It enables using Nx Cloud to speed the up the pipelines
that affect any node package.
It streamlines the dev experience for frontend and backend developers by
providing the following commands:

| Task | Command | Notes |
|------|---------|--------|
| **Production** | `nx run PROJECT:prod` | Production server |
| **Develop** | `nx run PROJECT:dev` | Hot reloading development server
|
| **Test** | `nx run PROJECT:test` | Run all tests |
| **Lint** | `nx run PROJECT:lint` | Check code style |
| **Lint Fix** | `nx run PROJECT:lint-fix` | Auto-fix style issues |

The following values can be used for PROJECT:

- @zitadel/zitadel (root commands)
- @zitadel/api,
- @zitadel/login,
- @zitadel/console,
- @zitadel/docs,
- @zitadel/client
- @zitadel/proto

The project names and folders are streamlined:

| Old Folder | New Folder |
| --- | --- |
| ./e2e | ./tests/functional-ui |
| ./load-test | ./benchmark |
| ./build/zitadel | ./apps/api |
| ./console | ./apps/console (postponed so the PR is reviewable) |  

Also, all references to the TypeScript repo are removed so we can
archive it.

# How the Problems Are Solved

- Ran `npx nx@latest init`
- Replaced all turbo.json by project.json and fixed the target configs
- Removed Turbo dependency
- All JavaScript related code affected by a PRs changes is
quality-checked using the `nx affected` command
- We move PR checks that are runnable using Nx into the `check`
workflow. For workflows where we don't use Nx, yet, we restore
previously built dependency artifacts from Nx.
- We only use a single and easy to understand dev container
- The CONTRIBUTING.md is streamlined
- The setup with a generated client pat is orchestrated with Nx
- Everything related to the TypeScript repo is updated or removed. A
**Deploy with Vercel** button is added to the docs and the
CONTRIBUTING.md.

# Additional Changes

- NPM package names have a consistent pattern.
- Docker bake is removed. The login container is built and released like
the core container.
- The integration tests build the login container before running, so
they don't rely on the login container action anymore. This fixes
consistently failing checks on PRs from forks.
- The docs build in GitHub actions is removed, as we already build on
Vercel.

# Additional Context

- Internal discussion:
https://zitadel.slack.com/archives/C087ADF8LRX/p1756277884928169
- Workflow dispatch test:
https://github.com/zitadel/zitadel/actions/runs/17760122959

---------

Co-authored-by: Florian Forster <florian@zitadel.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-08 10:27:02 +02:00
Max Peintner
695db96745 fix(login): Redirect to IDP flow when password auth is disabled (#10839)
Closes #10671

# Which Problems Are Solved

Users with only password authentication method were immediately shown an
error "Username Password not allowed" when
`loginSettings.allowUsernamePassword` was set to false. However, the IDP
flow could potentially allow the user to register a new account or link
an existing account, providing a better user experience than a dead-end
error.

# How the Problems Are Solved

- Modified single password method case to attempt IDP redirect before
showing error
- This allows users to potentially register or link accounts through the
IDP flow instead of hitting an immediate error
- Only show error as last resort when no IDP alternative is available
2025-10-07 05:47:58 +00:00
Tim Möhlmann
a45908b364 feat(rt): project repository (#10789)
# Which Problems Are Solved

Add projects to the relational tables

# How the Problems Are Solved

- Define table migrations
- Define and implement Project and Project Role repositories.
- Provide projection handlers to populate the relational tables.

# Additional Changes

- Statement Builder now has a constructor which allows setting of a base
query with arguments.
- Certain operations, like Get, Update and Delete require the Primary
Key to be set as conditions. However, this requires knowledge of the
implementation and table definition. This PR proposes an additional
condition for repositories: `PrimaryKeyCondition`. This gives clarity on
the required IDs for these operations.
- Added couple of helpers to the repository package, to allow more DRY
code.
- getOne / getMany: generic functions for query execution and scanning.
- checkRestrictingColumns, checkPkCondition: simplify condition
checking, instead of using ladders of conditionals.
- Added a couple of helpers to the repository test package:
  - Transaction, savepoint and rollback helpers.
- Create instance and organization helpers for objects that depend on
them (like projects).

# Additional Context

- after https://github.com/zitadel/zitadel/pull/10809
- closes #10765
2025-10-01 09:47:04 +00:00
Max Peintner
28db24fa67 fix(login): Organization domain scope, Support for External Passkey Registration (#10729)
Closes #10727
Closes #10577

# Which Problems Are Solved

This PR fixes the organization domain scope when provided and introduces
a deep-link feature for external applications, that sends users directly
into passkey registration flow using either session-based or sessionless
flows. Previously, the `/passkey/set` page only supported session-based
registration, limiting external application integration scenarios.

The `/passkey/set` page now supports:
- `code` search parameter for automatic passkey registration
- `userId` parameter for sessionless flows (similar to `/verify` and
`/password/set` pages)
- Auto-submit functionality when verification codes are provided

# How the Problems Are Solved

The organization scope is fixed by the backend handler for OIDC flows,
now correctly submitting a `suffix` queryparam to the /loginname url
which is used to show in the input field.

The passkey code support is implemented by support multiple integration
patterns:
- **Session-based**: `/passkey/set?sessionId=123&code=abc123` (existing
flow)
- **Sessionless**: `/passkey/set?userId=123456&code=abc123` (new flow)

External Application Integration Flow
1. External app triggers passkey register and obtains code
2. User verification link containing `userId`, `code` and `id`
parameters
3. User clicks link → `/passkey/set?userId=123&code=abc&id=123`
4. Page loads user information using `userId` parameter
5. Auto-submit triggers passkey registration when `code` and `id` is
present
6. User completes WebAuthn request
7. Passkey is registered and user continues authentication flow

This enables external applications to seamlessly integrate passkey
registration into their user onboarding
2025-09-30 17:58:32 +02:00
Max Peintner
09d09ab337 fix(login): host utility to provide correct host behind proxies (#10770)
<!--
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 deploying the login application behind proxies or using Vercel
rewrites (e.g., `zitadel.com/login` → `login-zitadel-qa.vercel.app`),
the application was using the internal rewritten host instead of the
original user-facing host. This caused several issues:

1. **Broken Password Reset Emails**: Email links contained internal
hosts like `login-zitadel-qa.vercel.app` instead of `zitadel.com`
2. **Inconsistent User Experience**: Users would see different domains
in various parts of the flow
3. **Security Concerns**: Internal infrastructure details were exposed
to end users
4. **Scattered Logic**: Host detection logic was duplicated across
multiple files with inconsistent error handling

# How the Problems Are Solved

Created comprehensive host detection utilities in `/lib/server/host.ts`
and `/lib/client/host.ts`:

**Server-side utilities:**
- `getOriginalHost()` - Returns the original user-facing host
- `getOriginalHostWithProtocol()` - Returns host with proper protocol
(http/https)
2025-09-23 16:21:01 +00:00
Max Peintner
637b370c17 chore(login): Extract auth flow utilities and eliminate RSC request interference (#10644)
The /login route was experiencing issues with React Server Component
(RSC) requests interfering with one-time authentication callbacks. When
users navigated to /login via client-side routing (router.push()),
Next.js automatically triggered _rsc requests that could consume
single-use createCallback tokens, breaking OIDC and SAML authentication
flows.

# Which Problems Are Solved

When users attempt to log in, Next.js automatically makes requests with
the `_rsc=1` query parameter for React Server Components. The current
implementation treats these as server errors:

```typescript
// Before
if (_rsc) {
  return NextResponse.json({ error: "No _rsc supported" }, { status: 500 });
}
```

This results in:
- Spurious 500 error logs polluting monitoring systems
- False alerts for server failures 
- Difficulty distinguishing real issues from benign RSC requests

# How the Problems Are Solved

This PR implements a comprehensive refactoring that:

- Eliminates RSC interference by providing server actions for internal
auth flow completion
- Separates concerns between external flow initiation and internal flow
completion
- Extracts shared utilities to improve code maintainability and
reusability
- Maintains full backward compatibility for external applications

# Additional Context

## New Architecture
- auth-flow.ts: Shared utilities for auth flow completion with RSC
protection
- flow-initiation.ts: Extracted OIDC/SAML flow initiation logic (~400
lines)
- auth.ts: Server actions for internal components

## Route Handler Simplification
- route.ts: Reduced from ~350 lines to ~75 lines
- External-only focus: Now handles only flow initiation for external
applications
- Removed completion logic: External apps use their own callback URLs
- Enhanced validation: Early RSC blocking and parameter validation

## Flow Logic Improvements
- Early return patterns: Guard clauses eliminate deep nesting
- Better error handling: Specific error messages for different failure
modes
- Fixed SAML flow: Addressed incomplete logic
- Consistent session handling: Unified approach across OIDC and SAML
2025-09-22 16:09:20 +00:00
Max Peintner
0a31f4ba2b fix(login): remove image optimization entirely (#10702)
This PR completely removes Next.js image optimization from the login app
by replacing all next/image components with standard HTML <img> tags and
removing the image optimization configuration.

Closes https://github.com/zitadel/zitadel-charts/issues/381

# Which Problems Are Solved

Users were encountering issue when loading images in dedicated
environments. These happened due to nextjs imaging optimizations
creating different paths for images.

# How the Problems Are Solved

- Removed Next.js Image Optimization Config
- Removed images: { unoptimized: true } configuration from
[next.config.mjs](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html)
This config was redundant since we no longer use next/image components
- Replaced next/image with standard <img> tags
2025-09-22 11:49:21 +00:00
Max Peintner
a9cd3ff9c0 fix(login): Safari Cookie Issues in Development Mode (#10594)
Safari was not creating session cookies during local development,
causing authentication failures. This was due to nextjs default setting
of SameSite cookie property.
We explicitly set "strict" for session cookies now.

Closes #10473 

# Which Problems Are Solved

Authentication Issues with Safari in local development

# How the Problems Are Solved

- Cleaner API: Replaced confusing sameSite boolean/string parameters
with iFrameEnabled boolean
- Better logic flow:

iFrameEnabled: true → sameSite: "none" (for iframe embedding)
Production → sameSite: "strict" (maximum security)
2025-09-11 15:01:24 +00:00
Max Peintner
1a42e99329 chore(login): Remove Vercel Analytics from login application (#10701)
This PR removes the Vercel Analytics integration from the login
application to reduce external dependencies and improve privacy.

# Which Problems Are Solved

cleaner csp

# How the Problems Are Solved

- Removed dependency: Uninstalled @vercel/analytics package from
package.json
- Updated layout component: Removed Analytics import and component usage
from layout.tsx
- Updated Content Security Policy: Removed Vercel domains
(https://va.vercel-scripts.com and https://vercel.com) from CSP
configuration in csp.js
2025-09-11 12:10:09 +00:00
Max Peintner
b6cbb68428 fix(login): MFA session validation to support multiple authentication methods (#10610)
Fixed an issue in `isSessionValid()` where users with multiple
configured MFA methods (e.g., TOTP and U2F) would have their sessions
incorrectly invalidated. The function previously used exclusive if-else
logic that only checked the first matching method, causing validation to
fail even when other configured methods were successfully verified.

Closes #10529 

# Which Problems Are Solved

[#10529](https://github.com/zitadel/zitadel/issues/10529)

# How the Problems Are Solved

- Replaced exclusive if-else if chain with inclusive validation logic
- Session is now considered valid if ANY configured MFA method has been
verified
- Improved error logging to show all configured methods and their
verification status

Example: A user with both TOTP and U2F configured can now successfully
authenticate using either method, whereas previously the session would
be invalid if they used U2F but TOTP was checked first.
2025-09-11 10:36:39 +02:00
Max Peintner
b9b9baf67f fix: Registration Form Legal Checkbox Logic (#10597)
Closes #10498

The registration form's legal checkboxes had incorrect validation logic
that prevented users from completing registration when only one legal
document (ToS or Privacy Policy) was configured, or when no legal
documents were required.

additionally removes a duplicate description for "or use Identity
Provider"

# Which Problems Are Solved

Having only partial legal documents was blocking users to register. The
logic now conditionally renders checkboxes and checks if all provided
documents are accepted.

# How the Problems Are Solved

- Fixed checkbox validation: Now properly validates based on which legal
documents are actually available
- acceptance logic: Only requires acceptance of checkboxes that are
shown
- No legal docs support: Users can proceed when no legal documents are
configured
- Proper state management: Fixed checkbox state tracking and mixed-up
test IDs

---------

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
2025-09-09 07:37:32 +00:00
Max Peintner
adaa6a8de6 fix(login): integration tests failing due to React 19 SSR errors (#10613)
# Which Problems Are Solved

Integration tests were failing with Minified React error 419 caused by
React 19 Suspense boundary issues during server-side rendering (SSR) to
client-side rendering (CSR) transitions.

# How the Problems Are Solved

The fix handles infrastructure-level SSR errors gracefully while
maintaining proper error detection for actual application issues.

- Added Cypress error handling for React 19 SSR hydration errors that
don't affect functionality

# Additional Changes

Enhanced Next.js configuration with React 19 compatibility
optimizations:
- `optimizePackageImports`: @radix-ui/react-tooltip and @heroicons/react
can have large bundle sizes if not optimized. Such packages are
suggested to be optimized in
https://nextjs.org/docs/app/api-reference/config/next-config-js/optimizePackageImports
- `poweredByHeader`: Not that important. Benefits are smaller HTTP
headers, Tiny bandwidth savings, and more professional appearance due to
cleaner response headers, added it as a "security best practice".


# Additional Context

- Replaces #10611
2025-09-01 16:16:18 +02:00
Adam Kida
832e78f9bc feat(typescript): add i18n for input labels in Login V2 (#10233)
# Which Problems Are Solved

- Most inputs have hardcoded label

# How the Problems Are Solved

- add usage of i18n library for every label
- add labels to i18n translation files

# Additional Changes

- fixed key used in `device-code-form.tsx` by submit button
- `v2-default.json` was update and contains all values from login app
not only newly added key for labels.

# Additional Context

N.A

---------

Co-authored-by: David Skewis <david@zitadel.com>
Co-authored-by: Max Peintner <max@caos.ch>
2025-08-29 05:12:12 +00:00
Max Peintner
6699a6f966 fix(login): CSP img-src to allow instance assets (#10579)
Fix CSP img-src to allow ZITADEL instance assets

# Which Problems Are Solved

Login app was failing to load images (logos, branding assets) from
ZITADEL instances due to Content Security Policy restrictions. The CSP
img-src directive only allowed 'self' and https://vercel.com, blocking
images from ZITADEL domains like https://login-*.zitadel.app.

# How the Problems Are Solved

- Dynamic CSP configuration: Extract hostname from ZITADEL_API_URL
environment variable
- Fallback support: Use *.zitadel.cloud wildcard when no specific URL is
configured
- Environment-aware: Works across dev/staging/prod without hardcoded
domains
2025-08-27 10:38:15 +02:00
Nils
7a9cc5c456 fix(loginV2): Disable image optimization (#10508)
<!--
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

Next.js's Image Optimization feature requires that hostnames for remote
images be explicitly defined in the `next.config.js` file via
`remotePatterns`. This configuration is static and evaluated at **build
time**.

However, the `ZITADEL_API_URL`, which is supposed to be used for
additional whitelisted hostnames, is a dynamic environment variable only
known at **run time**. This creates a fundamental conflict, making it
impossible to add the user-provided URL to the configuration when
building the public Docker image. Consequently, images like instance
logos fail to load.

The existing workaround uses a permissive wildcard pattern
(`*.zitadel.*`). This is a significant security risk, as it could allow
malicious actors to abuse the server as an open image-resizing proxy,
leading to potential denial-of-service (DDoS) attacks or excessive
costs.

# How the Problems Are Solved

This change disables the Next.js Image Optimization feature entirely by
setting `unoptimized: true` in the `images` configuration.

By doing this, Next.js will no longer attempt to optimize, cache, or
validate remote image sources. Instead, it will pass the original image
URL directly to the client. This approach resolves the issue by:

1. **Eliminating the need for `remotePatterns`**, which bypasses the
build-time vs. run-time configuration conflict.
2. **Improving security** by removing the overly permissive wildcard
pattern.
3.  **Ensuring functionality**, as remote images now load correctly.

The trade-off is the loss of performance benefits from Next.js image
optimization, but I see this as an acceptable compromise to restore
essential functionality and secure the application.


Fixes #10456

Co-authored-by: Max Peintner <max@caos.ch>
2025-08-25 13:53:21 +00:00
Max Peintner
b23c0bc6ad fix(login): add email verification check before callback (#10516)
Closes https://github.com/zitadel/typescript/issues/539

This PR adds an additional email verification check before completing an
auth flow, if the environment configuration `EMAIL_VERIFICATION` asks
for it.

# Which Problems Are Solved

https://github.com/zitadel/typescript/issues/539

# How the Problems Are Solved

Adds an additional check before completing an auth flow
2025-08-25 11:39:37 +00:00
Max Peintner
772e9c5e3d fix(login): use translation title key prop to set page title (#10537)
This PR sets the page title to the same title as the respective pages
and introduces a default title ("Login with Zitadel").
Closes #10282 

# Which Problems Are Solved

Missing page title on pages.

# How the Problems Are Solved

Using the hosted translation service, we load and merge properties to
set the page title

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-08-22 10:59:13 +00:00
Max Peintner
98fb8b4209 fix(login): use /logout/done as success page, accept post_logout_redirect param as post logout uri (#10500)
Closes #10413

This PR changes the logout success page of the V2 login to
`/logout/done` and accepts both `post_logout_redirect` as well as
`post_logout_redirect_uri` as a param for the post logout url.

# Which Problems Are Solved

The new Login V2 aligns with the login V1  now.
Accepts `post_logout_redirect` as well as `post_logout_redirect_uri` as
a param for the post logout url.

# How the Problems Are Solved

Both search params are now accepted.
2025-08-18 07:38:37 +00:00
Jonas Badstübner
a718267191 fix(loginV2): hide sign-in-with-idp if none are configured (#10402)
<!--
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

Don't show the external IdP section, if none are configured.

# How the Problems Are Solved

- Checks if the length of `identityProviders` is non-empty.

# Additional Changes

- Added 2 additional null-checks for `identityProviders`

# Additional Context

- Closes #10401

Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-08-15 12:00:16 +00:00
Max Peintner
0318edcd3b fix(login): user discovery - ignore case for loginname, email (#10475)
# Which Problems Are Solved

The new login UI user case sensitive matching for usernames and email
addresses. This is different from the v1 login and not expected by
customers, leading to not found user errors.

# How the Problems Are Solved

The user search is changed to case insensitive matching.

# Additional Changes

None

# Additional Context

- reported by a customer
- requires backport to 4.x

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-08-15 08:30:46 +00:00
Max Peintner
a48cacfb02 fix(login): idp redirect (#10482)
This PR fixes an issue where a user was not redirected to an IDP
correctly if the user has entered the loginname and has an IDP as single
auth method
2025-08-14 13:42:33 +00:00
Max Peintner
5cb0f675cd chore: update lockfile to reflect 1.3.1 for packages (#10471)
this updates the lockfile to represent the latest package version for
latest
2025-08-13 11:53:57 +02:00
Elio Bischof
c5080463aa chore: retry login integration tests (#10422)
# Which Problems Are Solved

The login integration action page load in the idp test times out
sometimes.
Also, the debug steps fail, which cause confusion about why the pipeline
check failed.

# How the Problems Are Solved

- We retry failed tests twice, which should alleviate flakiness because
of eventual consistency. This is fine for now, because typically, a user
doesn't send input as fast as the tests do.
- The compose file path is fixed.
- ~~As suggested in the cypress error logs, we increase the
pageLoadTimeout.~~ The increased pageLoadTimeout didn't help.

# Additional Context

- Example of a failing check:
https://github.com/zitadel/zitadel/actions/runs/16829948857/attempts/1

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Max Peintner <max@caos.ch>
2025-08-13 08:44:57 +00:00
Elio Bischof
b02a68f7cf chore: update login lock file (#10466)
# Which Problems Are Solved

Updates the pnpm lockfile for the login repo.

# How the Problems Are Solved

Used the login dev container and ran `pnpm i`

# Additional Context

From this branch, `make login_push
LOGIN_REMOTE_BRANCH=mirror-zitadel-repo` was executed to sync the login
code with https://github.com/zitadel/typescript/pull/573

Co-authored-by: Max Peintner <max@caos.ch>
2025-08-13 08:23:50 +00:00
David Skewis
9ed0daaf8c fix: add form-data override (#10419)
# Which Problems Are Solved

- form-data Math.random() vulnerability

# How the Problems Are Solved

- Overrides the form-data usage in pnpm to a patched version

# Additional Context

CVE ID: https://github.com/advisories/GHSA-fjxv-7rqg-78g4
GHSA ID: https://github.com/advisories/GHSA-fjxv-7rqg-78g4
2025-08-08 16:10:12 +00:00
Elio Bischof
e210d0a16a chore: fix login integration (#10318)
# Which Problems Are Solved

Login integration tests are not executed in the pipeline

# How the Problems Are Solved

The login integration tests are fixed and added as a pipeline workflow.
It  tests against the built login docker image.
On pipeline failures, developers are guided on how to fix them using a
dev container configured for this purpose.

# Additional Changes

- email domains are replaced by example.com. In case the tests were
accidentally run against a cloud instance, it wouldn't cause bounces.
- pnpm is upgraded, because the --filter argument doesn't work for the
install command on the old version.
- The login Dockerfile is optimized for docker image builds

# Additional Changes From Review for
https://github.com/zitadel/zitadel/pull/10305

These changes were requested from @peintnermax 

- The base dev container starts without any services besides the
database and the dev container itself
- CONTRIBUTING.md is restructured
- To reproduce pipeline checks, only the devcontainer CLI and Docker are
needed. This is described in the CONTRIBUTING.md
- The convenience npm script "generate" is added

# Additional Context

- Follow-up for PR https://github.com/zitadel/zitadel/pull/10305
- Base for https://github.com/zitadel/zitadel/issues/10277
2025-08-05 15:59:30 +00:00
Elio Bischof
dcdea5a4fe fix: fix login image (#10355)
# Which Problems Are Solved

The broken login image is fixed.

# How the Problems Are Solved

The most important learnings from
https://github.com/zitadel/zitadel/pull/10318 are applied:
- Path in entrypoint is fixed: `exec node /runtime/apps/login/server.js`
- .dockerignore is updated so CSS styles are built into the image
- `source: .` is passed to the docker-bake action. Without this,
docker-bake builds from a remote context, which seems to be slow and not
updated on new PR commits. Looks like the bake action uploads an
artifact that [conflicts with the compile
workflow](https://github.com/zitadel/zitadel/actions/runs/16620417216/job/47023478437).
Therefore, a pattern is added to the compile workflow so only relevant
artifacts are selected.
2025-07-31 07:51:26 +00:00
Max Peintner
e4f633bcb3 chore: cleanup scripts, v1.3.1 @zitadel/client @zitadel/proto (#10329)
This PR includes scripts for cleaning up workspaces, and changes the
versions of @zitadel/client and /proto to v1.3.0
2025-07-28 13:32:41 +02:00
Max Peintner
c46fd01947 fix(packages): cjs, and module resolution fix (#10322)
This PR introduces CJS support for @zitadel/client and @zitadel/proto
from https://github.com/zitadel/zitadel/pull/10290
and fixes a module resolution error of @zitadel/client

---------

Co-authored-by: reluc <relu.cri@gmail.com>
2025-07-25 11:42:48 +00:00
Elio Bischof
b43c627c74 chore: remove redundant readme (#10324)
# Which Problems Are Solved

Since #10305 we have the following two files in `/apps/login`
- /apps/login/README.md
- /apps/login/readme.md

This confused case insensitive file systems, causing strange Git
behavior.

# How the Problems Are Solved

We remove the obsolete /apps/login/README.md file.
2025-07-24 22:29:38 +00:00
Elio Bischof
b10455b51f chore: reproducible pipeline with dev containers (#10305)
# Which Problems Are Solved

- The previous monorepo in monorepo structure for the login app and its
related packages was fragmented, complicated and buggy.
- The process for building and testing the login container was
inconsistent between local development and CI.
- Lack of clear documentation as well as easy and reliable ways for
non-frontend developers to reproduce and fix failing PR checks locally.

# How the Problems Are Solved

- Consolidated the login app and its related npm packages by moving the
main package to `apps/login/apps/login` and merging
`apps/login/packages/integration` and `apps/login/packages/acceptance`
into the main `apps/login` package.
- Migrated from Docker Compose-based test setups to dev container-based
setups, adding support for multiple dev container configurations:
  - `.devcontainer/base`
  - `.devcontainer/turbo-lint-unit`
  - `.devcontainer/turbo-lint-unit-debug`
  - `.devcontainer/login-integration`
  - `.devcontainer/login-integration-debug`
- Added npm scripts to run the new dev container setups, enabling exact
reproduction of GitHub PR checks locally, and updated the pipeline to
use these containers.
- Cleaned up Dockerfiles and docker-bake.hcl files to only build the
production image for the login app.
- Cleaned up compose files to focus on dev environments in dev
containers.
- Updated `CONTRIBUTING.md` with guidance on running and debugging PR
checks locally using the new dev container approach.
- Introduced separate Dockerfiles for the login app to distinguish
between using published client packages and building clients from local
protos.
- Ensured the login container is always built in the pipeline for use in
integration and acceptance tests.
- Updated Makefile and GitHub Actions workflows to use
`--frozen-lockfile` for installing pnpm packages, ensuring reproducible
installs.
- Disabled GitHub release creation by the changeset action.
- Refactored the `/build` directory structure for clarity and
maintainability.
- Added a `clean` command to `docks/package.json`.
- Experimentally added `knip` to the `zitadel-client` package for
improved linting of dependencies and exports.

# Additional Changes

- Fixed Makefile commands for consistency and reliability.
- Improved the structure and clarity of the `/build` directory to
support seamless integration of the login build.
- Enhanced documentation and developer experience for running and
debugging CI checks locally.

# Additional Context

- See updated `CONTRIBUTING.md` for new local development and debugging
instructions.
- These changes are a prerequisite for further improvements to the CI
pipeline and local development workflow.
- Closes #10276
2025-07-24 14:22:32 +02:00