diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b5c16134db..8f8b1c5425 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "features": { "ghcr.io/devcontainers/features/go:1": { - "version": "1.20" + "version": "1.21" }, "ghcr.io/devcontainers/features/node:1": { "version": "18" diff --git a/Makefile b/Makefile index ec88b80a0b..6495993ede 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ gen_authopt_path := "$(go_bin)/protoc-gen-authoption" gen_zitadel_path := "$(go_bin)/protoc-gen-zitadel" now := $(shell date --rfc-3339=seconds | sed 's/ /T/') -VERSION ?= development +VERSION ?= development-$(now) COMMIT_SHA ?= $(shell git rev-parse HEAD) .PHONY: compile diff --git a/README.md b/README.md index 3756fef915..96c6bd95e0 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ GitHub contributors - - + +

diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml index 10424663fe..debcd90518 100644 --- a/cmd/defaults.yaml +++ b/cmd/defaults.yaml @@ -415,7 +415,7 @@ SystemDefaults: # https://passlib.readthedocs.io/en/stable/modular_crypt_format.html # # Supported verifiers: (uncomment to enable) - # Verifiers: + Verifiers: # - "argon2" # verifier for both argon2i and argon2id. # - "bcrypt" # - "md5" diff --git a/console/src/app/modules/accounts-card/accounts-card.component.html b/console/src/app/modules/accounts-card/accounts-card.component.html index b4a9439c36..1ed1649545 100644 --- a/console/src/app/modules/accounts-card/accounts-card.component.html +++ b/console/src/app/modules/accounts-card/accounts-card.component.html @@ -31,14 +31,9 @@

{{ session.displayName ? session.displayName : session.userName }} {{ session.loginName }} - {{ 'USER.STATE.' + session.authState | translate }} + {{ + 'USER.STATE.' + session.authState | translate + }}
keyboard_arrow_right diff --git a/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.ts b/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.ts index f40be9038c..46d0232b86 100644 --- a/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.ts +++ b/console/src/app/pages/actions/add-action-dialog/add-action-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { MatLegacyDialog as MatDialog, @@ -7,7 +7,7 @@ import { } from '@angular/material/legacy-dialog'; import { Duration } from 'google-protobuf/google/protobuf/duration_pb'; -import { mapTo } from 'rxjs'; +import { mapTo, Subject, takeUntil } from 'rxjs'; import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component'; import { Action } from 'src/app/proto/generated/zitadel/action_pb'; import { CreateActionRequest, UpdateActionRequest } from 'src/app/proto/generated/zitadel/management_pb'; @@ -19,15 +19,18 @@ import { ToastService } from 'src/app/services/toast.service'; templateUrl: './add-action-dialog.component.html', styleUrls: ['./add-action-dialog.component.scss'], }) -export class AddActionDialogComponent implements OnInit { +export class AddActionDialogComponent implements OnInit, OnDestroy { public id: string = ''; public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true)); + private destroy$: Subject = new Subject(); + private showAllowedToFailWarning: boolean = true; + public form: FormGroup = new FormGroup({ name: new FormControl('', []), script: new FormControl('', []), durationInSec: new FormControl(10, []), - allowedToFail: new FormControl(false, []), + allowedToFail: new FormControl(true, []), }); constructor( private toast: ToastService, @@ -47,6 +50,21 @@ export class AddActionDialogComponent implements OnInit { }); this.id = action.id; } + + this.form.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(({ allowedToFail }) => { + if (!allowedToFail && this.showAllowedToFailWarning) { + this.dialog.open(WarnDialogComponent, { + data: { + confirmKey: 'ACTIONS.OK', + titleKey: 'FLOWS.ALLOWEDTOFAILWARN.TITLE', + descriptionKey: 'FLOWS.ALLOWEDTOFAILWARN.DESCRIPTION', + }, + width: '400px', + }); + + this.showAllowedToFailWarning = false; + } + }); } ngOnInit(): void { @@ -71,6 +89,11 @@ export class AddActionDialogComponent implements OnInit { }); } + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } + private showUnsavedDialog(): void { const unsavedChangesDialogRef = this.unsavedChangesDialog.open(WarnDialogComponent, { data: { diff --git a/console/src/app/pages/org-create/org-create.component.html b/console/src/app/pages/org-create/org-create.component.html index 5dafb01429..1672159ca0 100644 --- a/console/src/app/pages/org-create/org-create.component.html +++ b/console/src/app/pages/org-create/org-create.component.html @@ -170,7 +170,7 @@
{{ 'ORG_DETAIL.DETAIL.NAME' | translate }} - +
@@ -182,6 +182,7 @@ class="big-button" cdkFocusInitial type="submit" + data-e2e="create-org-button" > {{ 'ACTIONS.CREATE' | translate }} diff --git a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html index 67ea50c6ed..a83b7a7bc8 100644 --- a/console/src/app/pages/projects/apps/app-detail/app-detail.component.html +++ b/console/src/app/pages/projects/apps/app-detail/app-detail.component.html @@ -427,20 +427,22 @@
-

{{ wellKnownV.key }}

-
-
- -
-
+ +

{{ wellKnownV.key }}

+
+
+ +
+
diff --git a/console/src/app/pages/projects/project-list/project-list.component.ts b/console/src/app/pages/projects/project-list/project-list.component.ts index 8036549ee7..137432bb5b 100644 --- a/console/src/app/pages/projects/project-list/project-list.component.ts +++ b/console/src/app/pages/projects/project-list/project-list.component.ts @@ -60,6 +60,7 @@ export class ProjectListComponent implements OnInit, OnDestroy { public ProjectState: any = ProjectState; public ProjectType: any = ProjectType; private destroy$: Subject = new Subject(); + public INITIAL_PAGE_SIZE: number = 20; constructor( public translate: TranslateService, @@ -84,7 +85,7 @@ export class ProjectListComponent implements OnInit, OnDestroy { break; } - this.getData(type); + this.getData(type, this.INITIAL_PAGE_SIZE, 0); }); } diff --git a/console/src/app/services/environment.service.ts b/console/src/app/services/environment.service.ts index 343cd424b4..b2dbc59515 100644 --- a/console/src/app/services/environment.service.ts +++ b/console/src/app/services/environment.service.ts @@ -28,7 +28,7 @@ interface WellKnown { }) export class EnvironmentService { private environmentJsonPath = './assets/environment.json'; - private wellknownPath = '/.well-known/openid-configuration`'; + private wellknownPath = '/.well-known/openid-configuration'; public auth!: AuthServiceClient; public mgmt!: ManagementServiceClient; public admin!: AdminServiceClient; diff --git a/console/src/assets/i18n/bg.json b/console/src/assets/i18n/bg.json index b3407a41f9..01a19176c3 100644 --- a/console/src/assets/i18n/bg.json +++ b/console/src/assets/i18n/bg.json @@ -736,6 +736,10 @@ "TIMEOUT": "Време за изчакване", "TIMEOUTINSEC": "Изчакване в секунди", "ALLOWEDTOFAIL": "Разрешено да се провали", + "ALLOWEDTOFAILWARN": { + "TITLE": "Предупреждение", + "DESCRIPTION": "Ако деактивирате тази настройка, това може да доведе до това, че потребителите на вашата организация няма да могат да се регистрират. Освен това няма да можете да получите достъп до конзолата, за да деактивирате действието. Препоръчваме ви да създадете администраторски потребител в отделна организация или да тествате скриптове първо в среда за разработка или тестова организация." + }, "SCRIPT": "Скрипт", "FLOWTYPE": "Тип поток", "TRIGGERTYPE": "Тип тригер", @@ -957,8 +961,7 @@ "STATE": { "0": "Не е дефинирано", "1": "Активен", - "2": "Деактивиран", - "3": "Премахнато" + "2": "Деактивиран" }, "MEMBER": { "TITLE": "Мениджъри на организации", diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index daa3b704ee..4d70add212 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -742,6 +742,10 @@ "TIMEOUT": "Timeout", "TIMEOUTINSEC": "Timeout in Sekunden", "ALLOWEDTOFAIL": "Scheitern erlaubt", + "ALLOWEDTOFAILWARN": { + "TITLE": "Warnung", + "DESCRIPTION": "Wenn du diese Einstellung deaktivierst, kann es dazu führen, dass sich Benutzer deiner Organisation nicht mehr anmelden können. Ausserdem kannst du dann nicht mehr auf die Konsole zugreifen, um die Action zu deaktivieren. Wir empfehlen, einen Administratorbenutzer in einer separaten Organisation zu erstellen oder Skripte zuerst in einer Entwicklungsumgebung oder einer Entwicklungsorganisation zu testen." + }, "SCRIPT": "Script", "FLOWTYPE": "Flow Typ", "TRIGGERTYPE": "Trigger Typ", @@ -963,8 +967,7 @@ "STATE": { "0": "Nicht definiert", "1": "Aktiv", - "2": "Inaktiv", - "3": "Entfernt" + "2": "Inaktiv" }, "MEMBER": { "TITLE": "Manager der Organisation verwalten", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index 9c8daa3c30..389461c832 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -743,6 +743,10 @@ "TIMEOUT": "Timeout", "TIMEOUTINSEC": "Timeout in seconds", "ALLOWEDTOFAIL": "Allowed To Fail", + "ALLOWEDTOFAILWARN": { + "TITLE": "Warning", + "DESCRIPTION": "If you disable this setting, it may cause users in your organization to be unable to sign in. Additionally, you will no longer be able to access the console to disable the action. We recommend creating an administrator user in a separate organization or testing scripts first in a development environment or a development organization." + }, "SCRIPT": "Script", "FLOWTYPE": "Flow Type", "TRIGGERTYPE": "Trigger Type", @@ -964,8 +968,7 @@ "STATE": { "0": "Not defined", "1": "Active", - "2": "Deactivated", - "3": "Removed" + "2": "Deactivated" }, "MEMBER": { "TITLE": "Organization Managers", diff --git a/console/src/assets/i18n/es.json b/console/src/assets/i18n/es.json index 5d12e95524..1aaba364c8 100644 --- a/console/src/assets/i18n/es.json +++ b/console/src/assets/i18n/es.json @@ -743,6 +743,10 @@ "TIMEOUT": "Timeout", "TIMEOUTINSEC": "Timeout en segundos", "ALLOWEDTOFAIL": "Permitido el fallo", + "ALLOWEDTOFAILWARN": { + "TITLE": "Advertencia", + "DESCRIPTION": "Si desactiva esta configuración, puede hacer que los usuarios de su organización no puedan iniciar sesión. Además, ya no podrá acceder a la consola para desactivar la acción. Recomendamos crear un usuario administrador en una organización separada o probar scripts primero en un entorno de desarrollo o una organización de desarrollo." + }, "SCRIPT": "Script", "FLOWTYPE": "Tipo de flujo", "TRIGGERTYPE": "Tipo de disparador", @@ -964,8 +968,7 @@ "STATE": { "0": "No definida", "1": "Activa", - "2": "Desactivada", - "3": "Eliminada" + "2": "Desactivada" }, "MEMBER": { "TITLE": "Mánagers de la organización", diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json index c5a8f2b60a..469cd3ca69 100644 --- a/console/src/assets/i18n/fr.json +++ b/console/src/assets/i18n/fr.json @@ -742,6 +742,10 @@ "TIMEOUT": "Délai d'attente", "TIMEOUTINSEC": "Délai en secondes", "ALLOWEDTOFAIL": "Autorisé à échouer", + "ALLOWEDTOFAILWARN": { + "TITLE": "Avertissement", + "DESCRIPTION": "Si vous désactivez ce paramètre, cela peut empêcher les utilisateurs de votre organisation de se connecter. De plus, vous ne pourrez plus accéder à la console pour désactiver l'action. Nous vous recommandons de créer un utilisateur administrateur dans une organisation distincte ou de tester les scripts d'abord dans un environnement de développement ou une organisation de développement." + }, "SCRIPT": "Script", "FLOWTYPE": "Type de flux", "TRIGGERTYPE": "Type de déclencheur", @@ -963,8 +967,7 @@ "STATE": { "0": "Non défini", "1": "Actif", - "2": "Désactivé", - "3": "Supprimé" + "2": "Désactivé" }, "MEMBER": { "TITLE": "Gestionnaires de l'organisation", diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json index c1fc647d16..6605a8d91a 100644 --- a/console/src/assets/i18n/it.json +++ b/console/src/assets/i18n/it.json @@ -741,6 +741,10 @@ "TIMEOUT": "Timeout", "TIMEOUTINSEC": "Timeout in secondi", "ALLOWEDTOFAIL": "Può fallire", + "ALLOWEDTOFAILWARN": { + "TITLE": "Attenzione", + "DESCRIPTION": "Se disabiliti questa impostazione, potrebbe impedire agli utenti della tua organizzazione di accedere. Inoltre, non sarai più in grado di accedere alla console per disabilitare l'azione. Ti consigliamo di creare un utente amministratore in un'organizzazione separata o di testare gli script prima in un ambiente di sviluppo o in un'organizzazione di sviluppo." + }, "SCRIPT": "Script", "FLOWTYPE": "Tipo processo", "TRIGGERTYPE": "Tipo trigger", @@ -963,8 +967,7 @@ "STATE": { "0": "Non definito", "1": "Attivo", - "2": "Disattivato", - "3": "Rimosso" + "2": "Disattivato" }, "MEMBER": { "TITLE": "Manager dell'organizzazione", diff --git a/console/src/assets/i18n/ja.json b/console/src/assets/i18n/ja.json index 73d3cef814..623f802469 100644 --- a/console/src/assets/i18n/ja.json +++ b/console/src/assets/i18n/ja.json @@ -743,6 +743,10 @@ "TIMEOUT": "タイムアウト", "TIMEOUTINSEC": "数秒でタイムアウト", "ALLOWEDTOFAIL": "失敗を許可", + "ALLOWEDTOFAILWARN": { + "TITLE": "警告", + "DESCRIPTION": "この設定を無効にすると、組織のユーザーがログインできなくなる可能性があります。さらに、アクションを無効にするためにコンソールにアクセスできなくなります。開発環境または開発組織でスクリプトを最初にテストするか、別の組織で管理者ユーザーを作成することをお勧めします。" + }, "SCRIPT": "スクリプトp", "FLOWTYPE": "フロータイプ", "TRIGGERTYPE": "トリガータイプ", @@ -964,8 +968,7 @@ "STATE": { "0": "未定義", "1": "アクティブ", - "2": "非アクティブ", - "3": "削除" + "2": "非アクティブ" }, "MEMBER": { "TITLE": "組織マネージャー", diff --git a/console/src/assets/i18n/mk.json b/console/src/assets/i18n/mk.json index caac4b6b5c..65af79503c 100644 --- a/console/src/assets/i18n/mk.json +++ b/console/src/assets/i18n/mk.json @@ -743,6 +743,10 @@ "TIMEOUT": "Временски лимит", "TIMEOUTINSEC": "Временски лимит во секунди", "ALLOWEDTOFAIL": "Дозволено да не успее", + "ALLOWEDTOFAILWARN": { + "TITLE": "Предупредување", + "DESCRIPTION": "Ако ја деактивирате оваа поставка, тоа може да доведе до тоа што корисниците на вашата организација нема да можат да се најават. Покрај тоа, нема да можете повеќе да пристапите до конзолата за да ја деактивирате акцијата. Препорачуваме да создадете администраторски корисник во посебна организација или да ги тестирате скриптите прво во развојна средина или развојна организација." + }, "SCRIPT": "Скрипта", "FLOWTYPE": "Тип на Flow", "TRIGGERTYPE": "Тип на тригер", diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json index a29ec6ad95..f594d9993a 100644 --- a/console/src/assets/i18n/pl.json +++ b/console/src/assets/i18n/pl.json @@ -742,6 +742,10 @@ "TIMEOUT": "Timeout", "TIMEOUTINSEC": "Timeout w sekundach", "ALLOWEDTOFAIL": "Dozwolone na porażkę", + "ALLOWEDTOFAILWARN": { + "TITLE": "Ostrzeżenie", + "DESCRIPTION": "Jeśli wyłączysz tę opcję, może to spowodować, że użytkownicy Twojej organizacji nie będą mogli się zalogować. Ponadto nie będziesz już mógł uzyskać dostępu do konsoli, aby wyłączyć akcję. Zalecamy utworzenie administratora w oddzielnej organizacji lub przetestowanie skryptów najpierw w środowisku deweloperskim lub organizacji deweloperskiej." + }, "SCRIPT": "Skrypt", "FLOWTYPE": "Typ Przepływu", "TRIGGERTYPE": "Typ Wyzwalacza", @@ -963,8 +967,7 @@ "STATE": { "0": "Nieokreślone", "1": "Aktywne", - "2": "Dezaktywowane", - "3": "Usunięte" + "2": "Dezaktywowane" }, "MEMBER": { "TITLE": "Menadżerowie organizacji", diff --git a/console/src/assets/i18n/pt.json b/console/src/assets/i18n/pt.json index 4a72278b70..29e9e34f61 100644 --- a/console/src/assets/i18n/pt.json +++ b/console/src/assets/i18n/pt.json @@ -743,6 +743,10 @@ "TIMEOUT": "Tempo Limite", "TIMEOUTINSEC": "Tempo Limite em segundos", "ALLOWEDTOFAIL": "Permitido Falhar", + "ALLOWEDTOFAILWARN": { + "TITLE": "Aviso", + "DESCRIPTION": "Se você desabilitar esta configuração, pode fazer com que os usuários da sua organização não possam fazer login. Além disso, você não poderá mais acessar a console para desabilitar a ação. Recomendamos criar um usuário administrador em uma organização separada ou testar scripts primeiro em um ambiente de desenvolvimento ou uma organização de desenvolvimento." + }, "SCRIPT": "Script", "FLOWTYPE": "Tipo de Fluxo", "TRIGGERTYPE": "Tipo de Gatilho", diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json index 3a3a5c2115..23cacbc444 100644 --- a/console/src/assets/i18n/zh.json +++ b/console/src/assets/i18n/zh.json @@ -742,6 +742,10 @@ "TIMEOUT": "超时时间", "TIMEOUTINSEC": "以秒为单位的超时时间", "ALLOWEDTOFAIL": "允许失败", + "ALLOWEDTOFAILWARN": { + "TITLE": "警告", + "DESCRIPTION": "如果您禁用此设置,可能会导致您的组织中的用户无法登录。此外,您将无法再访问控制台以禁用该操作。我们建议您在单独的组织中创建管理员用户,或在开发环境或开发组织中先测试脚本。" + }, "SCRIPT": "脚本", "FLOWTYPE": "流程类型", "TRIGGERTYPE": "触发器类型", @@ -963,8 +967,7 @@ "STATE": { "0": "未定义", "1": "启用", - "2": "停用", - "3": "移除" + "2": "停用" }, "MEMBER": { "TITLE": "组织管理者", diff --git a/docs/docs/apis/actions/objects.md b/docs/docs/apis/actions/objects.md index dd8a9b648d..2f95b02efa 100644 --- a/docs/docs/apis/actions/objects.md +++ b/docs/docs/apis/actions/objects.md @@ -43,10 +43,10 @@ title: Objects ## user grant -- `projectId` *string* +- `projectID` *string* Required. Id of the project to be granted -- `projectGrantId` *string* - If the grant is for a project grant +- `projectGrantID` *string* + Optional. If the grant is for a project grant, include projectGrantID - `roles` Array of *string* Containing the roles diff --git a/docs/docs/apis/introduction.mdx b/docs/docs/apis/introduction.mdx index c17048083e..5f56fd811e 100644 --- a/docs/docs/apis/introduction.mdx +++ b/docs/docs/apis/introduction.mdx @@ -6,38 +6,72 @@ sidebar_label: Overview import { ApiCard } from "../../src/components/apicard"; import Column from "../../src/components/column"; -## APIs +ZITADEL exposes all features via different gRPC and REST APIs and provides SDKs for popular languages and frameworks. -ZITADEL provides five APIs for different use cases. Four of these APIs are built with GRPC and generate a REST service. -Each service's proto definition is located in the source control on GitHub. -As we generate the REST services and Swagger file out of the proto definition we recommend that you rely on the proto file. -We annotate the corresponding REST methods on each possible call as well as the AuthN and AuthZ requirements. -The last API (assets) is only a REST API because ZITADEL uses multipart form data for certain elements. +The [OpenID Connect & OAuth endpoints](/docs/apis/openidoauth/endpoints) and [SAML 2.0 endpoints](/docs/apis/saml/endpoints) are implemented and exposed according to the specific standards. Managing resources such as users, organizations, instances, or settings must be done with the different [ZITADEL APIs](#zitadel-apis-resource-based). -### Proto +[Actions](/docs/apis/actions/introduction) allow to extend ZITADEL with custom code to change default behaviors or calling external systems. -All of our APIs are generated by proto definitions. You can find all the proto definitions in the [Proto API Definitions](https://github.com/zitadel/zitadel/tree/main/proto/zitadel). +## Authentication & authorization -> More about [Protocol Buffer](https://developers.google.com/protocol-buffers) +ZITADEL implements industry standards such as OpenID Connect, OAuth 2.0, or SAML for authentication. +Please refer to our guides how to [authenticate users](/docs/guides/integrate/human-users) through an interactive authentication process and how to [authenticate service users](/docs/guides/integrate/serviceusers) with a programmatic authentication. -### Swagger Documentation +### OpenID Connect & OAuth -We provide some json files for the swagger documentation of our APIs with the following link: [https://zitadel.cloud/openapi/v2/swagger/](https://zitadel.cloud/openapi/v2/swagger/) +- [OpenID Connect endpoints](/docs/apis/openidoauth/endpoints) definition +- Standard and reserved [scopes reference](/docs/apis/openidoauth/scopes) +- Standard, custom, and reserved [claims reference](/docs/apis/openidoauth/claims) -The easiest way to have a look at them is, to import them in the [Swagger Editor](https://editor.swagger.io/) +The [OIDC Playground](/docs/apis/openidoauth/authrequest) is for testing OpenID authentication requests and their parameters. + +### SAML 2.0 + +- [SAML 2.0 endpoints](/docs/apis/saml/endpoints) definition +- [Custom attributes](https://github.com/zitadel/actions/blob/main/examples/set_custom_attribute.js) can be added with an action + +### Custom + +ZITADEL allows to authenticate users by creating a session with the [Session API](/docs/apis/resources/session_service) or get OIDC authentication request details with the [OIDC service API](/docs/apis/resources/oidc_service). +User authorizations can be [retrieved as roles from our APIs](/docs/guides/integrate/retrieve-user-roles). + +Refer to our guide to learn how to [build your own login UI](/docs/guides/integrate/login-ui) + +## ZITADEL APIs (resource-based) + +ZITADEL provides APIs for each [core resource](/docs/apis/resources): + +- [User](/docs/apis/resources/user_service) +- [Session](/docs/apis/resources/session_service) +- [Settings](/docs/apis/resources/settings_service) + +:::info +We are migrating to a resource-based API approach. +You might need to use the existing [service-based](#zitadel-apis-service-based) APIs for now to manage Organizations, Instances, Assets etc. +::: + +## ZITADEL APIs (service-based) + +:::info Prefer resource-based API +ZITADEL APIs were organized by UseCase/Context, such as Auth API for authenticated users and Management API for organization managers. +This led to confusion about which API to use, particularly for requests that could be useful across multiple APIs but with different filters. +For instance, SearchUsers on an Instance Level or on an Organization Level. + +To address this issue, ZITADEL is migrating to a [resource-based API](#zitadel-apis-resource-based). +:::
-## Authentication +### Authentication The authentication API (aka Auth API) is used for all operations on the currently logged in user. The user id is taken from the sub claim in the token.
-### GRPC +#### GRPC Endpoint: $ZITADEL_DOMAIN/zitadel.auth.v1.AuthService/ @@ -45,7 +79,7 @@ $ZITADEL_DOMAIN/zitadel.auth.v1.AuthService/ Definition: [Auth Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/auth.proto) -### REST +#### REST Endpoint: $ZITADEL_DOMAIN/auth/v1/ @@ -62,7 +96,7 @@ API Reference:
-## Management +### Management The management API is as the name states the interface where systems can mutate IAM objects like, organizations, projects, clients, users and so on if they have the necessary access rights. To identify the current organization you can send a header `x-zitadel-orgid` or if no header is set, the organization of the authenticated user is set. @@ -70,7 +104,7 @@ To identify the current organization you can send a header `x-zitadel-orgid` or
-### GRPC +#### GRPC Endpoint: $ZITADEL_DOMAIN/zitadel.management.v1.ManagementService/ @@ -78,7 +112,7 @@ $ZITADEL_DOMAIN/zitadel.management.v1.ManagementService/ Definition: [Management Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/management.proto) -### REST +#### REST Endpoint: $ZITADEL_DOMAIN/management/v1/ @@ -94,14 +128,14 @@ API Reference:
-## Administration +### Administration This API is intended to configure and manage one ZITADEL instance itself.
-### GRPC +#### GRPC Endpoint: $ZITADEL_DOMAIN/zitadel.admin.v1.AdminService/ @@ -109,7 +143,7 @@ $ZITADEL_DOMAIN/zitadel.admin.v1.AdminService/ Definition: [Admin Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/admin.proto) -### REST +#### REST Endpoint: $ZITADEL_DOMAIN/admin/v1/ @@ -125,7 +159,7 @@ API Reference:
-## System +### System This API is intended to manage the different ZITADEL instances within the system. @@ -134,7 +168,7 @@ Checkout the guide how to [access the ZITADEL System API](/guides/integrate/acce
-### GRPC +#### GRPC Endpoint: $ZITADEL_DOMAIN/zitadel.system.v1.SystemService/ @@ -142,7 +176,7 @@ $ZITADEL_DOMAIN/zitadel.system.v1.SystemService/ Definition: [System Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/system.proto) -### REST +#### REST Endpoint: $ZITADEL_DOMAIN/system/v1/ @@ -158,14 +192,14 @@ API Reference:
-## Assets +### Assets The Assets API allows you to up- and download all kinds of assets. This can be files such as logos, fonts or user avatar.
-### REST +#### REST Endpoint: $ZITADEL_DOMAIN/assets/v1/ @@ -177,11 +211,36 @@ Definition: -## Example + +## API definitions + +Each service's proto definition is located in the source control on GitHub. +As we generate the REST services and Swagger file out of the proto definition we recommend that you rely on the proto file. +We annotate the corresponding REST methods on each possible call as well as the AuthN and AuthZ requirements. +The last API (assets) is only a REST API because ZITADEL uses multipart form data for certain elements. + +### SDKs + +ZITADEL provides some [official and community supported SDKs](/docs/examples/sdks) for multiple languages and frameworks. +Most languages allow you to build a client from proto definitions, which allows you to build your own client in case an SDK is missing. + +### Proto + +All of our APIs are generated by proto definitions. You can find all the proto definitions in the [Proto API Definitions](https://github.com/zitadel/zitadel/tree/main/proto/zitadel). + +> More about [Protocol Buffer](https://developers.google.com/protocol-buffers) + +### Swagger documentation + +We provide some json files for the swagger documentation of our APIs with the following link: [https://zitadel.cloud/openapi/v2/swagger/](https://zitadel.cloud/openapi/v2/swagger/) + +The easiest way to have a look at them is, to import them in the [Swagger Editor](https://editor.swagger.io/) + +### Example See below for an example with the call **GetMyUser**. -```Go +```go //User rpc GetMyUser(google.protobuf.Empty) returns (UserView) { option (google.api.http) = { @@ -207,19 +266,14 @@ In the table below you can see the URI of those calls. ZITADEL hosts everything under a single domain: `{instance}.zitadel.cloud` or your custom domain `$ZITADEL_DOMAIN` -:::note -Changes from ZITADEL V1: -Be aware that issuer, api, accounts and console domains do not exist anymore. -::: - The domain is used as the OIDC issuer and as the base url for the gRPC and REST APIs, the Login and Console UI, which you'll find under `{your_domain}/ui/console/`. -## ZITADEL Path Prefixes +## API path prefixes If you run ZITADEL on a custom domain, you may want to reuse that domain for other applications. For easy copying to your reverse proxy configuration, here is the list of URL path prefixes, ZITADEL uses. -``` +```yaml /zitadel.admin.v1.AdminService/ /admin/v1/ /zitadel.auth.v1.AuthService/ @@ -233,6 +287,15 @@ For easy copying to your reverse proxy configuration, here is the list of URL pa /oidc/v1/ /saml/v2/ /oauth/v2/ +/device +/oidc/v1/ /.well-known/openid-configuration /openapi/ +/idps/callback +/v2beta/ +/zitadel.user.v2beta.UserService/ +/zitadel.session.v2beta.SessionService/ +/zitadel.settings.v2beta.SettingsService/ +/zitadel.oidc.v2beta.OIDCService/ +/zitadel.org.v2beta.OrganizationService/ ``` diff --git a/docs/docs/concepts/features/selfservice.md b/docs/docs/concepts/features/selfservice.md index 1a664e4bce..a39e99ba49 100644 --- a/docs/docs/concepts/features/selfservice.md +++ b/docs/docs/concepts/features/selfservice.md @@ -151,7 +151,9 @@ The current password must be entered first. Users can setup and delete a second factor and FIDO Passkeys (Passwordless). Available authenticators are: -- Mobile one-time password (OTP) (Authenticator Apps) +- Time-based one-time password (TOTP) (Which are Authenticator Apps like Google/Microsoft Authenticator, Authy, etc.) +- One-time password sent as E-Mail +- One-time password sent as SMS - FIDO Universal Second Factor (U2F) (Security Keys, Device, etc.) - FIDO2 WebAuthN (Passkeys) diff --git a/docs/docs/examples/sdks.md b/docs/docs/examples/sdks.md index fc868a08a3..4c56c5053a 100644 --- a/docs/docs/examples/sdks.md +++ b/docs/docs/examples/sdks.md @@ -2,18 +2,23 @@ title: SDKs --- -## ZITADEL SDK +On this page you find our official SDKs, links to supporting frameworks and providers, and resources to help with SDKs. +The SDKs wrap either our [gRPC or REST APIs](/docs/apis/introduction) to provide the client with User Authentication and Management for resources. -| Language / Framework | Link Github | User Authentication | Manage resources | Notes | -|--- | --- | --- | --- | --- | -| .NET | [zitadel-net](https://github.com/smartive/zitadel-net) | ✔️ | ✔️ | `community` | -| Elixir | [zitadel_api](https://github.com/jshmrtn/zitadel_api) | ✔️ | ✔️ | `community` | -| Go | [zitadel-go](https://github.com/zitadel/zitadel-go) | ❌ | ✔️ | `official` | -| JVM | 🚧 [WIP](https://github.com/zitadel/zitadel/discussions/3650) | ❓ | ❓ | TBD | -| Python | 🚧 [WIP](https://github.com/zitadel/zitadel/issues/3675) | ❓ | ❓ | TBD | -| NodeJS | [@zitadel/node](https://www.npmjs.com/package/@zitadel/node) | ❌ | ✔️ | `community` | +## ZITADEL SDKs -## Missing an SDK +| Language / Framework | Link Github | User Authentication | Manage resources | Notes | +|----------------------|---------------------------------------------------------------| --- | --- | --- | +| .NET | [zitadel-net](https://github.com/smartive/zitadel-net) | ✔️ | ✔️ | `community` | +| Elixir | [zitadel_api](https://github.com/jshmrtn/zitadel_api) | ✔️ | ✔️ | `community` | +| Go | [zitadel-go](https://github.com/zitadel/zitadel-go) | ❌ | ✔️ | `official` | +| JVM | 🚧 [WIP](https://github.com/zitadel/zitadel/discussions/3650) | ❓ | ❓ | TBD | +| Python | 🚧 [WIP](https://github.com/zitadel/zitadel/issues/3675) | ❓ | ❓ | TBD | +| NodeJS | [@zitadel/node](https://www.npmjs.com/package/@zitadel/node) | ❌ | ✔️ | `community` | +| Dart | [zitadel-dart](https://github.com/smartive/zitadel-dart) | ❌ | ✔️ | `community` | +| Rust | [zitadel-rust](https://github.com/smartive/zitadel-rust) | ✔️ | ✔️ | `community` | + +## Missing SDK Is your language/framework missing? Fear not, you can generate your gRPC API Client with ease. @@ -83,7 +88,6 @@ Import these files into your project to start interacting with ZITADEL's APIs. While we are not actively maintaining the following projects, it is worth checking out if you're interested in exploring ZITADEL in different programming languages or frameworks. - [NodeJS passport](https://github.com/buehler/node-passport-zitadel) authentication helper -- [Dart library for ZITADEL](https://github.com/smartive/zitadel-dart), contains gRPC and API access elements - [NextAuth Provider for ZITADEL](https://next-auth.js.org/providers/zitadel) If we do not provide an example, SDK or guide, we strongly recommend using existing authentication libraries for your language or framework instead of building your own. diff --git a/docs/docs/guides/integrate/identity-providers/_generic_oidc.mdx b/docs/docs/guides/integrate/identity-providers/_generic_oidc.mdx new file mode 100644 index 0000000000..e2da6fb9f5 --- /dev/null +++ b/docs/docs/guides/integrate/identity-providers/_generic_oidc.mdx @@ -0,0 +1,8 @@ +The Generic OIDC Provider allows you to configure any OIDC compliant identity providers. + +The following information you need to fill out by yourself: + +
  • Name {props.name}
  • +
  • Issuer {props.issuer}
  • +
  • Client-ID {props.clientid}
  • +
  • Scopes: (openid, profile, email is preconfigured)
  • diff --git a/docs/docs/guides/integrate/identity-providers/_intro.mdx b/docs/docs/guides/integrate/identity-providers/_intro.mdx index 01e386ca1d..3605f5bc21 100644 --- a/docs/docs/guides/integrate/identity-providers/_intro.mdx +++ b/docs/docs/guides/integrate/identity-providers/_intro.mdx @@ -6,4 +6,4 @@ In ZITADEL you can connect an Identity Provider (IdP) like {props.provider} to y Also, you can register the IdP to a specific organization only. If you allow so, your organizations members can do the same in self-service.

    -::: +::: \ No newline at end of file diff --git a/docs/docs/guides/integrate/identity-providers/apple.mdx b/docs/docs/guides/integrate/identity-providers/apple.mdx new file mode 100644 index 0000000000..cec4a76a70 --- /dev/null +++ b/docs/docs/guides/integrate/identity-providers/apple.mdx @@ -0,0 +1,88 @@ +--- +title: Configure Apple as Identity Provider +sidebar_label: Apple +--- + +import GeneralConfigDescription from './_general_config_description.mdx'; +import Intro from './_intro.mdx'; +import CustomLoginPolicy from './_custom_login_policy.mdx'; +import IDPsOverview from './_idps_overview.mdx'; +import Activate from './_activate.mdx'; +import TestSetup from './_test_setup.mdx'; + + + +## Apple Configuration + +### Register a new App + +1. Go to the Identifiers of your Apple Developer Account +2. Click the add button "+" on the top left +3. Choose App IDs and click "continue" +4. Add a description and a unique identifier +5. Enable "Sign in with Apple" and click "continue" + +### Register a new service + +1. Go to the Identifiers of your Apple Developer Account: [https://developer.apple.com/account/resources/identifiers/list](https://developer.apple.com/account/resources/identifiers/list) +2. Click the add button "+" on the top left +3. Choose Services IDs and click "continue" +4. Add a description and a unique identifier and click "register" +5. Select your registered service from the list and enable sign in with Apple, then click "configure" +6. Choose the previously created App in the Primary App ID List +7. Add your custom domain in the domains and subdomains field + - Example domain for `https://acme-gzoe4x.zitadel.cloud` would look like this: `acme-gzoe4x.zitadel.cloud` +8. Add the redirect uri in the Return URLs + - {your-domain}/ui/login/login/externalidp/callback/form + - Example redirect url for the domain `https://acme-gzoe4x.zitadel.cloud` would look like this: `https://acme-gzoe4x.zitadel.cloud/ui/login/login/externalidp/callback/form` +9. Save the Client ID and Client secret + +![Apple Service](/img/guides/apple_service_create.png) + + +### Register a new key + +1. Go to the keys list of your Apple Developer Account: [https://developer.apple.com/account/resources/authkeys/list](https://developer.apple.com/account/resources/authkeys/list) +2. Click the add button "+" on the top left +3. Give your key a name +4. Enable "Sign in with Apple" and click configure +5. Choose your app from the list +6. Register the key and download it + +## ZITADEL Configuration + +### Add custom login policy + + + +### Go to the IdP Providers Overview + + + +### Create a new Apple Provider + +1. Add the Client ID, this is the identifier of the service you created in your Apple Account +2. Fill the Team ID, you can find it when you login to your Apple Developer account, in your membership +3. Enter the Key ID and upload the Private Key you previously created + +You can configure the following settings if you like, a useful default will be filled if you don't change anything: + +**Scopes**: The scopes define which scopes will be sent to the provider, `name` and `email` are prefilled. This information will be taken to create/update the user within ZITADEL. + + + +![Apple Provider](/img/guides/zitadel_apple_create_provider.png) + +### Activate IdP + + + +![Activate the Apple Provider](/img/guides/zitadel_activate_apple.png) + +## Test the setup + + + +![Apple Button](/img/guides/zitadel_login_apple.png) + +![Apple Login](/img/guides/apple_login.png) diff --git a/docs/docs/guides/integrate/identity-providers/azuread-oidc.md b/docs/docs/guides/integrate/identity-providers/azuread-oidc.md deleted file mode 100644 index 9b7b1c899a..0000000000 --- a/docs/docs/guides/integrate/identity-providers/azuread-oidc.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Configure AzureAD as Identity Provider -sidebar_label: AzureAD OIDC (Deprecated) ---- - -:::caution deprecated - -This configuration is based on the generic OIDC configuration. You can use the [Azure AD Template](./azure-ad) instead. - -::: - -## AzureAD Tenant as Identity Provider for ZITADEL - -This guides shows you how to connect an AzureAD Tenant to ZITADEL. - -:::info -In ZITADEL you can connect an Identity Provider (IdP) like an AzureAD to your instance and provide it as default to all organizations or you can register the IdP to a specific organization only. This can also be done through your customers in a self-service fashion. -::: - -### Prerequisite - -You need to have access to an AzureAD Tenant. If you do not yet have one follow [this guide from Microsoft](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-create-new-tenant) to create one for free. - -### AzureAD Configuration - -#### Create a new Application - -Browse to the [App registration menus create dialog](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/CreateApplicationBlade/quickStartType~/null/isMSAApp~/false) to create a new app. - -![Create an Application](/img/guides/azure_app_register.png) - -:::info -Make sure to select `web` as application type in the `Redirect URI (optional)` section. -You can leave the second field empty since we will change this in the next step. -::: - -![Create an Application](/img/guides/azure_app.png) - -#### Configure Redirect URIS - -For this to work you need to whitelist the redirect URIs from your ZITADEL Instance. -In this example our test instance has the domain `test-qcon0h.zitadel.cloud`. In this case we need to whitelist these two entries: - -- `https://test-qcon0h.zitadel.cloud/ui/login/login/externalidp/callback` - -:::info -To adapt this for you setup just replace the domain -::: - -![Configure Redirect URIS](/img/guides/azure_app_redirects.png) - -#### Create Client Secret - -To allow your ZITADEL to communicate with the AzureAD you need to create a Secret - -![Create Client Secret](/img/guides/azure_app_secrets.png) - -:::info -Please save this for the later configuration of ZITADEL -::: - -#### Configure ID Token Claims - -![Configure ID Token Claims](/img/guides/azure_app_token.png) - -### ZITADEL Configuration - -#### Create IdP - -Use the values displayed on the AzureAD Application page in your ZITADEL IdP Settings. - -- You need to extract the `issuer` of your AzureAD Tenant from the OpenID configuration (`OpenID Connect metadata document`) in the `Endpoints submenu`. It should be your tenant's domain appended with `/v2.0` -- The `Client ID` of ZITADEL corresponds to the `Application (client) ID` in the Overview page -- The `Client Secret` was generated during the `Create Client Secret` step -- Add `https://graph.microsoft.com/User.Read` to the scopes list to let personal Azure accounts register themselves - -![Azure Application](/img/guides/azure_app.png) - -![Create IdP](/img/guides/azure_zitadel_settings.png) - -#### Activate IdP - -Once you created the IdP you need to activate it, to make it usable for your users. - -![Activate the AzureAD](/img/guides/azure_zitadel_activate.png) - -![Active AzureAD](/img/guides/azure_zitadel_active.png) - -#### Disable 2-Factor prompt - -If a user has no 2-factor configured, ZITADEL does ask on a regularly basis, if the user likes to add a new 2-factor for more security. -If you don't want your users to get this prompt when using Azure, you have to disable this feature. - -1. Go to the login behaviour settings of your instance or organization, depending if you like to disable it for all or just a specific organization respectively -2. Set "Multi-factor init lifetimes" to 0 - -![img.png](/img/guides/login_lifetimes.png) - -#### Create user with verified email - -Azure AD does not send the "email verified claim" in its token. -Due to that the user will get an email verification mail to verify his email address. - -To create the user with a verified email address you must add an action. - -1. Go to the actions of your organization -2. Create a new action with the following code to set the email to verified automatically -3. Make sure the action name matches the function in the action itself e.g: "setEmailVerified" - -```js reference -https://github.com/zitadel/actions/blob/main/examples/verify_email.js -``` - -![img.png](/img/guides/action_email_verify.png) - -3. Add the action "email verify" to the flow "external authentication" and to the trigger "pre creation" - -![img.png](/img/guides/action_pre_creation_email_verify.png) - -#### Automatically redirect to Azure AD - -If you like to get automatically redirected to your Azure AD login instead of showing the ZITADEL login with the Username/Password and a button "Login with AzureAD" you have to do the following steps: - -1. Go to the login behaviour settings of your instance or organization -2. Disable login with username and password -3. Make sure you have only configured AzureAD as external identity provider -4. If you did all your settings on the organization level make sure to send the organization scope in your authorization request: [scope](/apis/openidoauth/scopes#reserved-scopes) - -### Test the setup - -To test the setup use incognito mode and browse to your login page. -If you succeeded you should see a new button which should redirect you to your AzureAD Tenant. - -![AzureAD Button](/img/guides/azure_zitadel_button.png) - -![AzureAD Login](/img/guides/azure_login.png) diff --git a/docs/docs/guides/integrate/identity-providers/google-oidc.mdx b/docs/docs/guides/integrate/identity-providers/google-oidc.mdx deleted file mode 100644 index d4ac3ccde4..0000000000 --- a/docs/docs/guides/integrate/identity-providers/google-oidc.mdx +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Configure Google as Identity Provider -sidebar_label: Google OIDC (Deprecated) ---- - -:::caution deprecated - -This configuration is based on the generic OIDC configuration. You can use the [Google Template](./google) instead. - -::: - -## Register an external identity provider - -In this step we will add a new Google identity provider to federate identities with ZITADEL. - -### 1. Create new OIDC Client - -1. Register an OIDC Client in your preferred provider -2. Make sure you add the ZITADEL callback redirect uris - - {your-domain}/ui/login/login/externalidp/callback - -> **Information:** Make sure the provider is OIDC 1.0 compliant with a proper Discovery Endpoint - -Google Example: - -1. Go to the Google Cloud Platform and choose your project: -2. Click on "+ CREATE CREDENTIALS" and choose "OAuth client ID" -3. Choose Web application as Application type and give a name -4. Add the redirect uris - - {your-domain}/ui/login/register/externalidp/callback - - {your-domain}/ui/login/login/externalidp/callback -5. Save clientid and client secret - -![Add new oAuth credentials in Google Console](/img/google_add_credentials.gif) - -### 2. Add custom login policy - -The login policy can be configured on two levels. Once as default on the instance and this can be overwritten for each organization. -This case describes how to change it on the organization. - -1. Go to your organization settings by clicking on "Organization" in the menu -2. Modify your login policy in the menu "Login Behavior and Security" - -![Add custom login policy](/img/console_org_custom_login_policy.gif) - -### 3. Configure new identity provider - -1. Go to the settings of your instance or a specific organization (depending on where you need the identity provider) -2. Go to the identity providers section and click "New" -3. Select "OIDC Configuration" and fill out the form - - Use the issuer, clientid and client secret provided by your provider (Google Issuer: https://accounts.google.com) - - The scopes will be prefilled with openid, profile and email, because this information is relevant for ZITADEL - - You can choose what fields you like to map as the display name and as username. The fields you can choose are preferred_username and email - (Example: For Google you should choose email for both fields) -4. Save your configuration -5. You will now see the created configuration in the list. Click on the activate icon at the end of the row you can see when hovering over the row, to activate it in the login flow. - -![Configure identity provider](/img/console_org_identity_provider.gif) - -### 4. Send the primary domain scope on the authorization request - -ZITADEL will show a set of identity providers by default. This configuration can be changed by users with the [manager role](/guides/manage/console/managers#roles) `IAM_OWNER`. - -An organization's login settings will be shown - -- as soon as the user has entered the loginname and ZITADEL can identify to which organization he belongs; or -- by sending a primary domain scope. - To get your own configuration you will have to send the [primary domain scope](/apis/openidoauth/scopes#reserved-scopes) in your [authorization request](/guides/integrate/login-users#auth-request) . - The primary domain scope will restrict the login to your organization, so only users of your own organization will be able to login, also your branding and policies will trigger. - -:::note -You need to create your own auth request with your applications parameters. Please see the docs to construct an [Auth Request](/guides/integrate/login-users#auth-request). -::: - -Your user will now be able to choose Google for login instead of username/password or mfa. diff --git a/docs/docs/guides/integrate/identity-providers/okta.mdx b/docs/docs/guides/integrate/identity-providers/okta.mdx new file mode 100644 index 0000000000..2485cc669b --- /dev/null +++ b/docs/docs/guides/integrate/identity-providers/okta.mdx @@ -0,0 +1,67 @@ +--- +title: Configure OKTA as Identity Provider +sidebar_label: OKTA generic OIDC +id: okta +--- + +import GeneralConfigDescription from './_general_config_description.mdx'; +import Intro from './_intro.mdx'; +import CustomLoginPolicy from './_custom_login_policy.mdx'; +import IDPsOverview from './_idps_overview.mdx'; +import GenericOIDC from './_generic_oidc.mdx'; +import Activate from './_activate.mdx'; +import TestSetup from './_test_setup.mdx'; + + + +## OKTA Configuration + +### Register a new client + +1. Login to your OKTA Account and go to the applications list: +2. Click on "Create App Integration" and choose "OIDC - OpenID Connect" +3. Choose Web application as Application type and give a name +4. Add the Sign-in redirect uris + - {your-domain}/ui/login/login/externalidp/callback + - Example redirect url for the domain `https://acme-gzoe4x.zitadel.cloud` would look like this: `https://acme-gzoe4x.zitadel.cloud/ui/login/login/externalidp/callback` +5. Save clientid and client secret + +![Add new OIDC Application in OKTA](/img/guides/okta_add_app.png) + +## ZITADEL Configuration + +### Add custom login policy + + + +### Go to the IdP Providers Overview + + + +### Create a new Generic OIDC Provider + + + + + + +![OKTA Provider](/img/guides/zitadel_okta_create_provider.png) + +### Activate IdP + + + +![Activate the OKTA Provider](/img/guides/zitadel_activate_okta.png) + +## Test the setup + + + + +![OKTA Button](/img/guides/zitadel_login_okta.png) + +![OKTA Login](/img/guides/okta_login.png) diff --git a/docs/docs/guides/integrate/login-ui/_browser_signin_webauthn.mdx b/docs/docs/guides/integrate/login-ui/_browser_signin_webauthn.mdx new file mode 100644 index 0000000000..25c12a0d76 --- /dev/null +++ b/docs/docs/guides/integrate/login-ui/_browser_signin_webauthn.mdx @@ -0,0 +1,12 @@ + +After starting the WebAuthN authentication on the side of ZITADEL you have to challenge the browser. +To do this you need to call the browser API to get the credentials. +Make sure to send the public key credential request options you got from ZITADEL. + +```javascript +const credential = await navigator.credentials.get({ + publicKey: publicKeyCredentialRequestOptions +}); +``` + +Read the [WebAuthN Guide](https://webauthn.guide/#authentication) for more information about "Authenticating with a WebAuthN Credential". diff --git a/docs/docs/guides/integrate/login-ui/_list-mfa-options.mdx b/docs/docs/guides/integrate/login-ui/_list-mfa-options.mdx index ec454bc5c1..c4eaa886c4 100644 --- a/docs/docs/guides/integrate/login-ui/_list-mfa-options.mdx +++ b/docs/docs/guides/integrate/login-ui/_list-mfa-options.mdx @@ -8,7 +8,7 @@ Request Example: ```bash curl --request GET \ - --url https://$ZITADEL_DOMAIN/v2alpha/settings/login \ + --url https://$ZITADEL_DOMAIN/v2beta/settings/login \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' ``` diff --git a/docs/docs/guides/integrate/login-ui/_logout.mdx b/docs/docs/guides/integrate/login-ui/_logout.mdx index 9ed4414665..ce184109d3 100644 --- a/docs/docs/guides/integrate/login-ui/_logout.mdx +++ b/docs/docs/guides/integrate/login-ui/_logout.mdx @@ -7,7 +7,7 @@ Send the session token in the body of the request. ```bash curl --request DELETE \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions/218480890961985793 \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/218480890961985793 \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ diff --git a/docs/docs/guides/integrate/login-ui/_select-account.mdx b/docs/docs/guides/integrate/login-ui/_select-account.mdx index ad83eb4e21..b16cce281c 100644 --- a/docs/docs/guides/integrate/login-ui/_select-account.mdx +++ b/docs/docs/guides/integrate/login-ui/_select-account.mdx @@ -9,7 +9,7 @@ The list of session IDs can be sent in the “search sessions” request to get ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions/search \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/search \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ diff --git a/docs/docs/guides/integrate/login-ui/_update_session_webauthn.mdx b/docs/docs/guides/integrate/login-ui/_update_session_webauthn.mdx new file mode 100644 index 0000000000..0acbf805f9 --- /dev/null +++ b/docs/docs/guides/integrate/login-ui/_update_session_webauthn.mdx @@ -0,0 +1,25 @@ + +Now that you have successfully authenticated in the browser, you can update the session of the user. +Fill the webAuthN checks with the credential assertion data you get from the browser. + +More detailed information about the API: [Update Session Documentation](/apis/resources/session_service/session-service-set-session) + +Example Request: + +```bash +curl --request PATCH \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/218480890961985793 \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"''\ + --header 'Content-Type: application/json' \ + --data '{ + "sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg", + "checks": { + "webAuthN": { + "credentialAssertionData": {} + } + } +}' +``` + + diff --git a/docs/docs/guides/integrate/login-ui/external-login.mdx b/docs/docs/guides/integrate/login-ui/external-login.mdx index 9609062bea..1e1c34e847 100644 --- a/docs/docs/guides/integrate/login-ui/external-login.mdx +++ b/docs/docs/guides/integrate/login-ui/external-login.mdx @@ -26,7 +26,7 @@ In the response, you will get an authentication URL of the provider you like. ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/idp_intents \ + --url https://$ZITADEL_DOMAIN/v2beta/idp_intents \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -71,7 +71,7 @@ To get the information of the provider, make a request to ZITADEL. ### Request ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/idp_intents/$INTENT_ID \ + --url https://$ZITADEL_DOMAIN/v2beta/idp_intents/$INTENT_ID \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -127,7 +127,7 @@ This check requires that the previous step ended on the successful page and didn #### Request ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ @@ -158,7 +158,7 @@ The display name is used to list the linkings on the users. #### Request ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/human \ + --url https://$ZITADEL_DOMAIN/v2beta/users/human \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -196,7 +196,7 @@ If you want to link/connect to an existing account you can perform the add ident #### Request ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/users/218385419895570689/links \ + --url https://$ZITADEL_DOMAIN/v2beta/users/users/218385419895570689/links \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ diff --git a/docs/docs/guides/integrate/login-ui/mfa.mdx b/docs/docs/guides/integrate/login-ui/mfa.mdx index 05f2a5fe82..6e8a2fd37d 100644 --- a/docs/docs/guides/integrate/login-ui/mfa.mdx +++ b/docs/docs/guides/integrate/login-ui/mfa.mdx @@ -5,13 +5,17 @@ sidebar_label: Multi-Factor (MFA) import MfaOptions from './_list-mfa-options.mdx'; import BrowserRegisterWebAuthN from './_browser_register_webauthn.mdx'; +import BrowserSigninWebAuthN from './_browser_signin_webauthn.mdx'; +import UpdateSessionWebAuthN from './_update_session_webauthn.mdx'; Multi-factor authentication (MFA) is a multi-step account authentication which requires to user to enter more than only the password. It is highly recommended to use MFA or [Passkeys](./passkey) to make your user accounts more secure. -ZITADEL supports two different Methods: +ZITADEL supports different Methods: - Time-based one time password (TOTP), which are Authenticator apps like Google/Microsoft Authenticator, Authy, etc +- One-time password sent as SMS +- One-time password sent as E-Mail - Universal Second Factor (U2F), which is authentication with your device like Windows Hello, Apple FaceID, Fingerprint, FIDO2 keys, Yubikey, etc. ## TOTP Registration @@ -37,7 +41,7 @@ Request Example: ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/totp \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/totp \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' --header 'Content-Type: application/json' \ @@ -69,7 +73,7 @@ Request Example: ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/totp/verify \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/totp/verify \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' --header 'Content-Type: application/json' \ @@ -78,6 +82,292 @@ curl --request POST \ }' ``` +## TOTP Authentication + +### Flow + +![Authenticate TOTP](/img/guides/login-ui/authenticate-totp-flow.png) + +### Check User + +To be able to check the TOTP you need a session with a checked user. This can either happen before the TOTP check or at the same time. +In this example we do two separate requests. So the first step is to create a new Sessions. + +More detailed information about the API: [Create new session Documentation](/apis/resources/session_service/session-service-create-session) + +Example Request + +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "checks": { + "user": { + "loginName": "minnie-mouse@mouse.com" + } + } +}' +``` + +Example Response + +```bash +{ + "details": { + "sequence": "580", + "changeDate": "2023-06-14T05:32:39.007096Z", + "resourceOwner": "163840776835432705" + }, + "sessionId": "218480890961985793", + "sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg" +} +``` + +### Check TOTP + +Now you can show the code field to the user, where he has to enter the code from the Authenticator App. +With that code you have to update the existing session with a totp check. + +More detailed information about the API: [Update session Documentation](/apis/resources/session_service/session-service-set-session) + +Example Request +```bash +curl --request PATCH \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/$SESSION-ID \ + --header 'Accept: application/json' \ + --header 'Content-Type: application/json' \ + --data '{ + "sessionToken": "W3mEoesTiYOsiR1LYUCRw3vaEwXKLGDTsqOV_bkOhlah_-ZbuiLgvnzADwe_iYMusbwkMhp7VfMn8j", + "checks": { + "totp": { + "code": "323764" + }, + } +}' +``` + +## SMS Code Registration + +### Flow + +![Register SMS OTP](/img/guides/login-ui/register-phone-otp-flow.png) + +### List the Possible Methods + + + +### Add Phone Number + +When the user has decided to register the phone number to get a code as a second factor, the first step is to add a verified phone number to the user. +If the user already has a verified phone number you can skip this step. + +When adding a new phone number, you can choose if you want ZITADEL to send the verification code to the number, or if you want to send it by yourself. +If ZITADEL should do it, make sure that you have registered an [SMS Provider](/docs/guides/manage/console/instance-settings#sms) and send an empty sendCode object in the request. +With an empty returnCode object in the request, ZITADEL will not send the code, but return it in the response. + +If you don't want the user to verify the phone number, you can also create it directly as verified, by sending the isVerified attribute. + +More detailed information about the API: [Add phone](/apis/resources/user_service/user-service-set-phone) + +Example Request: + +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER-ID/phone \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "phone": "+41791234567", + "sendCode": {} + }' +``` + +### Verify Phone Number + +The next step is to show a screen, so the user is able to enter the code for verifying the phone number. +Send a verify phone request with the code in the body. + +More detailed information about the API: [Verify phone](/apis/resources/user_service/user-service-verify-phone) + +Example Request: +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER-ID/phone/verify \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "verificationCode": "VBQREB" + }' +``` + +### Add OTP SMS to the user + +Now that the user has a verified phone number you can enable SMS OTP on the user. + +More detailed information about the API: [Add OTP SMS for a user](/apis/resources/user_service/user-service-add-otpsms) + +Example Request: +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER-ID/otp_sms \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' +``` + +## SMS Code Authentication + +### Flow + +![Authenticate SMS OTP](/img/guides/login-ui/authenticate-phone-otp-flow.png) + +### Check User + +To be able to check the SMS Code you need a session with a checked user. +When creating the session you can already start the sms challenge, this will only be executed if the user check was successful. +You can tell the challenge, if the code should be returned (returnCode: true) or if ZITADEL should send it (returnCode: false). + +More detailed information about the API: [Create new session Documentation](/apis/resources/session_service/session-service-create-session) + +Example Request + +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "checks": { + "user": { + "loginName": "minni-mouse@mouse.com" + } + }, + "challenges": { + "otpSms": { + "returnCode": false + } + } +}' +``` + +### Check SMS Code + +In the next step you should show the user a code field, where he can enter the code, he got as SMS. +The update session request has a check otpSMS where you should send the code, the user has entered. + +Example Request + +```bash +curl --request PATCH \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/225307381909694507 \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "sessionToken": "W3mEoesTiYOsiR1LYUCRw3WaFwXKLGDRsqOV_bkOhlah_-ZpuiLgvnzADwe_iYMusbwkMhp7VfMn8g", + "checks": { + "otpSms": { + "code": "3237642" + }, + } +}' +``` + +## Email Code Registration + +### Flow + +![Register Email OTP](/img/guides/login-ui/register-email-otp-flow.png) + +### List the Possible Methods + + + +### Verified Email + +As ZITADEL required all users to have a verified email address, you do not need to add a new email and verify it for setting up the second factor. +For the Email second factor the already verified email address will be taken. + +### Add OTP Email to the user + +As the user already has a verified E-Mail address you can enable E-Mail OTP on the user. + +More detailed information about the API: [Add OTP Email for a user](/apis/resources/user_service/user-service-add-otp-email) + +Example Request: +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER-ID/otp_email \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' +``` + +## Email Code Authentication + +### Flow + +![Authenticate OTP Email](/img/guides/login-ui/authenticate-email-otp-flow.png) + +### Check User + +To be able to check the Email Code you need a session with a checked user. +When creating the session you can already start the sms challenge, this will only be executed if the user check was successful. +You can tell the challenge, if the code should be returned (returnCode: true) or if ZITADEL should send it (returnCode: false). + +More detailed information about the API: [Create new session Documentation](/apis/resources/session_service/session-service-create-session) + +Example Request + +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "checks": { + "user": { + "loginName": "minni-mouse@mouse.com" + } + }, + "challenges": { + "otpEmail": { + "returnCode": false + } + } +}' +``` + +### Check Email Code + +In the next step you should show the user a code field, where he can enter the code, he got per E-Mail. +The update session request has a check otpEmail where you should send the code, the user has entered. + +Example Request + +```bash +curl --request PATCH \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/225307381909694507 \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "sessionToken": "W3mEoesTiYOsiR1LYUCRw3WaFwXKLGDRsqOV_bkOhlah_-ZpuiLgvnzADwe_iYMusbwkMhp7VfMn8g", + "checks": { + "otpEmail": { + "code": "3237642" + }, + } +}' +``` + ## U2F Registration ### Flow @@ -99,7 +389,7 @@ Request Example: ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/u2f \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/u2f \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' --header 'Content-Type: application/json' \ @@ -170,7 +460,7 @@ Example Request: ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/u2f/$PASSKEY_ID \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/u2f/$PASSKEY_ID \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -181,7 +471,7 @@ curl --request POST \ "rawId": "pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00", "response": { "attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIgRKS3VpeE9tfExXRzkoUKnG4rQWPvtSSt4YtDGgTx32oCIQDPey-2YJ4uIg-QCM4jj6aE2U3tgMFM_RP7Efx6xRu3JGhhdXRoRGF0YVikSZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFAAAAADju76085Yhmlt1CEOHkwLQAIKWsFWqxeMT8SxZnwp0ZMF1nk6yhs2m3AIvdixCNVgtNpQECAyYgASFYIMGUDSP2FAQn2MIfPMy7cyB_Y30VqixVgGULTBtFjfRiIlggjUGfQo3_-CrMmH3S-ZQkFKWKnNBQEAMkFtG-9A4zqW0", - "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQlhXdHh0WGxJeFZZa0pHT1dVaUVmM25zby02aXZKdWw2YmNmWHdMVlFIayIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAifQ" + "clientDataJSON": "eyJ0eXBlJjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQlhXdHh0WGxJeFZZa0pHT1dVaUVmM25zby02aXZKdWw2YmNmWHdMVlFIayIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAifQ" } }, "tokenName": "Google Pixel" @@ -189,3 +479,65 @@ curl --request POST \ ``` You have successfully registered a new U2F to the user. + +## U2F Authentication + +### Flow + +![Authenticate U2F](/img/guides/login-ui/authenticate-u2f-flow.png) + +### Check User + +To be able to check the Universal-Second-Factor (U2F) you need a user check and a webAuthN challenge. +In the creat session request you can check for the user and directly initiate the webAuthN challenge. + +For U2F you can choose between "USER_VERIFICATION_REQUIREMENT_PREFERRED" and "USER_VERIFICATION_REQUIREMENT_DISCOURAGED" for the challenge. +Best practice is using discouraged, as this doesn't require the user to enter a PIN. With `preferred` the user might be prompted for the PIN, but it is not necessary. + +More detailed information about the API: [Create new session Documentation](/apis/resources/session_service/session-service-create-session) + +Example Request + +```bash +curl --request POST \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer '"$TOKEN"'' \ + --header 'Content-Type: application/json' \ + --data '{ + "checks": { + "user": { + "loginName": "minni-mouse@mouse.com" + } + }, + "metadata": {}, + "challenges": { + "webAuthN": { + "domain": "YOUR-Domain", + "userVerificationRequirement": "USER_VERIFICATION_REQUIREMENT_DISCOURAGED" + } + } +}' +``` + +Example Response + +```bash +{ + "details": { + "sequence": "580", + "changeDate": "2023-06-14T05:32:39.007096Z", + "resourceOwner": "163840776835432705" + }, + "sessionId": "218480890961985793", + "sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg" +} +``` + +### Signin in Browser + + + +### Update Session with WebAuthN + + \ No newline at end of file diff --git a/docs/docs/guides/integrate/login-ui/oidc-standard.mdx b/docs/docs/guides/integrate/login-ui/oidc-standard.mdx index e379060729..84da8a46b8 100644 --- a/docs/docs/guides/integrate/login-ui/oidc-standard.mdx +++ b/docs/docs/guides/integrate/login-ui/oidc-standard.mdx @@ -50,7 +50,7 @@ With the ID from the redirect before you will now be able to get the information ```bash curl --request GET \ - --url https://$ZITADEL_DOMAIN/v2alpha/oidc/auth_requests/V2_224908753244265546 \ + --url https://$ZITADEL_DOMAIN/v2beta/oidc/auth_requests/V2_224908753244265546 \ --header 'Authorization: Bearer '"$TOKEN"''\ ``` @@ -95,7 +95,7 @@ Read more about the [Finalize Auth Request Documentation](/docs/apis/resources/o Make sure that the authorization header is from the same account that you originally sent in the client id header ```x-zitadel-login-client: ``` on the authorize endpoint. ```bash curl --request POST \ - --url $ZITADEL_DOMAIN/v2alpha/oidc/auth_requests/V2_224908753244265546 \ + --url $ZITADEL_DOMAIN/v2beta/oidc/auth_requests/V2_224908753244265546 \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ diff --git a/docs/docs/guides/integrate/login-ui/passkey.mdx b/docs/docs/guides/integrate/login-ui/passkey.mdx index 247d8229bb..458da8f233 100644 --- a/docs/docs/guides/integrate/login-ui/passkey.mdx +++ b/docs/docs/guides/integrate/login-ui/passkey.mdx @@ -3,6 +3,10 @@ title: Passkeys sidebar_label: Passkeys --- +import BrowserRegisterWebAuthN from './_browser_register_webauthn.mdx'; +import BrowserSigninWebAuthN from './_browser_signin_webauthn.mdx'; +import UpdateSessionWebAuthN from './_update_session_webauthn.mdx'; + Passkeys are a replacement for passwords that provide faster, easier, and more secure sign-ins to websites and apps even across multiple devices. Unlike passwords, passkeys are phishing-resistant and can improve the user experience and security at the same time. Passkeys and there underlying protocols are a standard defined by the [FIDO Standard](https://fidoalliance.org/) . @@ -30,7 +34,7 @@ Send either the sendLink or the returnCode (empty message) in the request body, ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/passkeys/registration_link \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/passkeys/registration_link \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -77,7 +81,7 @@ The code only has to be filled if the user did get a registration code. ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/passkeys \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/passkeys \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -181,7 +185,7 @@ Example Request: ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/passkeys/$PASSKEY_ID \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/passkeys/$PASSKEY_ID \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -208,7 +212,6 @@ Next step is to authenticate the user with the new registered passkey. ![Passkey Login](/img/guides/login-ui/passkey-login-flow.png) - ### Create Session First step is to ask the user for his username and create a new session with the ZITADEL API. @@ -220,7 +223,7 @@ More detailed information about the API: [Create Session Documentation](/apis/re Example Request: ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ @@ -273,43 +276,11 @@ Example Response: ### Signing in Browser -After starting the passkey authentication on the side of ZITADEL you have to challenge the browser. -To do this you need to call the browser API to get the credentials. -Make sure to send the public key credential request options you got from ZITADEL. + -```javascript -const credential = await navigator.credentials.get({ - publicKey: publicKeyCredentialRequestOptions -}); -``` - -Read the [WebAuthN Guide](https://webauthn.guide/#authentication) for more information about "Authenticating with a WebAuthN Credential". - -### Update Session with Passkey - -Now that you have successfully authenticated in the browser, you can update the session of the user. -Fill the passkey checks with the credential assertion data you get from the browser. - -More detailed information about the API: [Update Session Documentation](/apis/resources/session_service/session-service-set-session) - -Example Request: - -```bash -curl --request PATCH \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions/218480890961985793 \ - --header 'Accept: application/json' \ - --header 'Authorization: Bearer '"$TOKEN"''\ - --header 'Content-Type: application/json' \ - --data '{ - "sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg", - "checks": { - "webAuthN": { - "credentialAssertionData": {} - } - } -}' -``` +### Update Session with WebAuthN + diff --git a/docs/docs/guides/integrate/login-ui/password-reset.mdx b/docs/docs/guides/integrate/login-ui/password-reset.mdx index 1d16bcb8b5..184777cb81 100644 --- a/docs/docs/guides/integrate/login-ui/password-reset.mdx +++ b/docs/docs/guides/integrate/login-ui/password-reset.mdx @@ -28,7 +28,7 @@ Make sure to also include the URL Template to customize the reset link in the em ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/password_reset \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/password_reset \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Content-Type: application/json' \ @@ -47,7 +47,7 @@ Send the request with asking for the return Code in the body of the request. #### Request ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/password_reset \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/password_reset \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Content-Type: application/json' \ @@ -95,7 +95,7 @@ In this case it requires additionally the current password instead of the verifi ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/password \ + --url https://$ZITADEL_DOMAIN/v2beta/users/$USER_ID/password \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Content-Type: application/json' \ diff --git a/docs/docs/guides/integrate/login-ui/username-password.mdx b/docs/docs/guides/integrate/login-ui/username-password.mdx index 6729760ce2..d94186111a 100644 --- a/docs/docs/guides/integrate/login-ui/username-password.mdx +++ b/docs/docs/guides/integrate/login-ui/username-password.mdx @@ -16,7 +16,7 @@ First, we create a new user with a username and password. In the example below w ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/users/human \ + --url https://$ZITADEL_DOMAIN/v2beta/users/human \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Content-Type: application/json' \ @@ -81,8 +81,8 @@ Return Code: To check what is allowed on your instance, call the settings service for more information. The following requests can be useful for registration: -- [Get Login Settings](https://zitadel.com/docs/apis/resources/settings_service/settings-service-get-login-settings) To find out which authentication possibilities are enabled (password, identity provider, etc.) -- [Get Password Complexity Settings](https://zitadel.com/docs/apis/resources/settings_service/settings-service-get-password-complexity-settings) to find out how the password should look like (length, characters, etc.) +- [Get Login Settings](/apis/resources/settings_service/settings-service-get-login-settings) To find out which authentication possibilities are enabled (password, identity provider, etc.) +- [Get Password Complexity Settings](/apis/resources/settings_service/settings-service-get-password-complexity-settings) to find out how the password should look like (length, characters, etc.) ## Create Session with User Check @@ -96,15 +96,15 @@ The create and update session endpoints will always return a session ID and an o If you do not rely on the OIDC standard you can directly use the token. Send it to the Get Session Endpoint to find out how the user has authenticated. -- [Create new session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-create-session) -- [Update an existing session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-set-session) -- [Get Session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-get-session) +- [Create new session Documentation](/apis/resources/session_service/session-service-create-session) +- [Update an existing session Documentation](/apis/resources/session_service/session-service-set-session) +- [Get Session Documentation](/apis/resources/session_service/session-service-get-session) ### Request ```bash curl --request POST \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Content-Type: application/json' \ @@ -167,7 +167,7 @@ To update an existing session, add the session ID to the URL and the session tok ```bash curl --request PATCH \ - --url https://$ZITADEL_DOMAIN/v2alpha/sessions/$SESSION_ID \ + --url https://$ZITADEL_DOMAIN/v2beta/sessions/$SESSION_ID \ --header 'Accept: application/json' \ --header 'Authorization: Bearer '"$TOKEN"''\ --header 'Content-Type: application/json' \ diff --git a/docs/docs/guides/integrate/services/google-workspace.md b/docs/docs/guides/integrate/services/google-workspace.md new file mode 100644 index 0000000000..a515f89a3b --- /dev/null +++ b/docs/docs/guides/integrate/services/google-workspace.md @@ -0,0 +1,211 @@ +--- +title: Google Workspace SSO with ZITADEL +sidebar_label: Google Workspace +--- + +This guide shows how to enable login with ZITADEL on Google Workspace. + +You can configure two types of SAML SSO on Google Workspace: + +- [SSO profile for your organization](#sso-profile-for-your-organization) +- [Third-party SSO SAML profile](#third-party-sso-saml-profile) + +Both profiles need to be configured differently. +Please make sure to configure your application for the correct type. +Please refer to Google Help to [Set up SSO for your organization](https://support.google.com/a/answer/12032922) in case you need additional information on the Workspace setup. + +:::info OpenID Connect +At this time Google supports SSO with OpenID Connect only for few providers. +::: + +Prerequisites: + +- You need to have a domain registered with your Google Workspace account to configure SSO profiles +- Make sure that you [verify the same domain also in your ZITADEL organization and set it as primary domain](/docs/guides/manage/console/organizations#domain-verification-and-primary-domain) +- A user in Google Workspace (eg, road.runner@acme.com) +- A user in ZITADEL with the same username (eg, road.runner@acme.com); make sure you verify the domain to set the username. This is different than the user's email address + +## SSO profile for your organization + +### Configure SSO profile on Google Workspace + +Open the Google settings for [SSO with third-party IdP](https://admin.google.com/u/1/ac/security/sso) and click on *ADD SSO PROFILE*. + +![SSO with third-party IdP](/img/guides/integrate/services/google-workspace-sso-overview.png) + +Download the public certificate from your ZITADEL instance by requesting `$YOUR_DOMAIN/saml/v2/certificate` + +```bash + wget $YOUR_DOMAIN/saml/v2/certificate -O idp.crt +``` + +Always replace `$YOUR_DOMAIN` with your instance domain. + +Use the following configuration + +| Setting | Value | +| --- | --- | +| Set up SSO with third-party identity provider | Enable (check) | +| Sign-in page URL | $YOUR_DOMAIN/saml/v2/SSO | +| Sign-out page URL | $YOUR_DOMAIN/saml/v2/SLO | +| Verification Certificate | Upload the certificate (idp.crt) | +| Use a domain-specific issuer | Enable (check) | +| Network masks | Leave blank| +| Change password URL | $YOUR_DOMAIN/ui/console/users/me?id=security | + +### Create a SAML application in ZITADEL + +Create a new .xml file with the following minimal SAML metadata contents: + +```xml + + + + + + +``` + +Set or replace the variables with the values from the next screen as follows: + +- `${ENTITYID}`: google.com/a/ +- `${ACSURL}`: https://www.google.com/a//acs + +`` is the domain you have verified in Google Workspace. + +In your existing project: + +Press the "+"-button to add an application +![Project](/img/saml/zitadel/project.png) + +Fill in a name for the application and chose the SAML type, then click "Continue". +![New Application](/img/saml/zitadel/application_saml.png) + +Either fill in the URL where ZITADEL can read the metadata from, or upload the metadata XML directly, then click "Continue". +![Add Metadata to Application](/img/saml/zitadel/application_saml_metadata.png) + +Check your application, if everything is correct, press "Create". +![Create Application](/img/saml/zitadel/application_saml_create.png) + +### Activate the SSO profile for your organization + +Make sure to enable the SSO profile for your organization. + +In the [domain-specific service URLs](https://admin.google.com/u/1/ac/security/sso/domain-specific-service-urls) settings select "Automatically redirect users to the third-party IdP in the following SSO profile" and select as SSO profile "SSO profile for your organization". + +![domain-specific service URLs](/img/guides/integrate/services/google-workspace-domain-sepcific-urls.png) + +Save the settings. + +![SSO with third-party IdP lower part](/img/guides/integrate/services/google-workspace-sso-bottom.png) + +### Verify the SSO profile for your organization + +Now you should be all set to verify your setup: + +- Open Gmail in an incognito session with the following link: https://mail.google.com/a/ +- Enter your username and credentials +- You should be redirected to Gmail and logged in + +`` is the domain you have verified in Google Workspace. + +## Third-party SSO SAML profile + +Configure a third party SSO SAML profile and login users with ZITADEL to Google Workspace. + +### Add SAML profile on Google Workspace + +Open the Google settings for [SSO with third-party IdP](https://admin.google.com/u/1/ac/security/sso) and click on *ADD SAML PROFILE*. + +![SSO with third-party IdP](/img/guides/integrate/services/google-workspace-sso-overview.png) + +Download the public certificate from your ZITADEL instance by requesting `$YOUR_DOMAIN/saml/v2/certificate` + +```bash + wget $YOUR_DOMAIN/saml/v2/certificate -O idp.crt +``` + +Always replace `$YOUR_DOMAIN` with your instance domain. + +Use the following configuration + +| Setting | Value | +| --- | --- | +| SSO profile name | ZITADEL SSO | +| IDP entity ID | $YOUR_DOMAIN/saml/v2/metadata | +| Sign-in page URL | $YOUR_DOMAIN/saml/v2/SSO | +| Sign-out page URL | $YOUR_DOMAIN/saml/v2/SLO | +| Change password URL | $YOUR_DOMAIN/ui/console/users/me?id=security | +| Verification Certificate | Upload the certificate (idp.crt) | + +Now go ahead and click *SAVE* + +### Entity ID and ACS URL + +Open the Google settings for [SSO with third-party IdP](https://admin.google.com/u/1/ac/security/sso) and click on the SAML Profile *ZITADEL SSO* + +![SSO Profile Overview](/img/guides/integrate/services/google-workspace-sso-zitadel.png) + +You can copy the "Entity ID" and "ACS URL" from the "SP details" section. + +![ZITADEL SSO Profile](/img/guides/integrate/services/google-workspace-zitadel-profile-configured.png) + +### Create a SAML application in ZITADEL + +Create a new .xml file with the following minimal SAML metadata contents: + +```xml + + + + + + +``` + +Set or replace the variables with the values from the next screen as follows: + +- `${ENTITYID}`: https://accounts.google.com/samlrp/metadata?rpid= +- `${ACSURL}`: https://accounts.google.com/samlrp/acs?rpid= + +Replace `` with the values from the [SSO profile](#entity-id-and-acs-url). + +In your existing project: + +Press the "+"-button to add an application +![Project](/img/saml/zitadel/project.png) + +Fill in a name for the application and chose the SAML type, then click "Continue". +![New Application](/img/saml/zitadel/application_saml.png) + +Either fill in the URL where ZITADEL can read the metadata from, or upload the metadata XML directly, then click "Continue". +![Add Metadata to Application](/img/saml/zitadel/application_saml_metadata.png) + +Check your application, if everything is correct, press "Create". +![Create Application](/img/saml/zitadel/application_saml_create.png) + +### Activate the SSO profile + +Make sure to enable the SSO profile. + +In the [domain-specific service URLs](https://admin.google.com/u/1/ac/security/sso/domain-specific-service-urls) settings select "Automatically redirect users to the third-party IdP in the following SSO profile" and select as SSO profile "ZITADEL SSO". + +![domain-specific service URLs with ZITADEL SSO](/img/guides/integrate/services/google-workspace-zitadel-set-profile.png) + +Save the settings. + +![SSO with third-party IdP lower part with ZITADEL SSO](/img/guides/integrate/services/google-workspace-sso-zitadel.png) + +### Verify the SAML SSO profile + +Now you should be all set to verify your setup: + +- Open Gmail in an incognito session with the following link: https://mail.google.com/a/ +- Enter your username and credentials +- You should be redirected to Gmail and logged in + +`` is the domain you have verified in Google Workspace. + +### Troubleshooting + +Make sure you don't use a super admin account in Google Workspace to test SSO. Super Admin users are not allowed to login with SSO and you might receive an status code 500. diff --git a/docs/docs/guides/start/quickstart.mdx b/docs/docs/guides/start/quickstart.mdx index 4f4d967d4d..c9f6e0f8c1 100644 --- a/docs/docs/guides/start/quickstart.mdx +++ b/docs/docs/guides/start/quickstart.mdx @@ -1,16 +1,14 @@ --- -title: Quick start guide +title: Quick start guide --- -import VSCodeFolderView from "../../../static/img/guides/quickstart/vscode1.png"; - +import VSCodeFolderView from "../../../static/img/guides/quickstart/vscode1.png"; ## Introduction -In this quick start guide, we will be learning some fundamentals on how to set up ZITADEL for user management and application security. Thereafter, we will secure a React-based Single Page Application (SPA) using ZITADEL. - -The sample application allows users to securely log in to ZITADEL using the OIDC Proof Key for Code Exchange (PKCE) flow. This flow ensures that the authentication process is secure by using a code verifier and a code challenge, which are sent to ZITADEL to obtain an access token. The access token is then used by the app to access the userinfo endpoint to retrieve and display information about the logged-in user. The app also has a logout feature that allows users to end their session and clear their access token. Overall, the app provides a simple and secure way for users to authenticate and access protected resources within ZITADEL. +In this quick start guide, we will be learning some fundamentals on how to set up ZITADEL for user management and application security. Thereafter, we will secure a React-based Single Page Application (SPA) using ZITADEL. +The sample application allows users to securely log in to ZITADEL using the OIDC Proof Key for Code Exchange (PKCE) flow. This flow ensures that the authentication process is secure by using a code verifier and a code challenge, which are sent to ZITADEL to obtain an access token. The access token is then used by the app to access the userinfo endpoint to retrieve and display information about the logged-in user. The app also has a logout feature that allows users to end their session and clear their access token. Overall, the app provides a simple and secure way for users to authenticate and access protected resources within ZITADEL. ## ZITADEL terminology: instances, organizations, projects, users, roles, authorizations and apps @@ -18,15 +16,48 @@ In ZITADEL, instances, organizations, projects, users, roles, and apps are the m The order of creation for the above components would typically be as follows: -
      -
    • Instance: An instance is a top-level entity in ZITADEL that represents a deployment of ZITADEL for a registered account. An instance can have one or more organizations.
    • -
    • Organization: An organization is a logical separation within an instance that represents a company/organization and can have one or more projects. The default organization is the one that is provided at the start of the account registration process. Typically, an instance would have one organization, but in B2B scenarios, an instance would have more than one.
    • -
    • Project: A project is a logical separation within an organization and is a container for apps, roles and authorization policies for the resources it contains.
    • -
    • Users: Users are created at the organizational level and are granted access to the resources within projects. They can be assigned different roles, which define the permissions and privileges they have within the project.
    • -
    • Roles: Roles are the sets of permissions and privileges that are assigned to users within a project.
    • -
    • Authorizations: Authorization policies in ZITADEL are defined at the project level, which means that they apply to all the resources within the project. These policies are based on the roles that are assigned to users, and they determine the actions that users are allowed to perform within the project.
    • -
    • Apps: Apps are the applications that are developed and managed within a project. They can be client apps that use the resources within the project, or they can be backend apps that provide the resources for other apps to use. The apps can use the OIDC or SAML protocol to authenticate users to access protected resources.
    • +
    • + Instance: An instance is a top-level entity in ZITADEL that + represents a deployment of ZITADEL for a registered account. An instance can + have one or more organizations. +
    • +
    • + Organization: An organization is a logical separation within an + instance that represents a company/organization and can have one or more + projects. The default organization is the one that is provided at the start + of the account registration process. Typically, an instance would have one + organization, but in B2B scenarios, an instance would have more than one. +
    • +
    • + Project: A project is a logical separation within an organization and + is a container for apps, roles and authorization policies for the resources + it contains. +
    • +
    • + Users: Users are created at the organizational level and are granted + access to the resources within projects. They can be assigned different + roles, which define the permissions and privileges they have within the + project. +
    • +
    • + Roles: Roles are the sets of permissions and privileges that are + assigned to users within a project. +
    • +
    • + Authorizations: Authorization policies in ZITADEL are defined at the + project level, which means that they apply to all the resources within the + project. These policies are based on the roles that are assigned to users, + and they determine the actions that users are allowed to perform within the + project. +
    • +
    • + Apps: Apps are the applications that are developed and managed within + a project. They can be client apps that use the resources within the + project, or they can be backend apps that provide the resources for other + apps to use. The apps can use the OIDC or SAML protocol to authenticate + users to access protected resources. +
    The order of creation for the above components may vary depending on the specific needs and requirements of the organization. @@ -43,11 +74,11 @@ The order of creation for the above components may vary depending on the specifi ![Registration Page](/img/guides/quickstart/2.png) -3. You will receive a verification email to verify the user for the Customer Portal. Click the “Sign in” button. +3. You will receive a verification email to verify the user for the Customer Portal. Click the “Sign in” button. ![Congratulations Page](/img/guides/quickstart/3.png) -4. You will be prompted for a code, which has been emailed to you. +4. You will be prompted for a code, which has been emailed to you. ![Code](/img/guides/quickstart/4.png) @@ -55,7 +86,7 @@ The order of creation for the above components may vary depending on the specifi ![Inbox](/img/guides/quickstart/5.png) -6. Paste the code and add a password as shown below. Click on the “next” button. +6. Paste the code and add a password as shown below. Click on the “next” button. ![Code](/img/guides/quickstart/6.png) @@ -63,11 +94,11 @@ The order of creation for the above components may vary depending on the specifi ![User Activated](/img/guides/quickstart/7.png) -8. Login with the username and password that you provided. Click “next”. +8. Login with the username and password that you provided. Click “next”. ![Login](/img/guides/quickstart/8.png) -9. You should set up 2-factor authentication. However, we will skip this step for now. Click on “skip”. +9. You should set up 2-factor authentication. However, we will skip this step for now. Click on “skip”. ![2-factor Authentication](/img/guides/quickstart/9.png) @@ -77,13 +108,13 @@ The order of creation for the above components may vary depending on the specifi ### 2. Create your first instance -As a user of the ZITADEL Cloud Customer Portal, you now can create multiple instances to suit your specific needs. This includes instances for development, production, or user acceptance testing, as well as instances for different clients or applications. For example, you might create an instance for each product in a B2C scenario, or an instance for each tenant or customer in a B2B scenario. The possibilities are endless. You can create a pay-as-you-go instance for production purposes. +As a user of the ZITADEL Cloud Customer Portal, you now can create multiple instances to suit your specific needs. This includes instances for development, production, or user acceptance testing, as well as instances for different clients or applications. For example, you might create an instance for each product in a B2C scenario, or an instance for each tenant or customer in a B2B scenario. The possibilities are endless. You can create a pay-as-you-go instance for production purposes. 1. Let’s create an instance. Click on “Create new instance”. ![Create Instance](/img/guides/quickstart/10.png) -2. Provide a name for your instance, select the “Free” plan and click on the “Continue” button at the bottom of this screen. +2. Provide a name for your instance, select the “Free” plan and click on the “Continue” button at the bottom of this screen. ![Select Tier](/img/guides/quickstart/v2_1.png) @@ -91,19 +122,19 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![Instance Details](/img/guides/quickstart/v2_2.png) -4. The instance creation process will take a few seconds. +4. The instance creation process will take a few seconds. ![Instance Details](/img/guides/quickstart/v2_3.png) -5. Now you will see the details of your first instance. You can click on "Visit" at the top right to go to your instance. +5. Now you will see the details of your first instance. You can click on "Visit" at the top right to go to your instance. ![Instance Details](/img/guides/quickstart/v2_4.png) -6. To log in to your instance, provide the username and password, and click “next”. +6. To log in to your instance, provide the username and password, and click “next”. ![Instance Details](/img/guides/quickstart/v2_5.png) -7. Skip the 2-factor authentication for now by clicking “skip”. +7. Skip the 2-factor authentication for now by clicking “skip”. ![Instance Details](/img/guides/quickstart/v2_6.png) @@ -113,7 +144,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ### 3. Create your first project -1. To create a project in the instance you just created, click on “Create Project”. +1. To create a project in the instance you just created, click on “Create Project”. ![Create Project](/img/guides/quickstart/19.png) @@ -129,19 +160,19 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst [Skip optional steps](quickstart/#7-create-an-application-in-your-project) and jump directly to the create application step. -1. To add users, click on “Users” at the top menu. You will see that the user you already created is listed as a user here. Click on the “New” button to create a new user. +1. To add users, click on “Users” at the top menu. You will see that the user you already created is listed as a user here. Click on the “New” button to create a new user. ![Add User](/img/guides/quickstart/26.png) -2. Let’s add another user as shown below. Fill in the user details as shown below and click on the “Create” button when you are done. +2. Let’s add another user as shown below. Fill in the user details as shown below and click on the “Create” button when you are done. ![Add User](/img/guides/quickstart/27.png) -3. The newly created user details will be displayed as shown below. +3. The newly created user details will be displayed as shown below. ![User Info](/img/guides/quickstart/28.png) -4. Once you navigate back to the "Users" view, you will see a list of all the users that have been added to your instance. If you need to add more users, you can do so. +4. Once you navigate back to the "Users" view, you will see a list of all the users that have been added to your instance. If you need to add more users, you can do so. ![User Info](/img/guides/quickstart/29.png) @@ -177,7 +208,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ![Add Authorization](/img/guides/quickstart/32.png) -4. Let’s select the role “sales”. Click on “Save”. +4. Let’s select the role “sales”. Click on “Save”. ![Add Authorization](/img/guides/quickstart/33.png) @@ -195,9 +226,9 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst ### 7. Create an application in your project -We will now create an application in the project, which will allow our React client application to access protected resources through the use of the OpenID Connect (OIDC) protocol. +We will now create an application in the project, which will allow our React client application to access protected resources through the use of the OpenID Connect (OIDC) protocol. -1. Go to “Projects” and click on “Project1”. +1. Go to “Projects” and click on “Project1”. ![Add Application](/img/guides/quickstart/38.png) @@ -209,15 +240,15 @@ We will now create an application in the project, which will allow our React cli ![Add Application](/img/guides/quickstart/41.png) -4. Select “PKCE” because we recommend the use of [Authorization Code](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) for all web applications. More about the different app types can be found [here](https://zitadel.com/docs/guides/integrate/oauth-recommended-flows#different-client-profiles). Click on "Continue". +4. Select “PKCE” because we recommend the use of [Authorization Code](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) for all web applications. More about the different app types can be found [here](https://zitadel.com/docs/guides/integrate/oauth-recommended-flows#different-client-profiles). Click on "Continue". ![Add Application](/img/guides/quickstart/42.png) -5. The Redirect URL in your application is where the ZITADEL authorization server redirects the user after they have been authenticated. Set your “Redirect URI” to [http://localhost:3000/callback](http://localhost:3000/callback) and “Post Logout URI” to [http://localhost:3000/](http://localhost:3000/). Click on “Continue”. +5. The Redirect URL in your application is where the ZITADEL authorization server redirects the user after they have been authenticated. Set your “Redirect URI” to [http://localhost:3000/callback](http://localhost:3000/callback) and “Post Logout URI” to [http://localhost:3000/](http://localhost:3000/). Click on “Continue”. ![Add Application](/img/guides/quickstart/43.png) -6. Now you will be presented with the details of your application for review. Click on “Create”. +6. Now you will be presented with the details of your application for review. Click on “Create”. ![Add Application](/img/guides/quickstart/44.png) @@ -229,7 +260,7 @@ We will now create an application in the project, which will allow our React cli ![Add Application](/img/guides/quickstart/46.png) -9. To proceed with HTTP, go to “Redirect Settings” on the left. +9. To proceed with HTTP, go to “Redirect Settings” on the left. ![Add Application](/img/guides/quickstart/47.png) @@ -242,11 +273,12 @@ We will now create an application in the project, which will allow our React cli ![Add Application](/img/guides/quickstart/50.png) ### 8. Obtain ClientId and OIDC endpoints for your application {#referred1} -You will need the ClientId and the OIDC endpoints (issuer and userinfo) when building your React application. The issuer URL is the base URL for the OIDC provider and includes the path to the OIDC discovery document, which contains information about the OIDC provider, including the authorization and token endpoints. By providing the issuer URL, you can use the OIDC library to automatically determine the endpoints for these requests. -The authorization endpoint is used to initiate the authorization process, the token endpoint is used to exchange authorization codes for access tokens, and the userinfo endpoint is used to retrieve information about the user. You need an access token to access the userinfo endpoint and other protected resources. +You will need the ClientId and the OIDC endpoints (issuer and userinfo) when building your React application. The issuer URL is the base URL for the OIDC provider and includes the path to the OIDC discovery document, which contains information about the OIDC provider, including the authorization and token endpoints. By providing the issuer URL, you can use the OIDC library to automatically determine the endpoints for these requests. -1. Click on “Configurations” to access the Client ID as shown below: +The authorization endpoint is used to initiate the authorization process, the token endpoint is used to exchange authorization codes for access tokens, and the userinfo endpoint is used to retrieve information about the user. You need an access token to access the userinfo endpoint and other protected resources. + +1. Click on “Configurations” to access the Client ID as shown below: ![Get URLs](/img/guides/quickstart/51.png) @@ -260,19 +292,19 @@ And with that, configuring ZITADEL for our application is complete. Now we can m ### 1. Functional requirements of the application -1. The user navigates to the React app (client) and clicks the "login" button. +1. The user navigates to the React app (client) and clicks the "login" button. 2. The app initiates the authorization process by redirecting the user’s browser to the authorization endpoint of the ZITADEL instance, along with the PKCE parameters (code challenge, and code challenge method). 3. The user will see the ZITADEL login page, where the user can enter their credentials. 4. After successful authentication, ZITADEL generates an authorization code and redirects the user back to the React app. 5. The React app sends a request to the ZITADEL token endpoint, along with the authorization code and code verifier. -6. ZITADEL verifies the code verifier to ensure that the authorization request is coming from the same client that initiated it. If it is valid, ZITADEL returns an access token to the React app. +6. ZITADEL verifies the code verifier to ensure that the authorization request is coming from the same client that initiated it. If it is valid, ZITADEL returns an access token to the React app. 7. The React app uses the access token to make a request to the userinfo endpoint, which is protected by the OIDC protocol. 8. The userinfo endpoint returns information about the logged-in user, such as their name and email address. 9. The React app displays this information to the user. 10. When the user wants to log out, the React app sends a request to the ZITADEL logout endpoint, which clears the access token and ends the user's session. -11. The user will be redirected to the login page of the app. +11. The user will be redirected to the login page of the app. -***The scope of this application for this quick start guide is limited to user authentication and doesn't include role-based authentication, even though we previously discussed adding roles and users.*** +**_The scope of this application for this quick start guide is limited to user authentication and doesn't include role-based authentication, even though we previously discussed adding roles and users._** ### 2. Prerequisites @@ -282,37 +314,37 @@ To install React, you will need to have Node.js installed on your system. You ca To install Visual Studio Code, go to their [website](https://code.visualstudio.com/) and download and install the version for your operating system. - ### 3. Development + #### 1. Create project + 1. Open a new terminal window in Visual Studio Code. -2. Navigate to the folder where you want to create the React app. +2. Navigate to the folder where you want to create the React app. 3. Run the following command to create a new React app named "react-oidc-zitadel": - ``` npx create-react-app react-oidc-zitadel ``` + `npx create-react-app react-oidc-zitadel` 4. Navigate to the "react-oidc-zitadel" folder: - ``` cd react-oidc-zitadel ``` + `cd react-oidc-zitadel` -This will create the following files in your project: +This will create the following files in your project: 5. The dependencies for this project include react-router-dom and oidc-client-ts. To include them in your React application, you will need to run the following command in your terminal: - ``` npm install react-router-dom oidc-client-ts ``` + `npm install react-router-dom oidc-client-ts` - -#### 2. Add source files +#### 2. Add source files The code needed to run this project can be found [here](https://github.com/zitadel/react-user-authentication). -1. Replace the content in your App.js file with the one provided below: +1. Replace the content in your App.js file with the one provided below: - [src/App.js](https://github.com/zitadel/react-user-authentication/blob/main/src/App.js): +[src/App.js](https://github.com/zitadel/react-user-authentication/blob/main/src/App.js): -``` +``` import React, { useState, useEffect } from "react"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Login from "./components/Login"; @@ -372,23 +404,23 @@ function App() { ); } -export default App; +export default App; ``` The App.js file is the root component of the React app that initializes the OIDC flow and manages the user's session. It does this by: -- Importing the necessary libraries and components from the dependencies, including the ```oidc-client-ts``` library, the ```authConfig``` file with the OIDC configuration values, and the Login and Callback components. -- Initializing a new ``UserManager`` instance with the OIDC configuration values from the authConfig file. The ``` UserManager``` instance manages the OIDC flow and stores the user's session information. -- Defining two functions: ```authorize``` and ```clearAuth```. The ```authorize``` function initiates the OIDC flow when the user clicks the ```login``` button, while the ```clearAuth``` function ends the user's session when the user clicks the ```logout``` button. -- Defining two state variables: ```authenticated``` and ```userInfo```. The authenticated variable is a boolean that indicates whether the user is authenticated or not, while the ```userInfo``` variable stores the user's information when they are authenticated. -- Using the ```useEffect``` hook to retrieve the user's session information from the ```UserManager``` instance and updating the ```authenticated``` and ```userInfo``` state variables accordingly. -- Defining the routes for the app using the ```react-router-dom``` library, including the ```/``` and ```/callback``` routes for the login and callback pages, respectively. The ```Login``` and ```Callback``` components handle the login and callback processes, respectively. +- Importing the necessary libraries and components from the dependencies, including the `oidc-client-ts` library, the `authConfig` file with the OIDC configuration values, and the Login and Callback components. +- Initializing a new `UserManager` instance with the OIDC configuration values from the authConfig file. The ` UserManager` instance manages the OIDC flow and stores the user's session information. +- Defining two functions: `authorize` and `clearAuth`. The `authorize` function initiates the OIDC flow when the user clicks the `login` button, while the `clearAuth` function ends the user's session when the user clicks the `logout` button. +- Defining two state variables: `authenticated` and `userInfo`. The authenticated variable is a boolean that indicates whether the user is authenticated or not, while the `userInfo` variable stores the user's information when they are authenticated. +- Using the `useEffect` hook to retrieve the user's session information from the `UserManager` instance and updating the `authenticated` and `userInfo` state variables accordingly. +- Defining the routes for the app using the `react-router-dom` library, including the `/` and `/callback` routes for the login and callback pages, respectively. The `Login` and `Callback` components handle the login and callback processes, respectively. 2. Create a folder named components in the src directory. Create two files named Login.js and Callback.js. -3. Paste the following code to Login.js. +3. Paste the following code to Login.js. - [src/components/Login.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Login.js) +[src/components/Login.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Login.js) ``` import { Navigate } from "react-router-dom"; @@ -417,11 +449,12 @@ const Login = ({ auth, handleLogin, userManager }) => { export default Login; ``` -The ```/``` route corresponds to the login page, which is rendered by the Login component. The Login(Login.js) component is a functional component that displays the login button and calls the ```handleLogin``` function (which corresponds to the ```authorize``` function defined in the App component) when the button is clicked. This initiates the OIDC flow by redirecting the user to the authorization endpoint. -4. Paste the following code to Callback.js. +The `/` route corresponds to the login page, which is rendered by the Login component. The Login(Login.js) component is a functional component that displays the login button and calls the `handleLogin` function (which corresponds to the `authorize` function defined in the App component) when the button is clicked. This initiates the OIDC flow by redirecting the user to the authorization endpoint. - [src/components/Callback.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Callback.js) +4. Paste the following code to Callback.js. + +[src/components/Callback.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Callback.js) ``` import React, { useEffect } from 'react'; @@ -451,6 +484,20 @@ const Callback = ({ auth, setAuth, userManager, userInfo, setUserInfo, handleLog }).catch((error) => { setAuth(false); }); + } else if (auth === true && !userInfo) { + userManager.getUser().then((user) => { + const access_token = user.access_token; + + fetch(authConfig.userinfo_endpoint, { + headers: { + Authorization: `Bearer ${access_token}`, + }, + }) + .then((response) => response.json()) + .then((userInfo) => { + setUserInfo(userInfo); + }); + }); } }, [auth, userManager, setAuth]); @@ -478,11 +525,11 @@ const Callback = ({ auth, setAuth, userManager, userInfo, setUserInfo, handleLog export default Callback; ``` -The ```/callback``` route corresponds to the callback page, which is rendered by the Callback(Callback.js) component. The Callback component is also a functional component that handles the callback from the authorization server after the user logs in. It retrieves the authorization code from the URL, exchanges it for an access token and id token, and retrieves the user's information from the userinfo endpoint. It also sets the ```authenticated``` and ```userInfo``` state variables in the App(App.js) component and displays the ```logout``` button. When the ```logout``` button is clicked, the ```clearAuth``` function is called and the user's session is ended. The ```clearAuth``` function is defined in the App component and is called with no arguments. It initiates the end session flow by redirecting the user to the end session endpoint. +The `/callback` route corresponds to the callback page, which is rendered by the Callback(Callback.js) component. The Callback component is also a functional component that handles the callback from the authorization server after the user logs in. It retrieves the authorization code from the URL, exchanges it for an access token and id token, and retrieves the user's information from the userinfo endpoint. It also sets the `authenticated` and `userInfo` state variables in the App(App.js) component and displays the `logout` button. When the `logout` button is clicked, the `clearAuth` function is called and the user's session is ended. The `clearAuth` function is defined in the App component and is called with no arguments. It initiates the end session flow by redirecting the user to the end session endpoint. -5. Create a new file in the src folder named authConfig.js and paste the following code to it. +5. Create a new file in the src folder named authConfig.js and paste the following code to it. - [src/authConfig.js](https://github.com/zitadel/react-user-authentication/blob/main/src/authConfig.js) +[src/authConfig.js](https://github.com/zitadel/react-user-authentication/blob/main/src/authConfig.js) ``` const authConfig = { @@ -498,26 +545,27 @@ const authConfig = { }; export default authConfig; - ``` +``` - The authConfig.js file exports an object with configuration values for the OIDC flow. These values are used to initialize the ```UserManager``` instance in the App component. The configuration values include the: -- authority (the URL of the authorization server). ***Don’t forget to replace the ```authority``` value with the “issuer URL” that you obtained from this [step](#referred1).*** -- client_id (the unique identifier for the client application). ***Don’t forget to replace the ```client_id``` with your “ClientId” that you obtained from this [step](#referred1).*** +The authConfig.js file exports an object with configuration values for the OIDC flow. These values are used to initialize the `UserManager` instance in the App component. The configuration values include the: + +- authority (the URL of the authorization server). **_Don’t forget to replace the `authority` value with the “issuer URL” that you obtained from this [step](#referred1)._** +- client_id (the unique identifier for the client application). **_Don’t forget to replace the `client_id` with your “ClientId” that you obtained from this [step](#referred1)._** - redirect_uri (the URL to redirect to after the authorization flow is complete) - response_type (the type of response expected from the authorization server) - scope (the permissions requested from the user) - post_logout_redirect_uri (the URL to redirect to after the user logs out) -- userinfo_endpoint (the URL of the endpoint to retrieve the user's information). ***Don’t forget to replace the ```userinfo_endoint``` with your “userinfo_endpoint” that you obtained from this [step](#referred1).*** +- userinfo_endpoint (the URL of the endpoint to retrieve the user's information). **_Don’t forget to replace the `userinfo_endoint` with your “userinfo_endpoint” that you obtained from this [step](#referred1)._** - response_mode (the method to use to send the authorization response) -- code_challenge_method (the method to use to generate the code challenge). +- code_challenge_method (the method to use to generate the code challenge). Note that the oidc-client-ts library automatically handles the generation of the code verifier and code challenge when the user clicks on the login button, eliminating the need for the application to manually generate and include these values in the requests. -In the PKCE flow, the code verifier is a random string generated by the client application, and the code challenge is a transformed version of the code verifier using the SHA-256 hashing algorithm. +In the PKCE flow, the code verifier is a random string generated by the client application, and the code challenge is a transformed version of the code verifier using the SHA-256 hashing algorithm. 6. Add a file called style.css to the src folder to apply CSS styling to the pages. - [src/style.css](https://github.com/zitadel/react-user-authentication/blob/main/src/style.css) +[src/style.css](https://github.com/zitadel/react-user-authentication/blob/main/src/style.css) ``` /* The body element covers the entire page, so setting the background color here @@ -529,14 +577,14 @@ In the PKCE flow, the code verifier is a random string generated by the client a /* Center the text in the body element */ text-align: center; } - + /* The h1, h2, and h3 elements are used for headings */ h1, h2, h3 { /* The hex code for the dark blue color from the image is #2c3e50 */ color: #2c3e50; text-align: center; } - + /* The button element represents a clickable button */ button { /* The hex code for the light purple color from the image is #9b59b6 */ @@ -549,17 +597,16 @@ In the PKCE flow, the code verifier is a random string generated by the client a /* Add some hover effect to the button */ cursor: pointer; } - + button:hover { /* The hex code for the dark purple color from the image is #8e44ad */ background-color: #8e44ad; } - ``` +``` +7. Go to index.js and replace `import './index.css';` with `import './style.css'`. Your index.js file should look like this: -7. Go to index.js and replace ```import './index.css';``` with ```import './style.css'```. Your index.js file should look like this: - - [src/index.js](https://github.com/zitadel/react-user-authentication/blob/main/src/index.js) +[src/index.js](https://github.com/zitadel/react-user-authentication/blob/main/src/index.js) ``` import React from 'react'; @@ -583,13 +630,13 @@ reportWebVitals(); ### 4. Running the application -1. Run ```npm start``` to start the development server. -2. Open your browser and navigate to ```http://localhost:3000/``` to view the app. -3. You will see the login page, which is the landing page of the app, when you run the application. Click on the “Please log in” button. +1. Run `npm start` to start the development server. +2. Open your browser and navigate to `http://localhost:3000/` to view the app. +3. You will see the login page, which is the landing page of the app, when you run the application. Click on the “Please log in” button. ![Login](/img/guides/quickstart/login1.png) -4. You will be redirected to the ZITADEL login page. Add your username/email and click on “next”. +4. You will be redirected to the ZITADEL login page. Add your username/email and click on “next”. ![Redirect](/img/guides/quickstart/login2.png) @@ -601,22 +648,20 @@ reportWebVitals(); ![Redirect](/img/guides/quickstart/login4.png) -7. You can click on “Log out” to log out of the application and you will be taken to the landing page. +7. You can click on “Log out” to log out of the application and you will be taken to the landing page. ![Redirect](/img/guides/quickstart/login1.png) -8. To see if the user has been successfully logged out and the user session has been terminated, click on “Please log in”, which brings you to the following page. Select the same user you logged in with earlier. +8. To see if the user has been successfully logged out and the user session has been terminated, click on “Please log in”, which brings you to the following page. Select the same user you logged in with earlier. ![Redirect](/img/guides/quickstart/login5.png) -9. You will see that since the login session was terminated after logging out, the user has to enter his password again. +9. You will see that since the login session was terminated after logging out, the user has to enter his password again. ![Redirect](/img/guides/quickstart/login6.png) +And this brings us to the end of this quick start guide! -And this brings us to the end of this quick start guide! - -This tutorial covered how to configure ZITADEL and how to use React to build an app that communicates with ZITADEL to access secured resources. +This tutorial covered how to configure ZITADEL and how to use React to build an app that communicates with ZITADEL to access secured resources. We hope you enjoyed the tutorial and encourage you to check out the ZITADEL [documentation](https://zitadel.com/docs) for more information on how to use the ZITADEL platform to its full potential. Thanks for joining us! - diff --git a/docs/docs/support/advisory/a10000.md b/docs/docs/support/advisory/a10000.md index 1bdf0d2baa..5b7a8e20ff 100644 --- a/docs/docs/support/advisory/a10000.md +++ b/docs/docs/support/advisory/a10000.md @@ -2,6 +2,12 @@ title: Technical Advisory 10000 --- +## Date and Version + +Version: 2.32.0 + +Date: Calendar Week 32 + ## Description Currently, by default, users are directed to the "Select Account Page" on the ZITADEL login. @@ -14,7 +20,7 @@ To address this, we are going to change this behavior so that users will be auto ## Statement This behaviour change was tracked in the following issue: [Reuse current session if no prompt is selected](https://github.com/zitadel/zitadel/issues/4841) -and released in Version [v2.32.0](https://github.com/zitadel/zitadel/releases/tag/v2.32.0) +and released in version [v2.32.0](https://github.com/zitadel/zitadel/releases/tag/v2.32.0) ## Mitigation diff --git a/docs/docs/support/advisory/a10001.md b/docs/docs/support/advisory/a10001.md index 9fec2ff599..e082107c09 100644 --- a/docs/docs/support/advisory/a10001.md +++ b/docs/docs/support/advisory/a10001.md @@ -2,6 +2,12 @@ title: Technical Advisory 10001 --- +## Date and Version + +Version: 2.35.0 + +Date: Calendar Week 34 + ## Description Currently, disabling the `Allow Register` setting in the Login Policy, will disable any registration - local and through External Identity Providers (IDP). @@ -14,8 +20,8 @@ To address this, we are going to change the behavior of the setting mentioned ab ## Statement -This behaviour change is tracked in the following PR: [Restrict AllowRegistration check to local registration](https://github.com/zitadel/zitadel/pull/5939). -As soon as the release version is published, we will include the version here. +This behaviour change was tracked in the following PR: [Restrict AllowRegistration check to local registration](https://github.com/zitadel/zitadel/pull/5939). +The change was part of version [v2.35.0](https://github.com/zitadel/zitadel/releases/tag/v2.35.0) ## Mitigation diff --git a/docs/docs/support/advisory/a10002.md b/docs/docs/support/advisory/a10002.md new file mode 100644 index 0000000000..6d1e4dc4fc --- /dev/null +++ b/docs/docs/support/advisory/a10002.md @@ -0,0 +1,35 @@ +--- +title: Technical Advisory 10002 +--- + +## Date and Version + +Version: TBD + +Date: Calendar week 40/41 + +## Description + +Since Angular Material v15 many of the UI components have been refactored +to be based on the official Material Design Components for Web (MDC). +These refactored components do not support dynamic styling, so in order to keep the library up-to-date, +the console UI will loose its dynamic theming capability. + +## Statement + +This design change is tracked in the following PR: [feat(console): MDC components](https://github.com/zitadel/zitadel/pull/6482). +As soon as the release version is published, we will include the version here. + +## Mitigation + +If you need users to have your branding settings +(background-, button-, link and text coloring), you should implemement your +own user facing UI yourself and not use ZITADELs console UI. Assets like your logo and icons will still be used. + +## Impact + +Once this update has been released and deployed, the console UI won't apply any coloring of your branding settings to the UI components. + +:::note +ZITADEL hosted Login-UI is not affected by this change. +::: diff --git a/docs/docs/support/technical_advisory.mdx b/docs/docs/support/technical_advisory.mdx index 355f21a230..5d63fbcb8a 100644 --- a/docs/docs/support/technical_advisory.mdx +++ b/docs/docs/support/technical_advisory.mdx @@ -2,13 +2,12 @@ title: Technical Advisory --- -Technical advisories are notices that report major issues with ZITADEL Self-Hosted or the ZITADEL Cloud platform that could potentially impact security or stability in production environments. +Technical advisories are notices that report major issues with ZITADEL Self-Hosted or the ZITADEL Cloud platform that could potentially impact security or stability in production environments. These advisories may include details about the nature of the issue, its potential impact, and recommended mitigation actions. -Users are strongly encouraged to evaluate these advisories and consider the recommended mitigation actions independently from their version upgrade schedule. +Users are strongly encouraged to evaluate these advisories and consider the recommended mitigation actions independently from their version upgrade schedule. We understand that these advisories may include breaking changes, and we aim to provide clear guidance on how to address these changes. - @@ -19,20 +18,56 @@ We understand that these advisories may include breaking changes, and we aim to - + - + - + - + + + + + + + + + - +
    AdvisoryDate
    A-10000 + A-10000 + Reusing user session Breaking Behaviour ChangeThe default behavior for users logging in is to be directed to the Select Account Page on the Login. With the upcoming changes, users will be automatically authenticated when logging into a second application, as long as they only have one active session. No action is required on your part if this is the intended behavior. + The default behavior for users logging in is to be directed to the Select + Account Page on the Login. With the upcoming changes, users will be + automatically authenticated when logging into a second application, as + long as they only have one active session. No action is required on your + part if this is the intended behavior. + 2.32.0 Calendar week 32
    A-10001 + A-10001 + Login Policy - Allow Register Breaking Behaviour ChangeWhen disabling the option, users are currently not able to register locally and also not through an external IDP. With the upcoming change, the setting will only prevent local registration. Restriction to Identity Providers can be managed through the corresponding IDP Template. No action is required on your side if this is the intended behaviour or if you already disabled registration on your IDP. + When disabling the option, users are currently not able to register + locally and also not through an external IDP. With the upcoming change, + the setting will only prevent local registration. Restriction to Identity + Providers can be managed through the corresponding IDP Template. No action + is required on your side if this is the intended behaviour or if you + already disabled registration on your IDP. + 2.35.0Calendar week 34
    + A-10002 + Console - BrandingBreaking Design Change + Since Angular Material v15 many of the UI components have been refactored + to be based on the official Material Design Components for Web (MDC). + These refactored components do not support dynamic styling, so in order to + keep the library up-to-date, the console UI will loose its dynamic theming + capability. If you need users to have your branding settings (background-, + button-, link and text coloring) you should implement your own user + facing UI yourself and not use ZITADELs console UI. + ZITADEL hosted Login-UI is not affected by this change. + TBDCalendar week 34/35Calendar week 40/41
    @@ -51,4 +86,3 @@ A breaking behavior change refers to a modification or update that changes the b This change does not necessarily affect the APIs or any functions you are calling, so it may not require an update to your code. However, if you rely on specific results or behaviors, they may no longer be guaranteed after the change is implemented. Therefore, it is important to be aware of breaking behavior changes and their potential impact on your use of ZITADEL, and to take appropriate action if needed to ensure continued functionality. - diff --git a/docs/docs/support/troubleshooting.mdx b/docs/docs/support/troubleshooting.mdx index 76d3204638..12c1ed6f41 100644 --- a/docs/docs/support/troubleshooting.mdx +++ b/docs/docs/support/troubleshooting.mdx @@ -38,7 +38,7 @@ This claim identifies the audience, i.e. the resource server, that this token is If a resource server does not identify itself with a value in the "aud" claim when this claim is present, then the must be rejected (see [RFC7519](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3) for more details). You might encounter this error message from ZITADEL, typically when you authenticated with a client in one project and trying to access an application in another project. -You need add a specific [reserved scope](http://localhost:3000/docs/apis/openidoauth/scopes#reserved-scopes) to add the projectID to the audience of the access token. +You need add a specific [reserved scope](/docs/apis/openidoauth/scopes#reserved-scopes) to add the projectID to the audience of the access token. The two scenarios should help you troubleshoot this issue: diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index eff51f94ba..8e7dc19264 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -261,28 +261,28 @@ module.exports = { }, }, user: { - specPath: ".artifacts/openapi/zitadel/user/v2alpha/user_service.swagger.json", + specPath: ".artifacts/openapi/zitadel/user/v2beta/user_service.swagger.json", outputDir: "docs/apis/resources/user_service", sidebarOptions: { groupPathsBy: "tag", }, }, session: { - specPath: ".artifacts/openapi/zitadel/session/v2alpha/session_service.swagger.json", + specPath: ".artifacts/openapi/zitadel/session/v2beta/session_service.swagger.json", outputDir: "docs/apis/resources/session_service", sidebarOptions: { groupPathsBy: "tag", }, }, oidc: { - specPath: ".artifacts/openapi/zitadel/oidc/v2alpha/oidc_service.swagger.json", + specPath: ".artifacts/openapi/zitadel/oidc/v2beta/oidc_service.swagger.json", outputDir: "docs/apis/resources/oidc_service", sidebarOptions: { groupPathsBy: "tag", }, }, settings: { - specPath: ".artifacts/openapi/zitadel/settings/v2alpha/settings_service.swagger.json", + specPath: ".artifacts/openapi/zitadel/settings/v2beta/settings_service.swagger.json", outputDir: "docs/apis/resources/settings_service", sidebarOptions: { groupPathsBy: "tag", diff --git a/docs/sidebars.js b/docs/sidebars.js index 8ddf32ca67..55e1ebd8c6 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -144,6 +144,13 @@ module.exports = { type: "category", label: "Authenticate users", collapsed: true, + link: { + type: "generated-index", + title: "Authenticate human users", + slug: "guides/integrate/human-users", + description: + "How to authenticate human users with OpenID Connect", + }, items: [ "guides/integrate/login-users", "guides/integrate/oauth-recommended-flows", @@ -231,11 +238,11 @@ module.exports = { "guides/integrate/identity-providers/azure-ad", "guides/integrate/identity-providers/github", "guides/integrate/identity-providers/gitlab", + "guides/integrate/identity-providers/apple", "guides/integrate/identity-providers/ldap", "guides/integrate/identity-providers/openldap", "guides/integrate/identity-providers/migrate", - "guides/integrate/identity-providers/google-oidc", - "guides/integrate/identity-providers/azuread-oidc", + "guides/integrate/identity-providers/okta", ], }, { @@ -275,20 +282,20 @@ module.exports = { }, collapsed: true, items: [ - "guides/integrate/services/gitlab-self-hosted", - "guides/integrate/services/cloudflare-oidc", - "guides/integrate/services/aws-saml", - "guides/integrate/services/google-cloud", - "guides/integrate/services/atlassian-saml", - "guides/integrate/services/gitlab-saml", - "guides/integrate/services/auth0-oidc", - "guides/integrate/services/auth0-saml", - "guides/integrate/services/pingidentity-saml", + { + type: 'autogenerated', + dirName: 'guides/integrate/services', + }, { type: 'link', label: 'Nextcloud', href: 'https://zitadel.com/blog/zitadel-as-sso-provider-for-selfhosting', }, + { + type: 'link', + label: 'Bold BI (boldbi.com)', + href: 'https://support.boldbi.com/kb/article/13708/how-to-configure-zitadel-oauth-login-in-bold-bi', + }, { type: 'link', label: 'Cloudflare workers', @@ -309,6 +316,11 @@ module.exports = { label: 'Netbird (netbird.io)', href: 'https://docs.netbird.io/selfhosted/identity-providers', }, + { + type: 'link', + label: 'Zoho Desk (zoho.com)', + href: 'https://help.zoho.com/portal/en/kb/desk/user-management-and-security/data-security/articles/setting-up-saml-single-signon-for-help-center#Zitadel_IDP', + }, ], }, { @@ -439,6 +451,13 @@ module.exports = { type: "category", label: "Core Resources", collapsed: false, + link: { + type: "generated-index", + title: "Core Resources", + slug: "/apis/resources/", + description: + "Resource based API definitions", + }, items: [ { type: "category", @@ -493,57 +512,57 @@ module.exports = { }, { type: "category", - label: "User lifecycle (alpha)", + label: "User lifecycle (Beta)", link: { type: "generated-index", - title: "User service API (Alpha)", + title: "User service API (Beta)", slug: "/apis/resources/user_service", description: "This API is intended to manage users in a ZITADEL instance.\n"+ "\n"+ - "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.", + "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", }, items: require("./docs/apis/resources/user_service/sidebar.js"), }, { type: "category", - label: "Session lifecycle (Alpha)", + label: "Session lifecycle (Beta)", link: { type: "generated-index", - title: "Session service API (Alpha)", + title: "Session service API (Beta)", slug: "/apis/resources/session_service", description: "This API is intended to manage sessions in a ZITADEL instance.\n"+ "\n"+ - "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.", + "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", }, items: require("./docs/apis/resources/session_service/sidebar.js"), }, { type: "category", - label: "OIDC lifecycle (Alpha)", + label: "OIDC lifecycle (Beta)", link: { type: "generated-index", - title: "OIDC service API (Alpha)", + title: "OIDC service API (Beta)", slug: "/apis/resources/oidc_service", description: "Get OIDC Auth Request details and create callback URLs.\n"+ "\n"+ - "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.", + "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", }, items: require("./docs/apis/resources/oidc_service/sidebar.js"), }, { type: "category", - label: "Settings lifecycle (alpha)", + label: "Settings lifecycle (Beta)", link: { type: "generated-index", - title: "Settings service API (Alpha)", + title: "Settings service API (Beta)", slug: "/apis/resources/settings_service", description: "This API is intended to manage settings in a ZITADEL instance.\n"+ "\n"+ - "This project is in alpha state. It can AND will continue to break until the services provide the same functionality as the current login.", + "This project is in beta state. It can AND will continue to break until the services provide the same functionality as the current login.", }, items: require("./docs/apis/resources/settings_service/sidebar.js"), }, diff --git a/docs/static/img/guides/apple_login.png b/docs/static/img/guides/apple_login.png new file mode 100644 index 0000000000..eae5651a5e Binary files /dev/null and b/docs/static/img/guides/apple_login.png differ diff --git a/docs/static/img/guides/apple_service_create.png b/docs/static/img/guides/apple_service_create.png new file mode 100644 index 0000000000..051e6d22a5 Binary files /dev/null and b/docs/static/img/guides/apple_service_create.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-domain-sepcific-urls.png b/docs/static/img/guides/integrate/services/google-workspace-domain-sepcific-urls.png new file mode 100644 index 0000000000..e8ebd2f467 Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-domain-sepcific-urls.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-sso-bottom.png b/docs/static/img/guides/integrate/services/google-workspace-sso-bottom.png new file mode 100644 index 0000000000..8eba71b0bd Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-sso-bottom.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-sso-overview.png b/docs/static/img/guides/integrate/services/google-workspace-sso-overview.png new file mode 100644 index 0000000000..d32124d72d Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-sso-overview.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-sso-zitadel.png b/docs/static/img/guides/integrate/services/google-workspace-sso-zitadel.png new file mode 100644 index 0000000000..11a1f107d8 Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-sso-zitadel.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-zitadel-profile-configured.png b/docs/static/img/guides/integrate/services/google-workspace-zitadel-profile-configured.png new file mode 100644 index 0000000000..7ab469e011 Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-zitadel-profile-configured.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-zitadel-profile.png b/docs/static/img/guides/integrate/services/google-workspace-zitadel-profile.png new file mode 100644 index 0000000000..21b22f6528 Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-zitadel-profile.png differ diff --git a/docs/static/img/guides/integrate/services/google-workspace-zitadel-set-profile.png b/docs/static/img/guides/integrate/services/google-workspace-zitadel-set-profile.png new file mode 100644 index 0000000000..ebd8ddff39 Binary files /dev/null and b/docs/static/img/guides/integrate/services/google-workspace-zitadel-set-profile.png differ diff --git a/docs/static/img/guides/login-ui/authenticate-email-otp-flow.png b/docs/static/img/guides/login-ui/authenticate-email-otp-flow.png new file mode 100644 index 0000000000..bf940aff16 Binary files /dev/null and b/docs/static/img/guides/login-ui/authenticate-email-otp-flow.png differ diff --git a/docs/static/img/guides/login-ui/authenticate-phone-otp-flow.png b/docs/static/img/guides/login-ui/authenticate-phone-otp-flow.png new file mode 100644 index 0000000000..652344f8dd Binary files /dev/null and b/docs/static/img/guides/login-ui/authenticate-phone-otp-flow.png differ diff --git a/docs/static/img/guides/login-ui/authenticate-totp-flow.png b/docs/static/img/guides/login-ui/authenticate-totp-flow.png new file mode 100644 index 0000000000..4d0fa751be Binary files /dev/null and b/docs/static/img/guides/login-ui/authenticate-totp-flow.png differ diff --git a/docs/static/img/guides/login-ui/authenticate-u2f-flow.png b/docs/static/img/guides/login-ui/authenticate-u2f-flow.png new file mode 100644 index 0000000000..14e9093965 Binary files /dev/null and b/docs/static/img/guides/login-ui/authenticate-u2f-flow.png differ diff --git a/docs/static/img/guides/login-ui/register-email-otp-flow.png b/docs/static/img/guides/login-ui/register-email-otp-flow.png new file mode 100644 index 0000000000..4285e73af3 Binary files /dev/null and b/docs/static/img/guides/login-ui/register-email-otp-flow.png differ diff --git a/docs/static/img/guides/login-ui/register-phone-otp-flow.png b/docs/static/img/guides/login-ui/register-phone-otp-flow.png new file mode 100644 index 0000000000..3fd67bd4bf Binary files /dev/null and b/docs/static/img/guides/login-ui/register-phone-otp-flow.png differ diff --git a/docs/static/img/guides/okta_add_app.png b/docs/static/img/guides/okta_add_app.png new file mode 100644 index 0000000000..9f1b63c54b Binary files /dev/null and b/docs/static/img/guides/okta_add_app.png differ diff --git a/docs/static/img/guides/okta_login.png b/docs/static/img/guides/okta_login.png new file mode 100644 index 0000000000..8bc2ec34e5 Binary files /dev/null and b/docs/static/img/guides/okta_login.png differ diff --git a/docs/static/img/guides/zitadel_activate_apple.png b/docs/static/img/guides/zitadel_activate_apple.png new file mode 100644 index 0000000000..253d20c690 Binary files /dev/null and b/docs/static/img/guides/zitadel_activate_apple.png differ diff --git a/docs/static/img/guides/zitadel_activate_okta.png b/docs/static/img/guides/zitadel_activate_okta.png new file mode 100644 index 0000000000..f73218a2d5 Binary files /dev/null and b/docs/static/img/guides/zitadel_activate_okta.png differ diff --git a/docs/static/img/guides/zitadel_apple_create_provider.png b/docs/static/img/guides/zitadel_apple_create_provider.png new file mode 100644 index 0000000000..f1c18b6358 Binary files /dev/null and b/docs/static/img/guides/zitadel_apple_create_provider.png differ diff --git a/docs/static/img/guides/zitadel_identity_provider_overview.png b/docs/static/img/guides/zitadel_identity_provider_overview.png index 055917aee4..7cb9cfdd72 100644 Binary files a/docs/static/img/guides/zitadel_identity_provider_overview.png and b/docs/static/img/guides/zitadel_identity_provider_overview.png differ diff --git a/docs/static/img/guides/zitadel_login_apple.png b/docs/static/img/guides/zitadel_login_apple.png new file mode 100644 index 0000000000..b96dfa47d7 Binary files /dev/null and b/docs/static/img/guides/zitadel_login_apple.png differ diff --git a/docs/static/img/guides/zitadel_login_okta.png b/docs/static/img/guides/zitadel_login_okta.png new file mode 100644 index 0000000000..01c47dd2e1 Binary files /dev/null and b/docs/static/img/guides/zitadel_login_okta.png differ diff --git a/docs/static/img/guides/zitadel_okta_create_provider.png b/docs/static/img/guides/zitadel_okta_create_provider.png new file mode 100644 index 0000000000..6c62e7ccd7 Binary files /dev/null and b/docs/static/img/guides/zitadel_okta_create_provider.png differ diff --git a/e2e/cypress/e2e/organization/organizations.cy.ts b/e2e/cypress/e2e/organization/organizations.cy.ts index 83531c1ce3..6cf1185fe9 100644 --- a/e2e/cypress/e2e/organization/organizations.cy.ts +++ b/e2e/cypress/e2e/organization/organizations.cy.ts @@ -3,15 +3,38 @@ import { v4 as uuidv4 } from 'uuid'; import { Context } from 'support/commands'; const orgPath = `/org`; +const orgsPath = `/orgs`; +const orgsPathCreate = `/orgs/create`; const orgNameOnCreation = 'e2eorgrename'; const testOrgNameChange = uuidv4(); +const newOrg = uuidv4(); beforeEach(() => { cy.context().as('ctx'); }); describe('organizations', () => { + describe('add and delete org', () => { + it('should create an org', () => { + cy.visit(orgsPathCreate); + cy.get('[data-e2e="org-name-input"]').focus().clear().type(newOrg); + cy.get('[data-e2e="create-org-button"]').click(); + cy.contains('tr', newOrg); + }); + + it('should delete an org', () => { + cy.visit(orgsPath); + cy.contains('tr', newOrg).click(); + cy.get('[data-e2e="actions"]').click(); + cy.get('[data-e2e="delete"]', { timeout: 1000 }).should('be.visible').click(); + cy.get('[data-e2e="confirm-dialog-input"]').focus().clear().type(newOrg); + cy.get('[data-e2e="confirm-dialog-button"]').click(); + cy.shouldConfirmSuccess(); + cy.contains('tr', newOrg).should('not.exist'); + }); + }); + describe('rename', () => { beforeEach(() => { cy.get('@ctx').then((ctx) => { diff --git a/internal/admin/repository/eventsourcing/handler/styling.go b/internal/admin/repository/eventsourcing/handler/styling.go index 8d5107e788..ed96aa4633 100644 --- a/internal/admin/repository/eventsourcing/handler/styling.go +++ b/internal/admin/repository/eventsourcing/handler/styling.go @@ -207,6 +207,7 @@ func (m *Styling) writeFile(policy *iam_model.LabelPolicyView) (io.Reader, int64 } } if policy.FontColor != "" { + cssContent += fmt.Sprintf("--zitadel-color-label: %s;", policy.FontColor) palette := m.generateColorPaletteRGBA255(policy.FontColor) for i, color := range palette { cssContent += fmt.Sprintf("--zitadel-color-text-%v: %s;", i, color) @@ -242,6 +243,7 @@ func (m *Styling) writeFile(policy *iam_model.LabelPolicyView) (io.Reader, int64 } } if policy.FontColorDark != "" { + cssContent += fmt.Sprintf("--zitadel-color-label: %s;", policy.FontColorDark) palette := m.generateColorPaletteRGBA255(policy.FontColorDark) for i, color := range palette { cssContent += fmt.Sprintf("--zitadel-color-text-%v: %s;", i, color) diff --git a/internal/api/grpc/object/v2/converter.go b/internal/api/grpc/object/v2/converter.go index 6c03e79a8c..36c6a322bc 100644 --- a/internal/api/grpc/object/v2/converter.go +++ b/internal/api/grpc/object/v2/converter.go @@ -8,7 +8,7 @@ import ( "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" ) func DomainToDetailsPb(objectDetail *domain.ObjectDetails) *object.Details { diff --git a/internal/api/grpc/oidc/v2/oidc.go b/internal/api/grpc/oidc/v2/oidc.go index 4675dfc6f1..d35a5dcff0 100644 --- a/internal/api/grpc/oidc/v2/oidc.go +++ b/internal/api/grpc/oidc/v2/oidc.go @@ -15,7 +15,7 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/query" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" ) func (s *Server) GetAuthRequest(ctx context.Context, req *oidc_pb.GetAuthRequestRequest) (*oidc_pb.GetAuthRequestResponse, error) { diff --git a/internal/api/grpc/oidc/v2/oidc_integration_test.go b/internal/api/grpc/oidc/v2/oidc_integration_test.go index b48bfc0834..b64b71325d 100644 --- a/internal/api/grpc/oidc/v2/oidc_integration_test.go +++ b/internal/api/grpc/oidc/v2/oidc_integration_test.go @@ -15,10 +15,10 @@ import ( "github.com/stretchr/testify/require" "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var ( diff --git a/internal/api/grpc/oidc/v2/oidc_test.go b/internal/api/grpc/oidc/v2/oidc_test.go index 91d795a00a..27dcdf7fb7 100644 --- a/internal/api/grpc/oidc/v2/oidc_test.go +++ b/internal/api/grpc/oidc/v2/oidc_test.go @@ -12,7 +12,7 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" ) func Test_authRequestToPb(t *testing.T) { diff --git a/internal/api/grpc/oidc/v2/server.go b/internal/api/grpc/oidc/v2/server.go index f15401d1bc..a7587dfdcf 100644 --- a/internal/api/grpc/oidc/v2/server.go +++ b/internal/api/grpc/oidc/v2/server.go @@ -8,7 +8,7 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/server" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/query" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" ) var _ oidc_pb.OIDCServiceServer = (*Server)(nil) diff --git a/internal/api/grpc/org/converter.go b/internal/api/grpc/org/converter.go index a73d77a279..142df950e5 100644 --- a/internal/api/grpc/org/converter.go +++ b/internal/api/grpc/org/converter.go @@ -103,8 +103,6 @@ func OrgStateToPb(state domain.OrgState) org_pb.OrgState { return org_pb.OrgState_ORG_STATE_ACTIVE case domain.OrgStateInactive: return org_pb.OrgState_ORG_STATE_INACTIVE - case domain.OrgStateRemoved: - return org_pb.OrgState_ORG_STATE_REMOVED default: return org_pb.OrgState_ORG_STATE_UNSPECIFIED } @@ -116,8 +114,6 @@ func OrgStateToDomain(state org_pb.OrgState) domain.OrgState { return domain.OrgStateActive case org_pb.OrgState_ORG_STATE_INACTIVE: return domain.OrgStateInactive - case org_pb.OrgState_ORG_STATE_REMOVED: - return domain.OrgStateRemoved case org_pb.OrgState_ORG_STATE_UNSPECIFIED: fallthrough default: diff --git a/internal/api/grpc/org/v2/org_integration_test.go b/internal/api/grpc/org/v2/org_integration_test.go index c8dbcff81f..d369cbeea7 100644 --- a/internal/api/grpc/org/v2/org_integration_test.go +++ b/internal/api/grpc/org/v2/org_integration_test.go @@ -15,7 +15,7 @@ import ( "github.com/zitadel/zitadel/internal/integration" org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var ( diff --git a/internal/api/grpc/org/v2/org_test.go b/internal/api/grpc/org/v2/org_test.go index 2f2797ac75..c8c4c0ea0d 100644 --- a/internal/api/grpc/org/v2/org_test.go +++ b/internal/api/grpc/org/v2/org_test.go @@ -12,9 +12,9 @@ import ( "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func Test_addOrganizationRequestToCommand(t *testing.T) { diff --git a/internal/api/grpc/server/middleware/auth_interceptor.go b/internal/api/grpc/server/middleware/auth_interceptor.go index e9d90c7cfa..96426e8577 100644 --- a/internal/api/grpc/server/middleware/auth_interceptor.go +++ b/internal/api/grpc/server/middleware/auth_interceptor.go @@ -11,7 +11,6 @@ import ( grpc_util "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/telemetry/tracing" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" ) func AuthorizationInterceptor(verifier *authz.TokenVerifier, authConfig authz.Config) grpc.UnaryServerInterceptor { @@ -37,10 +36,9 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, var orgDomain string orgID := grpc_util.GetHeader(authCtx, http.ZitadelOrgID) if o, ok := req.(OrganisationFromRequest); ok { - orgID = o.OrganisationFromRequest().GetOrgId() - orgDomain = o.OrganisationFromRequest().GetOrgDomain() + orgID = o.OrganisationFromRequest().ID + orgDomain = o.OrganisationFromRequest().Domain } - ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod) if err != nil { return nil, err @@ -50,5 +48,10 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, } type OrganisationFromRequest interface { - OrganisationFromRequest() *object.Organisation + OrganisationFromRequest() *Organisation +} + +type Organisation struct { + ID string + Domain string } diff --git a/internal/api/grpc/session/v2/server.go b/internal/api/grpc/session/v2/server.go index 3dc5a0c839..7450d6efd1 100644 --- a/internal/api/grpc/session/v2/server.go +++ b/internal/api/grpc/session/v2/server.go @@ -8,7 +8,7 @@ import ( "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" ) var _ session.SessionServiceServer = (*Server)(nil) diff --git a/internal/api/grpc/session/v2/session.go b/internal/api/grpc/session/v2/session.go index 392d31ded2..fe8e0d8744 100644 --- a/internal/api/grpc/session/v2/session.go +++ b/internal/api/grpc/session/v2/session.go @@ -12,7 +12,7 @@ import ( "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/query" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" ) func (s *Server) GetSession(ctx context.Context, req *session.GetSessionRequest) (*session.GetSessionResponse, error) { diff --git a/internal/api/grpc/session/v2/session_integration_test.go b/internal/api/grpc/session/v2/session_integration_test.go index 23c4871419..1dcad7bc53 100644 --- a/internal/api/grpc/session/v2/session_integration_test.go +++ b/internal/api/grpc/session/v2/session_integration_test.go @@ -16,9 +16,9 @@ import ( "google.golang.org/grpc/metadata" "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var ( diff --git a/internal/api/grpc/session/v2/session_test.go b/internal/api/grpc/session/v2/session_test.go index a7d725899c..33804caba5 100644 --- a/internal/api/grpc/session/v2/session_test.go +++ b/internal/api/grpc/session/v2/session_test.go @@ -14,8 +14,8 @@ import ( "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/query" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" ) func Test_sessionsToPb(t *testing.T) { diff --git a/internal/api/grpc/settings/v2/server.go b/internal/api/grpc/settings/v2/server.go index ea6ebd4a25..f001549595 100644 --- a/internal/api/grpc/settings/v2/server.go +++ b/internal/api/grpc/settings/v2/server.go @@ -10,7 +10,7 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/server" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/query" - settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha" + settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta" ) var _ settings.SettingsServiceServer = (*Server)(nil) diff --git a/internal/api/grpc/settings/v2/settings.go b/internal/api/grpc/settings/v2/settings.go index bf00d8084c..ff458fa98d 100644 --- a/internal/api/grpc/settings/v2/settings.go +++ b/internal/api/grpc/settings/v2/settings.go @@ -9,8 +9,8 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/api/grpc/text" "github.com/zitadel/zitadel/internal/query" - object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha" + object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta" ) func (s *Server) GetLoginSettings(ctx context.Context, req *settings.GetLoginSettingsRequest) (*settings.GetLoginSettingsResponse, error) { diff --git a/internal/api/grpc/settings/v2/settings_converter.go b/internal/api/grpc/settings/v2/settings_converter.go index f48177e1df..7c28776299 100644 --- a/internal/api/grpc/settings/v2/settings_converter.go +++ b/internal/api/grpc/settings/v2/settings_converter.go @@ -5,7 +5,7 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" - settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha" + settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta" ) func loginSettingsToPb(current *query.LoginPolicy) *settings.LoginSettings { diff --git a/internal/api/grpc/settings/v2/settings_converter_test.go b/internal/api/grpc/settings/v2/settings_converter_test.go index 37ad664f48..133715d8b1 100644 --- a/internal/api/grpc/settings/v2/settings_converter_test.go +++ b/internal/api/grpc/settings/v2/settings_converter_test.go @@ -14,7 +14,7 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" - settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha" + settings "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta" ) var ignoreTypes = []protoreflect.FullName{"google.protobuf.Duration"} diff --git a/internal/api/grpc/user/v2/email.go b/internal/api/grpc/user/v2/email.go index d1c91333e0..83f771b358 100644 --- a/internal/api/grpc/user/v2/email.go +++ b/internal/api/grpc/user/v2/email.go @@ -7,8 +7,8 @@ import ( "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) SetEmail(ctx context.Context, req *user.SetEmailRequest) (resp *user.SetEmailResponse, err error) { diff --git a/internal/api/grpc/user/v2/email_integration_test.go b/internal/api/grpc/user/v2/email_integration_test.go index 8b3f0b0137..53abd7c850 100644 --- a/internal/api/grpc/user/v2/email_integration_test.go +++ b/internal/api/grpc/user/v2/email_integration_test.go @@ -8,10 +8,11 @@ import ( "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/integration" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_SetEmail(t *testing.T) { diff --git a/internal/api/grpc/user/v2/otp.go b/internal/api/grpc/user/v2/otp.go index 6e8e7686c8..9e239fdfc4 100644 --- a/internal/api/grpc/user/v2/otp.go +++ b/internal/api/grpc/user/v2/otp.go @@ -5,7 +5,7 @@ import ( "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) AddOTPSMS(ctx context.Context, req *user.AddOTPSMSRequest) (*user.AddOTPSMSResponse, error) { diff --git a/internal/api/grpc/user/v2/otp_integration_test.go b/internal/api/grpc/user/v2/otp_integration_test.go index 9f99596f2e..bf205ac87c 100644 --- a/internal/api/grpc/user/v2/otp_integration_test.go +++ b/internal/api/grpc/user/v2/otp_integration_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/require" "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_AddOTPSMS(t *testing.T) { diff --git a/internal/api/grpc/user/v2/passkey.go b/internal/api/grpc/user/v2/passkey.go index 1b4414474c..97a853bfdd 100644 --- a/internal/api/grpc/user/v2/passkey.go +++ b/internal/api/grpc/user/v2/passkey.go @@ -9,8 +9,8 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) RegisterPasskey(ctx context.Context, req *user.RegisterPasskeyRequest) (resp *user.RegisterPasskeyResponse, err error) { diff --git a/internal/api/grpc/user/v2/passkey_integration_test.go b/internal/api/grpc/user/v2/passkey_integration_test.go index dbc6b11785..139bef3e68 100644 --- a/internal/api/grpc/user/v2/passkey_integration_test.go +++ b/internal/api/grpc/user/v2/passkey_integration_test.go @@ -9,10 +9,11 @@ import ( "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" "google.golang.org/protobuf/types/known/structpb" + + "github.com/zitadel/zitadel/internal/integration" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_RegisterPasskey(t *testing.T) { diff --git a/internal/api/grpc/user/v2/passkey_test.go b/internal/api/grpc/user/v2/passkey_test.go index fe8d397b54..8071db92bf 100644 --- a/internal/api/grpc/user/v2/passkey_test.go +++ b/internal/api/grpc/user/v2/passkey_test.go @@ -14,8 +14,8 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func Test_passkeyAuthenticatorToDomain(t *testing.T) { diff --git a/internal/api/grpc/user/v2/password.go b/internal/api/grpc/user/v2/password.go index 62a0b4458e..c0837d799f 100644 --- a/internal/api/grpc/user/v2/password.go +++ b/internal/api/grpc/user/v2/password.go @@ -7,7 +7,7 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) PasswordReset(ctx context.Context, req *user.PasswordResetRequest) (_ *user.PasswordResetResponse, err error) { diff --git a/internal/api/grpc/user/v2/password_integration_test.go b/internal/api/grpc/user/v2/password_integration_test.go index 2c8d50c9a2..b0074982bd 100644 --- a/internal/api/grpc/user/v2/password_integration_test.go +++ b/internal/api/grpc/user/v2/password_integration_test.go @@ -12,8 +12,8 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_RequestPasswordReset(t *testing.T) { diff --git a/internal/api/grpc/user/v2/password_test.go b/internal/api/grpc/user/v2/password_test.go index b80f0abd3f..5ce9930b39 100644 --- a/internal/api/grpc/user/v2/password_test.go +++ b/internal/api/grpc/user/v2/password_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/zitadel/zitadel/internal/domain" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func Test_notificationTypeToDomain(t *testing.T) { diff --git a/internal/api/grpc/user/v2/phone.go b/internal/api/grpc/user/v2/phone.go index c6d46e8341..9e97bb0195 100644 --- a/internal/api/grpc/user/v2/phone.go +++ b/internal/api/grpc/user/v2/phone.go @@ -7,8 +7,8 @@ import ( "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) SetPhone(ctx context.Context, req *user.SetPhoneRequest) (resp *user.SetPhoneResponse, err error) { diff --git a/internal/api/grpc/user/v2/phone_integration_test.go b/internal/api/grpc/user/v2/phone_integration_test.go index 5fc75e7cd3..239f86ca9f 100644 --- a/internal/api/grpc/user/v2/phone_integration_test.go +++ b/internal/api/grpc/user/v2/phone_integration_test.go @@ -11,8 +11,8 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/integration" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_SetPhone(t *testing.T) { diff --git a/internal/api/grpc/user/v2/server.go b/internal/api/grpc/user/v2/server.go index 13ee611776..83cf58c5df 100644 --- a/internal/api/grpc/user/v2/server.go +++ b/internal/api/grpc/user/v2/server.go @@ -10,7 +10,7 @@ import ( "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/query" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var _ user.UserServiceServer = (*Server)(nil) diff --git a/internal/api/grpc/user/v2/totp.go b/internal/api/grpc/user/v2/totp.go index 494c558983..e2ab157104 100644 --- a/internal/api/grpc/user/v2/totp.go +++ b/internal/api/grpc/user/v2/totp.go @@ -6,7 +6,7 @@ import ( "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/domain" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) RegisterTOTP(ctx context.Context, req *user.RegisterTOTPRequest) (*user.RegisterTOTPResponse, error) { diff --git a/internal/api/grpc/user/v2/totp_integration_test.go b/internal/api/grpc/user/v2/totp_integration_test.go index 66d286cff4..18a5e43bd1 100644 --- a/internal/api/grpc/user/v2/totp_integration_test.go +++ b/internal/api/grpc/user/v2/totp_integration_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/zitadel/zitadel/internal/integration" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_RegisterTOTP(t *testing.T) { diff --git a/internal/api/grpc/user/v2/totp_test.go b/internal/api/grpc/user/v2/totp_test.go index 021717283b..81a54675f2 100644 --- a/internal/api/grpc/user/v2/totp_test.go +++ b/internal/api/grpc/user/v2/totp_test.go @@ -10,8 +10,8 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/domain" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func Test_totpDetailsToPb(t *testing.T) { diff --git a/internal/api/grpc/user/v2/u2f.go b/internal/api/grpc/user/v2/u2f.go index 5178125f7a..8a935fe361 100644 --- a/internal/api/grpc/user/v2/u2f.go +++ b/internal/api/grpc/user/v2/u2f.go @@ -7,7 +7,7 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) RegisterU2F(ctx context.Context, req *user.RegisterU2FRequest) (*user.RegisterU2FResponse, error) { diff --git a/internal/api/grpc/user/v2/u2f_integration_test.go b/internal/api/grpc/user/v2/u2f_integration_test.go index 93c0b4c0a6..febe0ddfb1 100644 --- a/internal/api/grpc/user/v2/u2f_integration_test.go +++ b/internal/api/grpc/user/v2/u2f_integration_test.go @@ -11,7 +11,7 @@ import ( "google.golang.org/protobuf/types/known/structpb" "github.com/zitadel/zitadel/internal/integration" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func TestServer_RegisterU2F(t *testing.T) { diff --git a/internal/api/grpc/user/v2/u2f_test.go b/internal/api/grpc/user/v2/u2f_test.go index 1fe70a91d1..0a4aaf9563 100644 --- a/internal/api/grpc/user/v2/u2f_test.go +++ b/internal/api/grpc/user/v2/u2f_test.go @@ -13,8 +13,8 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func Test_u2fRegistrationDetailsToPb(t *testing.T) { diff --git a/internal/api/grpc/user/v2/user.go b/internal/api/grpc/user/v2/user.go index cc24e05ada..76cd067c49 100644 --- a/internal/api/grpc/user/v2/user.go +++ b/internal/api/grpc/user/v2/user.go @@ -18,8 +18,8 @@ import ( "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/ldap" "github.com/zitadel/zitadel/internal/query" - object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) func (s *Server) AddHumanUser(ctx context.Context, req *user.AddHumanUserRequest) (_ *user.AddHumanUserResponse, err error) { diff --git a/internal/api/grpc/user/v2/user_integration_test.go b/internal/api/grpc/user/v2/user_integration_test.go index 61ce038ff8..cf69969f33 100644 --- a/internal/api/grpc/user/v2/user_integration_test.go +++ b/internal/api/grpc/user/v2/user_integration_test.go @@ -19,8 +19,8 @@ import ( "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/integration" mgmt "github.com/zitadel/zitadel/pkg/grpc/management" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var ( diff --git a/internal/api/grpc/user/v2/user_test.go b/internal/api/grpc/user/v2/user_test.go index 768edad39a..e454bc5ae3 100644 --- a/internal/api/grpc/user/v2/user_test.go +++ b/internal/api/grpc/user/v2/user_test.go @@ -18,8 +18,8 @@ import ( "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/eventstore" - object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var ignoreTypes = []protoreflect.FullName{"google.protobuf.Duration", "google.protobuf.Struct"} diff --git a/internal/api/oidc/auth_request_integration_test.go b/internal/api/oidc/auth_request_integration_test.go index 1c5074e894..532814bee1 100644 --- a/internal/api/oidc/auth_request_integration_test.go +++ b/internal/api/oidc/auth_request_integration_test.go @@ -17,8 +17,8 @@ import ( http_utils "github.com/zitadel/zitadel/internal/api/http" oidc_api "github.com/zitadel/zitadel/internal/api/oidc" "github.com/zitadel/zitadel/internal/command" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" ) var ( diff --git a/internal/api/oidc/client_integration_test.go b/internal/api/oidc/client_integration_test.go index bc806ddd75..11121a8fae 100644 --- a/internal/api/oidc/client_integration_test.go +++ b/internal/api/oidc/client_integration_test.go @@ -15,7 +15,7 @@ import ( "github.com/zitadel/zitadel/pkg/grpc/authn" "github.com/zitadel/zitadel/pkg/grpc/management" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" ) func TestOPStorage_SetUserinfoFromToken(t *testing.T) { diff --git a/internal/api/oidc/oidc_integration_test.go b/internal/api/oidc/oidc_integration_test.go index 88dda2b926..1a1516040d 100644 --- a/internal/api/oidc/oidc_integration_test.go +++ b/internal/api/oidc/oidc_integration_test.go @@ -18,9 +18,9 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/auth" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) var ( diff --git a/internal/api/ui/login/init_user_handler.go b/internal/api/ui/login/init_user_handler.go index c058c62436..fb4b8b8459 100644 --- a/internal/api/ui/login/init_user_handler.go +++ b/internal/api/ui/login/init_user_handler.go @@ -121,10 +121,14 @@ func (l *Login) renderInitUser(w http.ResponseWriter, r *http.Request, authReq * baseData: l.getBaseData(r, authReq, "InitUser.Title", "InitUser.Description", errID, errMessage), profileData: l.getProfileData(authReq), UserID: userID, - LoginName: loginName, Code: code, PasswordSet: passwordSet, } + // if the user clicked on the link in the mail, we need to make sure the loginName is rendered + if authReq == nil { + data.LoginName = loginName + data.UserName = loginName + } policy := l.getPasswordComplexityPolicyByUserID(r, userID) if policy != nil { data.MinLength = policy.MinLength diff --git a/internal/api/ui/login/static/i18n/bg.yaml b/internal/api/ui/login/static/i18n/bg.yaml index 819073c5de..8e834db180 100644 --- a/internal/api/ui/login/static/i18n/bg.yaml +++ b/internal/api/ui/login/static/i18n/bg.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: 'Изберете своя акаунт, който да свържете с вашия външен потребител.' OtherUser: Друг потребител SessionState0: активен - SessionState1: неактивен + SessionState1: Не сте в профила си MustBeMemberOfOrg: 'Потребителят трябва да е член на {{.OrgName}} организация.' Password: Title: Парола diff --git a/internal/api/ui/login/static/i18n/de.yaml b/internal/api/ui/login/static/i18n/de.yaml index 6ae40c99c7..921026a1a9 100644 --- a/internal/api/ui/login/static/i18n/de.yaml +++ b/internal/api/ui/login/static/i18n/de.yaml @@ -1,31 +1,31 @@ Login: Title: Anmeldung - Description: Mit ZITADEL-Konto anmelden. - TitleLinking: Anmeldung für Benutzer Linking - DescriptionLinking: Gib deine Benutzerdaten ein um den externen Benutzer mit einem ZITADEL Benutzer zu linken. + Description: Bitte gib deine Anmeldedaten ein. + TitleLinking: Anmeldung für Kontoverknüpfung + DescriptionLinking: Gib deine Benutzerdaten ein um ein externes Benutzerkonto zu verknüpfen. LoginNameLabel: Loginname UsernamePlaceHolder: username LoginnamePlaceHolder: username@domain - ExternalUserDescription: oder melde dich mit einem externen Benutzer an + ExternalUserDescription: oder melde dich mit einem externen Benutzerkonto an MustBeMemberOfOrg: Der Benutzer muss der Organisation {{.OrgName}} angehören. - RegisterButtonText: registrieren - NextButtonText: weiter + RegisterButtonText: Registrieren + NextButtonText: Weiter LDAP: Title: Anmeldung Description: Mit Konto anmelden. LoginNameLabel: Loginname PasswordLabel: Passwort - NextButtonText: weiter + NextButtonText: Weiter SelectAccount: - Title: Account auswählen - Description: Wähle deinen Account aus. - TitleLinking: Account auswählen um zu verlinken - DescriptionLinking: Wähle deinen Account, um diesen mit deinem externen Benutzer zu verlinken. + Title: Konto auswählen + Description: Wähle dein Konto aus. + TitleLinking: Konto auswählen um zu verknüpfen + DescriptionLinking: Wähle dein Konto, um dieses mit deinem externen Benutzerkonto zu verbinden. OtherUser: Anderer Benutzer SessionState0: aktiv - SessionState1: inaktiv + SessionState1: Abgemeldet MustBeMemberOfOrg: Der Benutzer muss der Organisation {{.OrgName}} angehören. Password: @@ -33,89 +33,89 @@ Password: Description: Gib deine Benutzerdaten ein. PasswordLabel: Passwort MinLength: Mindestlänge - HasUppercase: Grossbuchstaben + HasUppercase: Großbuchstaben HasLowercase: Kleinbuchstaben HasNumber: Nummer HasSymbol: Symbol - Confirmation: Bestätigung stimmt überein - ResetLinkText: Password zurücksetzen - BackButtonText: zurück - NextButtonText: weiter + Confirmation: Wiederholung stimmt überein + ResetLinkText: Passwort zurücksetzen + BackButtonText: Zurück + NextButtonText: Weiter UsernameChange: - Title: Usernamen ändern + Title: Benutzernamen ändern Description: Wähle deinen neuen Benutzernamen UsernameLabel: Benutzernamen - CancelButtonText: abbrechen - NextButtonText: weiter + CancelButtonText: Abbrechen + NextButtonText: Weiter UsernameChangeDone: - Title: Username geändert - Description: Der Username wurde erfolgreich geändert. - NextButtonText: next + Title: Bentzername geändert + Description: Der Benutzername wurde erfolgreich geändert. + NextButtonText: Weiter InitPassword: Title: Passwort setzen - Description: Du hast einen Code erhalten, welcher im untenstehenden Formular eingegeben werden muss um ein neues Passwort zu setzen. + Description: Du hast einen Code erhalten, welcher im untenstehenden Formular eingegeben werden muss, um ein neues Passwort zu setzen. CodeLabel: Code NewPasswordLabel: Neues Passwort - NewPasswordConfirmLabel: Passwort bestätigen + NewPasswordConfirmLabel: Passwort wiederholen ResendButtonText: Code erneut senden - NextButtonText: weiter + NextButtonText: Weiter InitPasswordDone: Title: Passwort gesetzt Description: Passwort erfolgreich gesetzt - NextButtonText: weiter - CancelButtonText: abbrechen + NextButtonText: Weiter + CancelButtonText: Abbrechen InitUser: - Title: User aktivieren - Description: Bestätige deine E-Mail mit dem unten stehenden Code und legen dein Passwort fest. + Title: Benutzer aktivieren + Description: Bestätige deine E-Mail-Adresse mit dem unten stehenden Code und lege dein Passwort fest. CodeLabel: Code NewPasswordLabel: Neues Passwort NewPasswordConfirm: Passwort bestätigen - NextButtonText: weiter + NextButtonText: Weiter ResendButtonText: Code erneut senden InitUserDone: - Title: User aktiviert + Title: Benutzer aktiviert Description: E-Mail verifiziert und Passwort erfolgreich gesetzt - NextButtonText: weiter - CancelButtonText: abbrechen + NextButtonText: Weiter + CancelButtonText: Abbrechen InitMFAPrompt: - Title: 2-Faktor hinzufügen - Description: 2-Faktor-Authentifizierung gibt dir eine zusätzliche Sicherheit für dein Benutzerkonto. Damit stellst du sicher, dass nur du Zugriff auf deinen Account hast. - Provider0: Authenticator App (e.g Google/Microsoft Authenticator, Authy) - Provider1: Geräte abhängig (e.g FaceID, Windows Hello, Fingerprint) - Provider3: OTP SMS - Provider4: OTP Email - NextButtonText: weiter - SkipButtonText: überspringen + Title: Zweitfaktor hinzufügen + Description: Zwei-Faktor-Authentifizierung gibt dir eine zusätzliche Sicherheit für dein Benutzerkonto. Damit stellst du sicher, dass nur du Zugriff auf dein Konto hast. + Provider0: Authentifizierungs-App (z.B. Google/Microsoft Authenticator, Authy) + Provider1: Geräte-gebunden (z.B. FaceID, Windows Hello, Fingerprint) + Provider3: Einmalpasswort per SMS + Provider4: Einmalpasswort per E-Mail + NextButtonText: Weiter + SkipButtonText: Überspringen InitMFAOTP: - Title: 2-Faktor Verifizierung - Description: Erstelle deinen 2-Faktor. Lade eine Authenticator-App herunter, wenn du noch keines hast. - OTPDescription: Scanne den Code mit einem Authentifizierungs-App (z.B Google/Mircorsoft Authenticator, Authy) oder kopiere das Secret und gib anschliessend den Code ein. + Title: Zwei-Faktor-Anmeldung + Description: Erstelle deinen Zweitfaktor. Installiere eine Authentifizierungs-App, wenn du noch keine hast. + OTPDescription: Scanne den Code mit einer Authentifizierungs-App (z.B. Google/Mircorsoft Authenticator, Authy) oder kopiere das Secret und gib anschliessend den Code ein. SecretLabel: Secret CodeLabel: Code - NextButtonText: weiter - CancelButtonText: abbrechen + NextButtonText: Weiter + CancelButtonText: Abbrechen InitMFAOTPSMS: - Title: 2-Faktor hinzufügen - DescriptionPhone: Erstelle deinen 2-Faktor. Gib deine Telefonnummer ein, um sie zu verifizieren. - DescriptionCode: Erstelle deinen 2-Faktor. Gib den erhaltenen Code ein um deinen Telefonnummer zu verifizieren. + Title: Zweitfaktor hinzufügen + DescriptionPhone: Erstelle deinen Zweitfaktor. Gib deine Telefonnummer ein, um sie zu verifizieren. + DescriptionCode: Erstelle deinen Zweitfaktor. Gib den erhaltenen Code ein, um deine Telefonnummer zu verifizieren. PhoneLabel: Telefonnummer CodeLabel: Code - EditButtonText: bearbeiten + EditButtonText: Bearbeiten ResendButtonText: Code erneut senden - NextButtonText: weiter + NextButtonText: Weiter InitMFAU2F: Title: Sicherheitsschlüssel hinzufügen - Description: Ein Sicherheitsschlüssel ist eine Verifizierungsmethode, die in Ihrem Telefon integriert sein kann, Bluetooth verwenden oder direkt an den USB-Anschluss Ihres Computers angeschlossen werden. + Description: Ein Sicherheitsschlüssel ist eine Verifizierungsmethode, die in deinem Telefon integriert sein kann, oder ein externes Gerät, das über Bluetooth oder USB mit deinem Computer verbunden wird. TokenNameLabel: Name des Geräts NotSupported: WebAuthN wird durch deinen Browser nicht unterstützt. Stelle sicher, dass du die aktuelle Version installiert hast oder nutze eine anderen (z.B. Chrome, Safari, Firefox) RegisterTokenButtonText: Sicherschlüssel hinzufügen @@ -123,56 +123,56 @@ InitMFAU2F: InitMFADone: Title: Sicherheitsschlüssel eingerichtet - Description: Großartig! Du hast gerade erfolgreich deinen 2-Faktor eingerichtet und dein Konto viel sicherer gemacht. Der 2-Faktor muss bei jeder Anmeldung verwendet werden. - NextButtonText: weiter - CancelButtonText: abbrechen + Description: Großartig! Du hast gerade erfolgreich deinen Zweitfaktor eingerichtet und dein Konto viel sicherer gemacht. Der Zweitfaktor muss bei jeder Anmeldung verwendet werden. + NextButtonText: Weiter + CancelButtonText: Abbrechen MFAProvider: - Provider0: Authenticator App (e.g Google/Microsoft Authenticator, Authy) - Provider1: Geräte abhängig (e.g FaceID, Windows Hello, Fingerprint) - Provider3: OTP SMS - Provider4: OTP Email + Provider0: Authentifizierungs-App (z.B. Google/Microsoft Authenticator, Authy) + Provider1: Geräte-gebunden (z.B. FaceID, Windows Hello, Fingerprint) + Provider3: Einmalpasswort per SMS + Provider4: Einmalpasswort per E-Mail ChooseOther: oder wähle eine andere Option aus VerifyMFAOTP: - Title: 2-Faktor verifizieren + Title: Zweitfaktor verifizieren Description: Verifiziere deinen Zweitfaktor CodeLabel: Code - NextButtonText: next + NextButtonText: Weiter VerifyOTP: - Title: 2-Faktor verifizieren + Title: Zweitfaktor verifizieren Description: Verifiziere deinen Zweitfaktor CodeLabel: Code ResendButtonText: Code erneut senden - NextButtonText: next + NextButtonText: Weiter VerifyMFAU2F: - Title: 2-Faktor Verifizierung + Title: Zwei-Faktor Verifizierung Description: Verifiziere deinen Multifaktor U2F / WebAuthN Token NotSupported: WebAuthN wird durch deinen Browser nicht unterstützt. Stelle sicher, dass du die aktuelle Version installiert hast oder nutze einen anderen (z.B. Chrome, Safari, Firefox) ErrorRetry: Versuche es erneut, erstelle eine neue Abfrage oder wähle einen andere Methode. - ValidateTokenButtonText: 2-Faktor verifizieren + ValidateTokenButtonText: Zweitfaktor verifizieren Passwordless: Title: Passwortlos einloggen - Description: Melden Sie sich mit den von Ihrem Gerät bereitgestellten Authentifizierungsmethoden wie FaceID, Windows Hello oder Fingerabdruck an. + Description: Melde dich mit den von deinem Gerät bereitgestellten Authentifizierungsmethoden wie FaceID, Windows Hello oder Fingerabdruck an. NotSupported: WebAuthN wird durch deinen Browser nicht unterstützt. Stelle sicher, dass du die aktuelle Version installiert hast oder nutze einen anderen (z.B. Chrome, Safari, Firefox) ErrorRetry: Versuche es erneut, erstelle eine neue Abfrage oder wähle einen andere Methode. LoginWithPwButtonText: Mit Passwort anmelden ValidateTokenButtonText: Passwortlos anmelden PasswordlessPrompt: - Title: Passwortloser Login hinzufügen + Title: Passwortlosen Login hinzufügen Description: Möchtest du einen passwortlosen Login hinzufügen? (Authentifizierungsmethoden deines Gerätes wie FaceID, Windows Hello oder Fingerprint) - DescriptionInit: Du musst zuerst den Passwortlosen Login hinzufügen. Nutze dazu den Link, den du erhalten hast um dein Gerät zu registrieren. - PasswordlessButtonText: Werde Passwortlos - NextButtonText: weiter - SkipButtonText: überspringen + DescriptionInit: Du musst zuerst den passwortlosen Login hinzufügen. Nutze dazu den Link, den du erhalten hast, um dein Gerät zu registrieren. + PasswordlessButtonText: Werde passwortlos + NextButtonText: Weiter + SkipButtonText: Überspringen PasswordlessRegistration: - Title: Passwortloser Login hinzufügen - Description: Füge dein Authentifizierung hinzu, indem du einen Namen eingibst (eg. MyPhone, MacBook, etc) und den 'Passwortlos registrieren' Button drückst. + Title: Passwortlosen Login hinzufügen + Description: Füge das Gerät hinzu, indem du einen Namen eingibst (eg. MyPhone, MacBook, etc) und den 'Passwortlos registrieren' Button drückst. TokenNameLabel: Name des Geräts NotSupported: WebAuthN wird durch deinen Browser nicht unterstützt. Stelle sicher, dass du die aktuelle Version installiert hast oder nutze einen anderen (z.B. Chrome, Safari, Firefox) RegisterTokenButtonText: Passwortlos registrieren @@ -182,54 +182,53 @@ PasswordlessRegistrationDone: Title: Passwortloser Login erstellt Description: Gerät für passwortlosen Login erfolgreich hinzugefügt. DescriptionClose: Du kannst das Fenster nun schliessen. - NextButtonText: weiter - CancelButtonText: abbrechen + NextButtonText: Weiter + CancelButtonText: Abbrechen PasswordChange: Title: Passwort ändern - Description: Ändere dein Passwort in dem du dein altes und dann dein neues Passwort eingibst. + Description: Ändere dein Passwort indem du dein altes und dann dein neues Passwort eingibst. OldPasswordLabel: Altes Passwort NewPasswordLabel: Neues Passwort - NewPasswordConfirmLabel: Passwort Bestätigung - CancelButtonText: abbrechen - NextButtonText: weiter - Footer: Fusszeile + NewPasswordConfirmLabel: Passwort wiederholen + CancelButtonText: Abbrechen + NextButtonText: Weiter PasswordChangeDone: Title: Passwort ändern Description: Das Passwort wurde erfolgreich geändert. - NextButtonText: weiter + NextButtonText: Weiter PasswordResetDone: Title: Resetlink versendet - Description: Prüfe dein E-Mail Postfach, um ein neues Passwort zu setzen. - NextButtonText: weiter + Description: Prüfe dein E-Mail-Postfach, um ein neues Passwort zu setzen. + NextButtonText: Weiter EmailVerification: - Title: E-Mail Verifizierung - Description: Du hast ein E-Mail zur Verifizierung deiner E-Mail Adresse bekommen. Gib den Code im untenstehenden Formular ein. Mit erneut versenden, wird dir ein neues E-Mail zugestellt. + Title: E-Mail-Verifizierung + Description: Du hast eine E-Mail zur Verifizierung deiner E-Mail-Adresse bekommen. Gib den Code im untenstehenden Formular ein. Mit erneut versenden, wird dir eine neue E-Mail zugestellt. CodeLabel: Code - NextButtonText: weiter + NextButtonText: Weiter ResendButtonText: Code erneut senden EmailVerificationDone: - Title: E-Mail Verifizierung - Description: Deine E-Mail Adresse wurde erfolgreich verifiziert. - NextButtonText: weiter - CancelButtonText: abbrechen - LoginButtonText: anmelden + Title: E-Mail-Verifizierung + Description: Deine E-Mail-Adresse wurde erfolgreich verifiziert. + NextButtonText: Weiter + CancelButtonText: Abbrechen + LoginButtonText: Anmelden RegisterOption: - Title: Registrations Möglichkeiten - Description: Wähle aus wie du dich registrieren möchtest. - RegisterUsernamePasswordButtonText: Mit Benutzername Passwort - ExternalLoginDescription: oder registriere dich mit einem externen Benutzer - LoginButtonText: login + Title: Registrationsmöglichkeiten + Description: Wähle aus, wie du dich registrieren möchtest. + RegisterUsernamePasswordButtonText: Mit Benutzername/Passwort + ExternalLoginDescription: oder registriere dich mit einem externen Benutzerkonto + LoginButtonText: Einloggen RegistrationUser: - Title: Registration - Description: Gib deine Benutzerangaben an. Die E-Mail Adresse wird als Benutzernamen verwendet. - DescriptionOrgRegister: Gib deine Benutzerangaben an. + Title: Registrierung + Description: Gib deine Benutzerdaten an. Die E-Mail-Adresse wird als Benutzername verwendet. + DescriptionOrgRegister: Gib deine Benutzerdaten an. EmailLabel: E-Mail UsernameLabel: Benutzername FirstnameLabel: Vorname @@ -249,21 +248,21 @@ RegistrationUser: GenderLabel: Geschlecht Female: weiblich Male: männlich - Diverse: diverse + Diverse: divers PasswordLabel: Passwort PasswordConfirmLabel: Passwort wiederholen TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz TosConfirm: Ich akzeptiere die - TosLinkText: AGBs + TosLinkText: AGB PrivacyConfirm: Ich akzeptiere die PrivacyLinkText: Datenschutzerklärung - ExternalLogin: oder registriere dich mit einem externen Benutzer - BackButtonText: login - NextButtonText: weiter + ExternalLogin: oder registriere dich mit einem externen Benutzerkonto + BackButtonText: Anmelden + NextButtonText: Weiter ExternalRegistrationUserOverview: - Title: Externer Benutzer Registration - Description: Deine Benutzerangaben werden vom ausgewählten Provider übernommen. Du kannst sie hier ändern und ergänzen, bevor dein Benutzer angelegt wird. + Title: Registrierung mit externem Benutzerkonto + Description: Deine Benutzerdaten werden vom ausgewählten Provider übernommen. Du kannst sie hier ändern und ergänzen, bevor dein Benutzerkonto angelegt wird. EmailLabel: E-Mail UsernameLabel: Benutzername FirstnameLabel: Vorname @@ -284,16 +283,16 @@ ExternalRegistrationUserOverview: Macedonian: Македонски TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz TosConfirm: Ich akzeptiere die - TosLinkText: AGBs + TosLinkText: AGB PrivacyConfirm: Ich akzeptiere die PrivacyLinkText: Datenschutzerklärung - ExternalLogin: oder registriere dich mit einem externen Benutzer - BackButtonText: zurück - NextButtonText: speichern + ExternalLogin: oder registriere dich mit einem externen Benutzerkonto + BackButtonText: Zurück + NextButtonText: Speichern RegistrationOrg: - Title: Organisations Registration - Description: Gib deinen Organisationsnamen und deine Benutzerangaben an. + Title: Organisation registrieren + Description: Gib deinen Organisationsnamen und deine Benutzerdaten an. OrgNameLabel: Organisationsname EmailLabel: E-Mail UsernameLabel: Benutzername @@ -303,36 +302,36 @@ RegistrationOrg: PasswordConfirmLabel: Passwort wiederholen TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz TosConfirm: Ich akzeptiere die - TosLinkText: AGBs + TosLinkText: AGB PrivacyConfirm: Ich akzeptiere die PrivacyLinkText: Datenschutzerklärung SaveButtonText: Organisation speichern LoginSuccess: - Title: Erfolgreich eingeloggt - AutoRedirectDescription: Du wirst automatisch zurück in die Applikation geleitet. Danach kannst du diese Fenster schliessen. - RedirectedDescription: Du kannst diese Fenster nun schliessen. - NextButtonText: weiter + Title: Erfolgreich angemeldet + AutoRedirectDescription: Du wirst automatisch zurück in die Anwendung geleitet. Danach kannst du dieses Fenster schließen. + RedirectedDescription: Du kannst dieses Fenster nun schließen. + NextButtonText: Weiter LogoutDone: - Title: Ausgeloggt - Description: Du wurdest erfolgreich ausgeloggt. - LoginButtonText: anmelden + Title: Abgemeldet + Description: Du wurdest erfolgreich abgemeldet. + LoginButtonText: Anmelden LinkingUsersDone: - Title: Benutzerlinking - Description: Benuzterlinking erledigt. - CancelButtonText: abbrechen - NextButtonText: weiter + Title: Benutzerkonto verknpüfen + Description: Benuzterkonto verknpüft. + CancelButtonText: Abbrechen + NextButtonText: Weiter ExternalNotFound: - Title: Externer Benutzer nicht gefunden - Description: Externer Benutzer konnte nicht gefunden werden. Willst du deinen Benutzer mit einem bestehenden verlinken oder diesen als neuen Benutzer registrieren. - LinkButtonText: Verlinken - AutoRegisterButtonText: registrieren + Title: Externes Benutzerkonto nicht gefunden + Description: Externes Benutzerkonto konnte nicht gefunden werden. Willst du deinen Benutzer mit einem bestehenden verknüpfen oder diesen als neuen Benutzer registrieren. + LinkButtonText: Verknüpfen + AutoRegisterButtonText: Registrieren TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz TosConfirm: Ich akzeptiere die - TosLinkText: AGBs + TosLinkText: AGB PrivacyConfirm: Ich akzeptiere die PrivacyLinkText: Datenschutzerklärung German: Deutsch @@ -348,22 +347,22 @@ ExternalNotFound: Macedonian: Македонски DeviceAuth: - Title: Geräteautorisierung + Title: Gerätezulassung UserCode: Label: Benutzercode - Description: Geben Sie den auf dem Gerät angezeigten Benutzercode ein - ButtonNext: weiter + Description: Gib den auf dem Gerät angezeigten Benutzercode ein + ButtonNext: Weiter Action: Description: Gerätezugriff erlauben - GrantDevice: Sie sind dabei, das Gerät zu erlauben + GrantDevice: Du bist dabei, das Gerät zu erlauben AccessToScopes: Zugriff auf die folgenden Daten Button: - Allow: erlauben - Deny: verweigern + Allow: Erlauben + Deny: Verweigern Done: Description: Abgeschlossen Approved: Gerätezulassung genehmigt. Sie können jetzt zum Gerät zurückkehren. - Denied: Geräteautorisierung verweigert. Sie können jetzt zum Gerät zurückkehren. + Denied: Gerätezulassung verweigert. Sie können jetzt zum Gerät zurückkehren. Footer: PoweredBy: Powered By @@ -389,11 +388,11 @@ Errors: Inactive: Benutzer ist inaktiv NotFoundOnOrg: Benutzer konnte in der gewünschten Organisation nicht gefunden werden NotAllowedOrg: Benutzer gehört nicht der benötigten Organisation an - NotMatchingUserID: User stimmt nicht mit User in Auth Request überein + NotMatchingUserID: Benutzer stimmt nicht mit Benutzer in Auth Request überein UserIDMissing: UserID ist leer Invalid: Userdaten sind ungültig DomainNotAllowedAsUsername: Domäne ist bereits reserviert und kann nicht verwendet werden - NotAllowedToLink: Der Benutzer darf nicht mit einem externen Login Provider verlinkt werden + NotAllowedToLink: Der Benutzer darf nicht mit einem externen Benutzerkonto verknüpft werden Profile: NotFound: Profil nicht gefunden NotChanged: Profil nicht verändert @@ -402,12 +401,12 @@ Errors: LastNameEmpty: Nachname im Profil ist leer IDMissing: Profil ID fehlt Email: - NotFound: Email nicht gefunden - Invalid: Email ist ungültig - AlreadyVerified: Email ist bereits verifiziert - NotChanged: Email wurde nicht geändert - Empty: Email ist leer - IDMissing: Email ID fehlt + NotFound: E-Mail-Adresse nicht gefunden + Invalid: E-Mail-Adresse ist ungültig + AlreadyVerified: E-Mail-Adresse ist bereits verifiziert + NotChanged: E-Mail-Adresse wurde nicht geändert + Empty: E-Mail-Adresse ist leer + IDMissing: E-Mail ID fehlt Phone: NotFound: Telefonnummer nicht gefunden Invalid: Telefonnummer ist ungültig @@ -422,19 +421,19 @@ Errors: Reserved: Benutzername ist bereits vergeben Empty: Benutzername ist leer Password: - ConfirmationWrong: Passwort Bestätigung stimmt nicht überein + ConfirmationWrong: Passwortwiederholung stimmt nicht überein Empty: Passwort ist leer Invalid: Passwort ungültig - InvalidAndLocked: Password ist ungültig und Benutzer wurde gesperrt, melden Sie sich bei ihrem Administrator. + InvalidAndLocked: Passwort ist ungültig und Benutzer wurde gesperrt, wende dich an einen Administrator. NotChanged: Passwort nicht geändert UsernameOrPassword: - Invalid: Username oder Passwort ist ungültig + Invalid: Benutzername oder Passwort ist ungültig PasswordComplexityPolicy: - NotFound: Passwort Policy konnte nicht gefunden werden + NotFound: Passwortpolicy konnte nicht gefunden werden MinLength: Passwort ist zu kurz - HasLower: Passwort beinhaltet keinen klein Buchstaben - HasUpper: Passwort beinhaltet keinen gross Buchstaben - HasNumber: Passwort beinhaltet keine Nummer + HasLower: Passwort beinhaltet keinen Kleinbuchstaben + HasUpper: Passwort beinhaltet keinen Großbuchstaben + HasNumber: Passwort beinhaltet keine Zahl HasSymbol: Passwort beinhaltet kein Symbol Code: Expired: Code ist abgelaufen @@ -442,7 +441,7 @@ Errors: Empty: Code ist leer CryptoCodeNil: Crypto Code ist nil NotFound: Code konnte nicht gefunden werden - GeneratorAlgNotSupported: Generator Algorithmus wird nicht unterstützt + GeneratorAlgNotSupported: Generator-Algorithmus wird nicht unterstützt EmailVerify: UserIDEmpty: UserID ist leer ExternalData: @@ -461,15 +460,15 @@ Errors: IDPTypeNotImplemented: IDP Typ ist nicht implementiert NotAllowed: Externer Login Provider ist nicht erlaubt IDPConfigIDEmpty: Identity Provider ID ist leer - ExternalUserIDEmpty: Externe User ID ist leer + ExternalUserIDEmpty: Externe User ID ist leer UserDisplayNameEmpty: Benutzer Anzeige Name ist leer NoExternalUserData: Keine externe User Daten erhalten - CreationNotAllowed: Erstellen eines neuen User ist auf diesem Provider nicht erlaubt - LinkingNotAllowed: Linken eines Users ist auf diesem Provider nicht erlaubt - GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator. - ProjectRequired: Der Login an diese Applikation ist nicht möglich. Die Organisation des Benutzer benötigt Berechtigung auf das Projekt. Bitte melde dich bei deinem Administrator. + CreationNotAllowed: Erstellen eines neuen Benutzers mit diesem Provider ist nicht erlaubt + LinkingNotAllowed: Verknüpfen eines Benutzers mit diesem Provider ist nicht erlaubt + GrantRequired: Die Anmeldung an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator. + ProjectRequired: Die Anmeldung an dieser Applikation ist nicht möglich. Die Organisation des Benutzer benötigt Berechtigung auf das Projekt. Bitte melde dich bei deinem Administrator. IdentityProvider: - InvalidConfig: Identitätsprovider Konfiguration ist ungültig + InvalidConfig: Konfiguration des Identitätsproviders ist ungültig IAM: LockoutPolicy: NotExisting: Lockout Policy existiert nicht diff --git a/internal/api/ui/login/static/i18n/en.yaml b/internal/api/ui/login/static/i18n/en.yaml index 8c5d2b773b..99958d7563 100644 --- a/internal/api/ui/login/static/i18n/en.yaml +++ b/internal/api/ui/login/static/i18n/en.yaml @@ -2,7 +2,7 @@ Login: Title: Welcome back! Description: Enter your login data. TitleLinking: Login for user linking - DescriptionLinking: Enter your login data to link your external user with a ZITADEL user. + DescriptionLinking: Enter your login data to link your external user. LoginNameLabel: Loginname UsernamePlaceHolder: username LoginnamePlaceHolder: username@domain @@ -20,12 +20,12 @@ LDAP: SelectAccount: Title: Select account - Description: Use your ZITADEL-Account + Description: Use your account TitleLinking: Select account for user linking DescriptionLinking: Select your account to link with your external user. OtherUser: Other User SessionState0: active - SessionState1: inactive + SessionState1: Signed out MustBeMemberOfOrg: The user must be member of the {{.OrgName}} organization. Password: diff --git a/internal/api/ui/login/static/i18n/es.yaml b/internal/api/ui/login/static/i18n/es.yaml index 0976e7a695..98847b67a8 100644 --- a/internal/api/ui/login/static/i18n/es.yaml +++ b/internal/api/ui/login/static/i18n/es.yaml @@ -2,7 +2,7 @@ Login: Title: ¡Hola de nuevo! Description: Introduce tus datos de inicio de sesión. TitleLinking: Inicio de sesión para vincular un usuario - DescriptionLinking: Introduce tus datos de inicio de sesión para vincular tu usuario externo con un usuario ZITADEL. + DescriptionLinking: Introduce tus datos de inicio de sesión para vincular tu usuario externo con un usuario. LoginNameLabel: Nombre de inicio de sesión UsernamePlaceHolder: username LoginnamePlaceHolder: username@dominio @@ -20,12 +20,12 @@ LDAP: SelectAccount: Title: Seleccionar cuenta - Description: Utiliza tu cuenta ZITADEL + Description: Utiliza tu cuenta TitleLinking: Selecciona tu cuenta para vincular el usuario DescriptionLinking: Selecciona tu cuenta para vincular con tu usuario externo. OtherUser: Otro Usuario SessionState0: activo - SessionState1: inactivo + SessionState1: Se ha cerrado la sesión MustBeMemberOfOrg: El usuario debe ser miembro de la organización {{.OrgName}}. Password: diff --git a/internal/api/ui/login/static/i18n/fr.yaml b/internal/api/ui/login/static/i18n/fr.yaml index b39bb2cf98..ebc87dfebe 100644 --- a/internal/api/ui/login/static/i18n/fr.yaml +++ b/internal/api/ui/login/static/i18n/fr.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: Sélectionnez votre compte pour établir un lien avec votre utilisateur externe. OtherUser: Autre utilisateur SessionState0: actif - SessionState1: inactif + SessionState1: Déconnecté MustBeMemberOfOrg: L'utilisateur doit être membre de l'organisation {{.OrgName}}. Password: diff --git a/internal/api/ui/login/static/i18n/it.yaml b/internal/api/ui/login/static/i18n/it.yaml index 9430a8ed30..1fffcee7fc 100644 --- a/internal/api/ui/login/static/i18n/it.yaml +++ b/internal/api/ui/login/static/i18n/it.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: Seleziona il tuo account da collegare al tuo utente esterno. OtherUser: Altro utente SessionState0: attivo - SessionState1: inattivo + SessionState1: Disconnesso MustBeMemberOfOrg: "L'utente deve essere membro dell'organizzazione {{.OrgName}}." Password: diff --git a/internal/api/ui/login/static/i18n/ja.yaml b/internal/api/ui/login/static/i18n/ja.yaml index 7693d50e1e..fe58a191f2 100644 --- a/internal/api/ui/login/static/i18n/ja.yaml +++ b/internal/api/ui/login/static/i18n/ja.yaml @@ -18,7 +18,7 @@ SelectAccount: DescriptionLinking: アカウントを選択して、外部ユーザーにリンクします。 OtherUser: その他のユーザー SessionState0: アクティブ - SessionState1: 非アクティブ + SessionState1: ログアウトしました MustBeMemberOfOrg: ユーザーは組織 {{.OrgName}} のメンバーである必要があります。 Password: diff --git a/internal/api/ui/login/static/i18n/mk.yaml b/internal/api/ui/login/static/i18n/mk.yaml index d0107dec6c..6db9dea24a 100644 --- a/internal/api/ui/login/static/i18n/mk.yaml +++ b/internal/api/ui/login/static/i18n/mk.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: Изберете ја вашата корисничка сметка за да ја поврзете со вашиот надворешен корисник. OtherUser: Друг корисник SessionState0: активна - SessionState1: неактивна + SessionState1: Одјавени MustBeMemberOfOrg: Корисникот мора да биде член на организацијата {{.OrgName}}. Password: diff --git a/internal/api/ui/login/static/i18n/pl.yaml b/internal/api/ui/login/static/i18n/pl.yaml index 963e0d038a..4cc7e222f6 100644 --- a/internal/api/ui/login/static/i18n/pl.yaml +++ b/internal/api/ui/login/static/i18n/pl.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: Wybierz swoje konto, aby połączyć je z twoim zewnętrznym użytkownikiem. OtherUser: Inny użytkownik SessionState0: aktywne - SessionState1: nieaktywne + SessionState1: Wylogowano MustBeMemberOfOrg: Użytkownik musi być członkiem organizacji {{.OrgName}}. Password: diff --git a/internal/api/ui/login/static/i18n/pt.yaml b/internal/api/ui/login/static/i18n/pt.yaml index 3b32b21785..9b50f7087c 100644 --- a/internal/api/ui/login/static/i18n/pt.yaml +++ b/internal/api/ui/login/static/i18n/pt.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: Selecione sua conta para vincular com seu usuário externo. OtherUser: Outro usuário SessionState0: ativo - SessionState1: inativo + SessionState1: Sem sessão iniciada MustBeMemberOfOrg: O usuário deve ser membro da organização {{.OrgName}}. Password: diff --git a/internal/api/ui/login/static/i18n/zh.yaml b/internal/api/ui/login/static/i18n/zh.yaml index 315eed8dc4..1b02b36705 100644 --- a/internal/api/ui/login/static/i18n/zh.yaml +++ b/internal/api/ui/login/static/i18n/zh.yaml @@ -25,7 +25,7 @@ SelectAccount: DescriptionLinking: 选择您的帐户以与您的外部用户关联。 OtherUser: 其他用户 SessionState0: 启用 - SessionState1: 停用 + SessionState1: 未登入 MustBeMemberOfOrg: 用户必须是 {{.OrgName}} 组织的成员。 Password: diff --git a/internal/api/ui/login/static/templates/change_password.html b/internal/api/ui/login/static/templates/change_password.html index 45eacb3ab1..506c107783 100644 --- a/internal/api/ui/login/static/templates/change_password.html +++ b/internal/api/ui/login/static/templates/change_password.html @@ -12,7 +12,7 @@ {{ .CSRF }} - +
    diff --git a/internal/api/ui/login/static/templates/init_user.html b/internal/api/ui/login/static/templates/init_user.html index cf0ad71049..9ffd4f7c93 100644 --- a/internal/api/ui/login/static/templates/init_user.html +++ b/internal/api/ui/login/static/templates/init_user.html @@ -16,7 +16,7 @@ - +
    diff --git a/internal/api/ui/login/static/templates/password.html b/internal/api/ui/login/static/templates/password.html index 15e9d7c09b..2204a25bb2 100644 --- a/internal/api/ui/login/static/templates/password.html +++ b/internal/api/ui/login/static/templates/password.html @@ -12,7 +12,7 @@ {{ .CSRF }} - +
    diff --git a/internal/api/ui/login/static/templates/select_user.html b/internal/api/ui/login/static/templates/select_user.html index a656d0d87d..5a0e1fe090 100644 --- a/internal/api/ui/login/static/templates/select_user.html +++ b/internal/api/ui/login/static/templates/select_user.html @@ -42,7 +42,9 @@

    {{$user.DisplayName}}

    {{if and $displayLoginNameSuffix $user.SelectionPossible}}{{$user.UserName}}{{else}}{{$user.LoginName}}{{end}}

    + {{if $user.UserSessionState }}

    {{t $sessionState}}

    + {{end}}
    diff --git a/internal/command/org_test.go b/internal/command/org_test.go index e67ba69dc8..8696b3fb26 100644 --- a/internal/command/org_test.go +++ b/internal/command/org_test.go @@ -1088,34 +1088,6 @@ func TestCommandSide_RemoveOrg(t *testing.T) { err: errors.IsNotFound, }, }, - { - name: "org already removed, error", - fields: fields{ - eventstore: eventstoreExpect( - t, - expectFilter(), // zitadel project check - expectFilter( - eventFromEventPusher( - org.NewOrgAddedEvent(context.Background(), - &org.NewAggregate("org1").Aggregate, - "org"), - ), - eventFromEventPusher( - org.NewOrgRemovedEvent(context.Background(), - &org.NewAggregate("org1").Aggregate, - "org", []string{}, false, []string{}, []*domain.UserIDPLink{}, []string{}), - ), - ), - ), - }, - args: args{ - ctx: context.Background(), - orgID: "org1", - }, - res: res{ - err: errors.IsNotFound, - }, - }, { name: "push failed, error", fields: fields{ diff --git a/internal/database/postgres/config.go b/internal/database/postgres/config.go index 5521891685..bacd099484 100644 --- a/internal/database/postgres/config.go +++ b/internal/database/postgres/config.go @@ -8,6 +8,7 @@ import ( "github.com/mitchellh/mapstructure" "github.com/zitadel/logging" + "github.com/zitadel/zitadel/internal/database/dialect" ) @@ -62,7 +63,6 @@ func (c *Config) Decode(configs []interface{}) (dialect.Connector, error) { } func (c *Config) Connect(useAdmin bool) (*sql.DB, error) { - logging.Warn("postgres is currently in beta") db, err := sql.Open("pgx", c.String(useAdmin)) if err != nil { return nil, err diff --git a/internal/integration/assert.go b/internal/integration/assert.go index e5105d8d23..5c19eea986 100644 --- a/internal/integration/assert.go +++ b/internal/integration/assert.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" ) type DetailsMsg interface { diff --git a/internal/integration/assert_test.go b/internal/integration/assert_test.go index 49a6949007..31855e1e51 100644 --- a/internal/integration/assert_test.go +++ b/internal/integration/assert_test.go @@ -5,7 +5,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" ) type myMsg struct { diff --git a/internal/integration/client.go b/internal/integration/client.go index ab18c64524..4e82ea5442 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -21,12 +21,12 @@ import ( "github.com/zitadel/zitadel/pkg/grpc/admin" "github.com/zitadel/zitadel/pkg/grpc/auth" mgmt "github.com/zitadel/zitadel/pkg/grpc/management" - object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" - oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" + object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" + oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" organisation "github.com/zitadel/zitadel/pkg/grpc/org/v2beta" - session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" + session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" "github.com/zitadel/zitadel/pkg/grpc/system" - user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" + user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" ) type Client struct { diff --git a/internal/notification/static/i18n/de.yaml b/internal/notification/static/i18n/de.yaml index bf3fe133cb..676534229c 100644 --- a/internal/notification/static/i18n/de.yaml +++ b/internal/notification/static/i18n/de.yaml @@ -6,56 +6,56 @@ InitCode: Text: Dieser Benutzer wurde soeben in ZITADEL erstellt. Mit dem Benutzernamen <br><strong>{{.PreferredLoginName}}</strong><br> kannst du dich anmelden. Nutze den untenstehenden Button, um die Initialisierung abzuschliessen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du dieses Mail nicht angefordert hast, kannst du es einfach ignorieren. ButtonText: Initialisierung abschliessen PasswordReset: - Title: ZITADEL - Passwort zurücksetzen + Title: Passwort zurücksetzen PreHeader: Passwort zurücksetzen Subject: Passwort zurücksetzen Greeting: Hallo {{.DisplayName}}, - Text: Wir haben eine Anfrage für das Zurücksetzen deines Passwortes bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du dieses Mail nicht angefordert hast, kannst du es ignorieren. + Text: Wir haben eine Anfrage für das Zurücksetzen deines Passworts bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du das Zurücksetzen des Passworts nicht angefordert hast, kannst du diese E-Mail ignorieren. ButtonText: Passwort zurücksetzen VerifyEmail: - Title: ZITADEL - Email verifizieren - PreHeader: Email verifizieren - Subject: Email verifizieren + Title: E-Mail-Adresse verifizieren + PreHeader: E-Mail-Adresse verifizieren + Subject: E-Mail-Adresse verifizieren Greeting: Hallo {{.DisplayName}}, - Text: Eine neue E-Mail Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button um diese zu verifizieren <br>(Code <strong>{{.Code}}</strong>).<br> Falls du deine E-Mail Adresse nicht selber hinzugefügt hast, kannst du dieses E-Mail ignorieren. - ButtonText: Email verifizieren + Text: Eine neue E-Mail-Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button, um diese zu verifizieren <br>(Code <strong>{{.Code}}</strong>).<br> Falls du die E-Mail-Adresse nicht selber hinzugefügt hast, kannst du diese E-Mail ignorieren. + ButtonText: E-Mail-Adresse verifizieren VerifyPhone: - Title: ZITADEL - Telefonnummer verifizieren + Title: Telefonnummer verifizieren PreHeader: Telefonnummer verifizieren Subject: Telefonnummer verifizieren Greeting: Hallo {{.DisplayName}}, - Text: Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese in dem du folgenden Code eingibst<br>(Code <strong>{{.Code}}</strong>).<br> - ButtonText: Telefon verifizieren + Text: Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese, indem du folgenden Code eingibst<br>(Code <strong>{{.Code}}</strong>).<br> + ButtonText: Telefonnummer verifizieren VerifyEmailOTP: - Title: ZITADEL - Einmalpasswort verifizieren + Title: Einmalpasswort verifizieren PreHeader: Einmalpasswort verifizieren Subject: Einmalpasswort verifizieren Greeting: Hallo {{.DisplayName}}, - Text: Bitte nutze den 'Authentifizieren'-Button oder kopiere das Einmalpasswort {{.OTP}} und füge es in den Authentifizierungsbildschirm ein, um dich innerhalb der nächsten fünf Minuten bei ZITADEL zu authentifizieren. + Text: Bitte nutze den 'Authentifizieren'-Button oder kopiere das Einmalpasswort {{.OTP}} und füge es in den Authentifizierungsbildschirm ein, um dich innerhalb der nächsten fünf Minuten zu authentifizieren. ButtonText: Authentifizieren VerifySMSOTP: Text: >- - {{.OTP}} ist Ihr Einmalpasswort für {{ .Domain }}. Verwenden Sie es innerhalb der nächsten {{.Expiry}}. + {{.OTP}} ist dein Einmalpasswort für {{ .Domain }}. Verwende es innerhalb der nächsten {{.Expiry}}. @{{.Domain}} #{{.OTP}} DomainClaimed: - Title: ZITADEL - Domain wurde beansprucht - PreHeader: Email / Username ändern + Title: Domain wurde beansprucht + PreHeader: E-Mail / Benutzername ändern Subject: Domain wurde beansprucht Greeting: Hallo {{.DisplayName}}, - Text: Die Domain {{.Domain}} wurde von einer Organisation beansprucht. Dein derzeitiger User {{.Username}} ist nicht Teil dieser Organisation. Daher musst du beim nächsten Login eine neue Email hinterlegen. Für diesen Login haben wir dir einen temporären Usernamen ({{.TempUsername}}) erstellt. + Text: Die Domain {{.Domain}} wurde von einer Organisation beansprucht. Dein derzeitiger User {{.Username}} ist nicht Teil dieser Organisation. Daher musst du beim nächsten Login eine neue E-Mail-Adresse hinterlegen. Für diesen Login haben wir dir einen temporären Usernamen ({{.TempUsername}}) erstellt. ButtonText: Login PasswordlessRegistration: - Title: ZITADEL - Passwortlosen Login hinzufügen + Title: Passwortlosen Login hinzufügen PreHeader: Passwortlosen Login hinzufügen Subject: Passwortlosen Login hinzufügen Greeting: Hallo {{.DisplayName}}, Text: Wir haben eine Anfrage für das Hinzufügen eines Token für den passwortlosen Login erhalten. Du kannst den untenstehenden Button verwenden, um dein Token oder Gerät hinzuzufügen. ButtonText: Passwortlosen Login hinzufügen PasswordChange: - Title: ZITADEL - Passwort von Benutzer wurde geändert - PreHeader: Passwort Änderung - Subject: Passwort von Benutzer wurde geändert + Title: Passwort wurde geändert + PreHeader: Passwortänderung + Subject: Passwort wurde geändert Greeting: Hallo {{.DisplayName}}, - Text: Das Password vom Benutzer wurde geändert, wenn diese Änderung von jemand anderem gemacht wurde, empfehlen wir die sofortige Zurücksetzung ihres Passworts. + Text: Dein Passwort wurde geändert. Wenn diese Änderung nicht von dir gemacht wurde, empfehlen wir das sofortige Zurücksetzen deines Passworts. ButtonText: Login diff --git a/internal/notification/static/i18n/en.yaml b/internal/notification/static/i18n/en.yaml index c6257188e0..20e187aa0b 100644 --- a/internal/notification/static/i18n/en.yaml +++ b/internal/notification/static/i18n/en.yaml @@ -1,37 +1,37 @@ InitCode: - Title: ZITADEL - Initialize User + Title: Initialize User PreHeader: Initialize User Subject: Initialize User Greeting: Hello {{.DisplayName}}, - Text: This user was created in ZITADEL. Use the username {{.PreferredLoginName}} to login. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. + Text: This user was created. Use the username {{.PreferredLoginName}} to login. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. ButtonText: Finish initialization PasswordReset: - Title: ZITADEL - Reset password + Title: Reset password PreHeader: Reset password Subject: Reset password Greeting: Hello {{.DisplayName}}, Text: We received a password reset request. Please use the button below to reset your password. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. ButtonText: Reset password VerifyEmail: - Title: ZITADEL - Verify email + Title: Verify email PreHeader: Verify email Subject: Verify email Greeting: Hello {{.DisplayName}}, - Text: A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you didn't add a new email, please ignore this email. + Text: A new email has been added. Please use the button below to verify your email. (Code {{.Code}}) If you didn't add a new email, please ignore this email. ButtonText: Verify email VerifyPhone: - Title: ZITADEL - Verify phone + Title: Verify phone PreHeader: Verify phone Subject: Verify phone Greeting: Hello {{.DisplayName}}, Text: A new phone number has been added. Please use the following code to verify it {{.Code}} ButtonText: Verify phone VerifyEmailOTP: - Title: ZITADEL - Verify One-Time Password + Title: Verify One-Time Password PreHeader: Verify One-Time Password Subject: Verify One-Time Password Greeting: Hello {{.DisplayName}}, - Text: Please use the one-time password {{.OTP}} to authenticate at ZITADEL within the next five minutes or click the "Authenticate" button. + Text: Please use the one-time password {{.OTP}} to authenticate within the next five minutes or click the "Authenticate" button. ButtonText: Authenticate VerifySMSOTP: Text: >- @@ -39,23 +39,23 @@ VerifySMSOTP: @{{.Domain}} #{{.OTP}} DomainClaimed: - Title: ZITADEL - Domain has been claimed + Title: Domain has been claimed PreHeader: Change email / username Subject: Domain has been claimed Greeting: Hello {{.DisplayName}}, Text: The domain {{.Domain}} has been claimed by an organization. Your current user {{.Username}} is not part of this organization. Therefore you'll have to change your email when you login. We have created a temporary username ({{.TempUsername}}) for this login. ButtonText: Login PasswordlessRegistration: - Title: ZITADEL - Add Passwordless Login + Title: Add Passwordless Login PreHeader: Add Passwordless Login Subject: Add Passwordless Login Greeting: Hello {{.DisplayName}}, Text: We received a request to add a token for passwordless login. Please use the button below to add your token or device for passwordless login. ButtonText: Add Passwordless Login PasswordChange: - Title: ZITADEL - Password of user has changed + Title: Password of user has changed PreHeader: Change password Subject: Password of user has changed Greeting: Hello {{.DisplayName}}, - Text: The password of your user has changed, if this change was not done by you, please be advised to immediately reset your password. + Text: The password of your user has changed. If this change was not done by you, please be advised to immediately reset your password. ButtonText: Login diff --git a/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl b/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl index 4b321b3b37..bc0123c750 100644 --- a/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl +++ b/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl @@ -4,7 +4,7 @@ package {{.GoPackageName}} import ( "github.com/zitadel/zitadel/internal/api/authz" - {{if .AuthContext}}"github.com/zitadel/zitadel/pkg/grpc/object/v2alpha"{{end}} + {{if .AuthContext}}"github.com/zitadel/zitadel/internal/api/grpc/server/middleware"{{end}} ) var {{.ServiceName}}_AuthMethods = authz.MethodMapping { @@ -17,8 +17,11 @@ var {{.ServiceName}}_AuthMethods = authz.MethodMapping { } {{ range $m := .AuthContext}} -func (r *{{ $m.Name }}) OrganisationFromRequest() *object.Organisation { - return r{{$m.OrgMethod}} +func (r *{{ $m.Name }}) OrganisationFromRequest() *middleware.Organisation { + return &middleware.Organisation{ + ID: r{{$m.OrgMethod}}.GetOrgId(), + Domain: r{{$m.OrgMethod}}.GetOrgDomain(), + } } {{ end }} diff --git a/internal/query/org.go b/internal/query/org.go index 6ba4b54dc6..e99878f63e 100644 --- a/internal/query/org.go +++ b/internal/query/org.go @@ -214,8 +214,10 @@ func (q *Queries) SearchOrgs(ctx context.Context, queries *OrgSearchQueries) (or query, scan := prepareOrgsQuery(ctx, q.client) stmt, args, err := queries.toQuery(query). - Where(sq.Eq{ - OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(), + Where(sq.And{ + sq.Eq{ + OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(), + }, }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-wQ3by", "Errors.Query.InvalidRequest") diff --git a/internal/query/org_test.go b/internal/query/org_test.go index c4c2c21ad5..55e9546297 100644 --- a/internal/query/org_test.go +++ b/internal/query/org_test.go @@ -17,19 +17,19 @@ import ( ) var ( - orgUniqueQuery = "SELECT COUNT(*) = 0 FROM projections.orgs LEFT JOIN projections.org_domains2 ON projections.orgs.id = projections.org_domains2.org_id AND projections.orgs.instance_id = projections.org_domains2.instance_id AS OF SYSTEM TIME '-1 ms' WHERE (projections.org_domains2.is_verified = $1 AND projections.orgs.instance_id = $2 AND (projections.org_domains2.domain ILIKE $3 OR projections.orgs.name ILIKE $4) AND projections.orgs.org_state <> $5)" + orgUniqueQuery = "SELECT COUNT(*) = 0 FROM projections.orgs1 LEFT JOIN projections.org_domains2 ON projections.orgs1.id = projections.org_domains2.org_id AND projections.orgs1.instance_id = projections.org_domains2.instance_id AS OF SYSTEM TIME '-1 ms' WHERE (projections.org_domains2.is_verified = $1 AND projections.orgs1.instance_id = $2 AND (projections.org_domains2.domain ILIKE $3 OR projections.orgs1.name ILIKE $4) AND projections.orgs1.org_state <> $5)" orgUniqueCols = []string{"is_unique"} - prepareOrgsQueryStmt = `SELECT projections.orgs.id,` + - ` projections.orgs.creation_date,` + - ` projections.orgs.change_date,` + - ` projections.orgs.resource_owner,` + - ` projections.orgs.org_state,` + - ` projections.orgs.sequence,` + - ` projections.orgs.name,` + - ` projections.orgs.primary_domain,` + + prepareOrgsQueryStmt = `SELECT projections.orgs1.id,` + + ` projections.orgs1.creation_date,` + + ` projections.orgs1.change_date,` + + ` projections.orgs1.resource_owner,` + + ` projections.orgs1.org_state,` + + ` projections.orgs1.sequence,` + + ` projections.orgs1.name,` + + ` projections.orgs1.primary_domain,` + ` COUNT(*) OVER ()` + - ` FROM projections.orgs` + + ` FROM projections.orgs1` + ` AS OF SYSTEM TIME '-1 ms' ` prepareOrgsQueryCols = []string{ "id", @@ -43,15 +43,15 @@ var ( "count", } - prepareOrgQueryStmt = `SELECT projections.orgs.id,` + - ` projections.orgs.creation_date,` + - ` projections.orgs.change_date,` + - ` projections.orgs.resource_owner,` + - ` projections.orgs.org_state,` + - ` projections.orgs.sequence,` + - ` projections.orgs.name,` + - ` projections.orgs.primary_domain` + - ` FROM projections.orgs` + + prepareOrgQueryStmt = `SELECT projections.orgs1.id,` + + ` projections.orgs1.creation_date,` + + ` projections.orgs1.change_date,` + + ` projections.orgs1.resource_owner,` + + ` projections.orgs1.org_state,` + + ` projections.orgs1.sequence,` + + ` projections.orgs1.name,` + + ` projections.orgs1.primary_domain` + + ` FROM projections.orgs1` + ` AS OF SYSTEM TIME '-1 ms' ` prepareOrgQueryCols = []string{ "id", @@ -65,8 +65,8 @@ var ( } prepareOrgUniqueStmt = `SELECT COUNT(*) = 0` + - ` FROM projections.orgs` + - ` LEFT JOIN projections.org_domains2 ON projections.orgs.id = projections.org_domains2.org_id AND projections.orgs.instance_id = projections.org_domains2.instance_id` + + ` FROM projections.orgs1` + + ` LEFT JOIN projections.org_domains2 ON projections.orgs1.id = projections.org_domains2.org_id AND projections.orgs1.instance_id = projections.org_domains2.instance_id` + ` AS OF SYSTEM TIME '-1 ms' ` prepareOrgUniqueCols = []string{ "count", diff --git a/internal/query/project_grant_test.go b/internal/query/project_grant_test.go index b504cf1fb4..fbb3432b6a 100644 --- a/internal/query/project_grant_test.go +++ b/internal/query/project_grant_test.go @@ -29,8 +29,8 @@ var ( ` COUNT(*) OVER () ` + ` FROM projections.project_grants3 ` + ` LEFT JOIN projections.projects3 ON projections.project_grants3.project_id = projections.projects3.id AND projections.project_grants3.instance_id = projections.projects3.instance_id ` + - ` LEFT JOIN projections.orgs AS r ON projections.project_grants3.resource_owner = r.id AND projections.project_grants3.instance_id = r.instance_id` + - ` LEFT JOIN projections.orgs AS o ON projections.project_grants3.granted_org_id = o.id AND projections.project_grants3.instance_id = o.instance_id` + + ` LEFT JOIN projections.orgs1 AS r ON projections.project_grants3.resource_owner = r.id AND projections.project_grants3.instance_id = r.instance_id` + + ` LEFT JOIN projections.orgs1 AS o ON projections.project_grants3.granted_org_id = o.id AND projections.project_grants3.instance_id = o.instance_id` + ` AS OF SYSTEM TIME '-1 ms'` projectGrantsCols = []string{ "project_id", @@ -61,8 +61,8 @@ var ( ` r.name` + ` FROM projections.project_grants3 ` + ` LEFT JOIN projections.projects3 ON projections.project_grants3.project_id = projections.projects3.id AND projections.project_grants3.instance_id = projections.projects3.instance_id ` + - ` LEFT JOIN projections.orgs AS r ON projections.project_grants3.resource_owner = r.id AND projections.project_grants3.instance_id = r.instance_id` + - ` LEFT JOIN projections.orgs AS o ON projections.project_grants3.granted_org_id = o.id AND projections.project_grants3.instance_id = o.instance_id` + + ` LEFT JOIN projections.orgs1 AS r ON projections.project_grants3.resource_owner = r.id AND projections.project_grants3.instance_id = r.instance_id` + + ` LEFT JOIN projections.orgs1 AS o ON projections.project_grants3.granted_org_id = o.id AND projections.project_grants3.instance_id = o.instance_id` + ` AS OF SYSTEM TIME '-1 ms'` projectGrantCols = []string{ "project_id", diff --git a/internal/query/projection/action.go b/internal/query/projection/action.go index a687bad50f..780aee2d90 100644 --- a/internal/query/projection/action.go +++ b/internal/query/projection/action.go @@ -220,13 +220,8 @@ func (p *actionProjection) reduceOwnerRemoved(event eventstore.Event) (*handler. if !ok { return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-mSmWM", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(ActionChangeDateCol, e.CreationDate()), - handler.NewCol(ActionSequenceCol, e.Sequence()), - handler.NewCol(ActionOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(ActionInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(ActionResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/action_test.go b/internal/query/projection/action_test.go index b93875b4bb..2c235281ea 100644 --- a/internal/query/projection/action_test.go +++ b/internal/query/projection/action_test.go @@ -195,11 +195,8 @@ func TestActionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.actions3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.actions3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/app.go b/internal/query/projection/app.go index 483764d5d5..8ac53c10ba 100644 --- a/internal/query/projection/app.go +++ b/internal/query/projection/app.go @@ -598,13 +598,8 @@ func (p *appProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Sta return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Hyd1f", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(AppColumnChangeDate, e.CreationDate()), - handler.NewCol(AppColumnSequence, e.Sequence()), - handler.NewCol(AppColumnOwnerRemoved, true), - }, []handler.Condition{ handler.NewCond(AppColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(AppColumnResourceOwner, e.Aggregate().ID), diff --git a/internal/query/projection/app_test.go b/internal/query/projection/app_test.go index c605ed6dc4..fe63c29919 100644 --- a/internal/query/projection/app_test.go +++ b/internal/query/projection/app_test.go @@ -629,11 +629,8 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.apps5 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/authn_key.go b/internal/query/projection/authn_key.go index 8288756612..789fb7edf9 100644 --- a/internal/query/projection/authn_key.go +++ b/internal/query/projection/authn_key.go @@ -256,13 +256,8 @@ func (p *authNKeyProjection) reduceOwnerRemoved(event eventstore.Event) (*handle return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Hyd1f", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(AuthNKeyChangeDateCol, e.CreationDate()), - handler.NewCol(AuthNKeySequenceCol, e.Sequence()), - handler.NewCol(AuthNKeyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(AuthNKeyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(AuthNKeyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/authn_key_test.go b/internal/query/projection/authn_key_test.go index f75b2590bb..c1341fb647 100644 --- a/internal/query/projection/authn_key_test.go +++ b/internal/query/projection/authn_key_test.go @@ -488,11 +488,8 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.authn_keys2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/custom_text.go b/internal/query/projection/custom_text.go index 56e21e2b3f..b2e3650c46 100644 --- a/internal/query/projection/custom_text.go +++ b/internal/query/projection/custom_text.go @@ -188,13 +188,8 @@ func (p *customTextProjection) reduceOwnerRemoved(event eventstore.Event) (*hand return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-V2T3z", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(CustomTextChangeDateCol, e.CreationDate()), - handler.NewCol(CustomTextSequenceCol, e.Sequence()), - handler.NewCol(CustomTextOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(CustomTextInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(CustomTextAggregateIDCol, e.Aggregate().ID), diff --git a/internal/query/projection/custom_text_test.go b/internal/query/projection/custom_text_test.go index faee39dd41..f6889cf40e 100644 --- a/internal/query/projection/custom_text_test.go +++ b/internal/query/projection/custom_text_test.go @@ -278,11 +278,8 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.custom_texts2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)", + expectedStmt: "DELETE FROM projections.custom_texts2 WHERE (instance_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/domain_policy.go b/internal/query/projection/domain_policy.go index dc192c58f5..97896edb98 100644 --- a/internal/query/projection/domain_policy.go +++ b/internal/query/projection/domain_policy.go @@ -185,13 +185,8 @@ func (p *domainPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*ha return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-JYD2K", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(DomainPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(DomainPolicySequenceCol, e.Sequence()), - handler.NewCol(DomainPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(DomainPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(DomainPolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/domain_policy_test.go b/internal/query/projection/domain_policy_test.go index 4823ff0f4b..7aa64999e6 100644 --- a/internal/query/projection/domain_policy_test.go +++ b/internal/query/projection/domain_policy_test.go @@ -244,11 +244,8 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.domain_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.domain_policies2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/flow.go b/internal/query/projection/flow.go index 4b03d74515..62c6cb1584 100644 --- a/internal/query/projection/flow.go +++ b/internal/query/projection/flow.go @@ -135,13 +135,8 @@ func (p *flowProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.St return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Yd7WC", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(FlowChangeDateCol, e.CreationDate()), - handler.NewCol(FlowSequenceCol, e.Sequence()), - handler.NewCol(FlowOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(FlowInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(FlowResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/flow_test.go b/internal/query/projection/flow_test.go index 3ebfb8de75..49b1b8d497 100644 --- a/internal/query/projection/flow_test.go +++ b/internal/query/projection/flow_test.go @@ -122,11 +122,8 @@ func TestFlowProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.flow_triggers2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.flow_triggers2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/idp.go b/internal/query/projection/idp.go index 94c1c9798b..a355c7adc1 100644 --- a/internal/query/projection/idp.go +++ b/internal/query/projection/idp.go @@ -554,13 +554,8 @@ func (p *idpProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Sta return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-YsbQC", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(IDPChangeDateCol, e.CreationDate()), - handler.NewCol(IDPSequenceCol, e.Sequence()), - handler.NewCol(IDPOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(IDPInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(IDPResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/idp_login_policy_link.go b/internal/query/projection/idp_login_policy_link.go index 62118106d8..34df691a46 100644 --- a/internal/query/projection/idp_login_policy_link.go +++ b/internal/query/projection/idp_login_policy_link.go @@ -259,13 +259,8 @@ func (p *idpLoginPolicyLinkProjection) reduceOwnerRemoved(event eventstore.Event return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-YbhOv", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(IDPLoginPolicyLinkChangeDateCol, e.CreationDate()), - handler.NewCol(IDPLoginPolicyLinkSequenceCol, e.Sequence()), - handler.NewCol(IDPLoginPolicyLinkOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(IDPLoginPolicyLinkInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(IDPLoginPolicyLinkResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/idp_login_policy_link_test.go b/internal/query/projection/idp_login_policy_link_test.go index f3d02c4730..569f3746bf 100644 --- a/internal/query/projection/idp_login_policy_link_test.go +++ b/internal/query/projection/idp_login_policy_link_test.go @@ -406,11 +406,8 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.idp_login_policy_links5 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links5 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/idp_template.go b/internal/query/projection/idp_template.go index 98da2db463..9dc9ff6073 100644 --- a/internal/query/projection/idp_template.go +++ b/internal/query/projection/idp_template.go @@ -2034,13 +2034,8 @@ func (p *idpTemplateProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Jp0D2K", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(IDPTemplateChangeDateCol, e.CreationDate()), - handler.NewCol(IDPTemplateSequenceCol, e.Sequence()), - handler.NewCol(IDPTemplateOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(IDPTemplateInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(IDPTemplateResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/idp_template_test.go b/internal/query/projection/idp_template_test.go index fe5c255ea1..fd4eedf880 100644 --- a/internal/query/projection/idp_template_test.go +++ b/internal/query/projection/idp_template_test.go @@ -77,11 +77,8 @@ func TestIDPTemplateProjection_reducesRemove(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.idp_templates5 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.idp_templates5 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, @@ -2411,11 +2408,8 @@ func TestIDPTemplateProjection_reducesLDAP(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.idp_templates5 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.idp_templates5 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/idp_test.go b/internal/query/projection/idp_test.go index 10bbe76164..54eda3b848 100644 --- a/internal/query/projection/idp_test.go +++ b/internal/query/projection/idp_test.go @@ -906,11 +906,8 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.idps3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/idp_user_link.go b/internal/query/projection/idp_user_link.go index ed47ff1de5..c4b15a36d7 100644 --- a/internal/query/projection/idp_user_link.go +++ b/internal/query/projection/idp_user_link.go @@ -171,13 +171,8 @@ func (p *idpUserLinkProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-PGiAY", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(IDPUserLinkChangeDateCol, e.CreationDate()), - handler.NewCol(IDPUserLinkSequenceCol, e.Sequence()), - handler.NewCol(IDPUserLinkOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(IDPUserLinkResourceOwnerCol, e.Aggregate().ID), handler.NewCond(IDPUserLinkInstanceIDCol, e.Aggregate().InstanceID), diff --git a/internal/query/projection/idp_user_link_test.go b/internal/query/projection/idp_user_link_test.go index a343fe0b63..f518163e26 100644 --- a/internal/query/projection/idp_user_link_test.go +++ b/internal/query/projection/idp_user_link_test.go @@ -141,11 +141,8 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.idp_user_links3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (resource_owner = $4) AND (instance_id = $5)", + expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (resource_owner = $1) AND (instance_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "agg-id", "instance-id", }, diff --git a/internal/query/projection/instance_member_test.go b/internal/query/projection/instance_member_test.go index 5f56c64fe2..33c277f6c4 100644 --- a/internal/query/projection/instance_member_test.go +++ b/internal/query/projection/instance_member_test.go @@ -215,11 +215,8 @@ func TestInstanceMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.instance_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)", + expectedStmt: "DELETE FROM projections.instance_members3 WHERE (instance_id = $1) AND (user_resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/label_policy.go b/internal/query/projection/label_policy.go index e62c39b4c5..fb3cd221af 100644 --- a/internal/query/projection/label_policy.go +++ b/internal/query/projection/label_policy.go @@ -607,13 +607,8 @@ func (p *labelPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Su6pX", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(LabelPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(LabelPolicySequenceCol, e.Sequence()), - handler.NewCol(LabelPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(LabelPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(LabelPolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/label_policy_test.go b/internal/query/projection/label_policy_test.go index 88a82ea0cd..c046bb01dd 100644 --- a/internal/query/projection/label_policy_test.go +++ b/internal/query/projection/label_policy_test.go @@ -1007,11 +1007,8 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.label_policies2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/lockout_policy.go b/internal/query/projection/lockout_policy.go index 025213381f..1a6f9f7a77 100644 --- a/internal/query/projection/lockout_policy.go +++ b/internal/query/projection/lockout_policy.go @@ -179,13 +179,8 @@ func (p *lockoutPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*h return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-IoW0x", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(LockoutPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(LockoutPolicySequenceCol, e.Sequence()), - handler.NewCol(LockoutPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(LockoutPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(LockoutPolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/lockout_policy_test.go b/internal/query/projection/lockout_policy_test.go index 1b853dfc6b..338f3a92a5 100644 --- a/internal/query/projection/lockout_policy_test.go +++ b/internal/query/projection/lockout_policy_test.go @@ -236,11 +236,8 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.lockout_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.lockout_policies2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/login_name.go b/internal/query/projection/login_name.go index 12aaeb2af8..2d21bdaff8 100644 --- a/internal/query/projection/login_name.go +++ b/internal/query/projection/login_name.go @@ -574,30 +574,21 @@ func (p *loginNameProjection) reduceOwnerRemoved(event eventstore.Event) (*handl return crdb.NewMultiStatement( event, - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(LoginNameDomainOwnerRemovedCol, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(LoginNameDomainInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(LoginNameDomainResourceOwnerCol, e.Aggregate().ID), }, crdb.WithTableSuffix(loginNameDomainSuffix), ), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(LoginNamePoliciesOwnerRemovedCol, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(LoginNamePoliciesInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(LoginNamePoliciesResourceOwnerCol, e.Aggregate().ID), }, crdb.WithTableSuffix(loginNamePolicySuffix), ), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(LoginNameUserOwnerRemovedCol, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(LoginNameUserInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(LoginNameUserResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/login_name_test.go b/internal/query/projection/login_name_test.go index 3364fcb1d7..92f1b583de 100644 --- a/internal/query/projection/login_name_test.go +++ b/internal/query/projection/login_name_test.go @@ -544,25 +544,22 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_names2_domains SET owner_removed = $1 WHERE (instance_id = $2) AND (resource_owner = $3)", + expectedStmt: "DELETE FROM projections.login_names2_domains WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.login_names2_policies SET owner_removed = $1 WHERE (instance_id = $2) AND (resource_owner = $3)", + expectedStmt: "DELETE FROM projections.login_names2_policies WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.login_names2_users SET owner_removed = $1 WHERE (instance_id = $2) AND (resource_owner = $3)", + expectedStmt: "DELETE FROM projections.login_names2_users WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/login_policy.go b/internal/query/projection/login_policy.go index 856d02a464..f05dce5260 100644 --- a/internal/query/projection/login_policy.go +++ b/internal/query/projection/login_policy.go @@ -401,13 +401,8 @@ func (p *loginPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-B8NZW", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(LoginPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(LoginPolicySequenceCol, e.Sequence()), - handler.NewCol(LoginPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(LoginPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(LoginPolicyIDCol, e.Aggregate().ID), diff --git a/internal/query/projection/login_policy_test.go b/internal/query/projection/login_policy_test.go index b475fa2a28..62df313b71 100644 --- a/internal/query/projection/login_policy_test.go +++ b/internal/query/projection/login_policy_test.go @@ -702,11 +702,8 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_policies5 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)", + expectedStmt: "DELETE FROM projections.login_policies5 WHERE (instance_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/mail_template.go b/internal/query/projection/mail_template.go index 8153ffceb4..d88f000543 100644 --- a/internal/query/projection/mail_template.go +++ b/internal/query/projection/mail_template.go @@ -170,13 +170,8 @@ func (p *mailTemplateProjection) reduceOwnerRemoved(event eventstore.Event) (*ha return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-CThXR", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(MailTemplateChangeDateCol, e.CreationDate()), - handler.NewCol(MailTemplateSequenceCol, e.Sequence()), - handler.NewCol(MailTemplateOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(MailTemplateInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(MailTemplateAggregateIDCol, e.Aggregate().ID), diff --git a/internal/query/projection/mail_template_test.go b/internal/query/projection/mail_template_test.go index 284a75b154..f4a7d46b0d 100644 --- a/internal/query/projection/mail_template_test.go +++ b/internal/query/projection/mail_template_test.go @@ -226,11 +226,8 @@ func TestMailTemplateProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.mail_templates2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)", + expectedStmt: "DELETE FROM projections.mail_templates2 WHERE (instance_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/member.go b/internal/query/projection/member.go index b6cad5098b..3c6f0af184 100644 --- a/internal/query/projection/member.go +++ b/internal/query/projection/member.go @@ -139,12 +139,8 @@ func multiReduceMemberOwnerRemoved(e eventstore.Event, opts ...reduceMemberOpt) for _, opt := range opts { config = opt(config) } - return crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(MemberChangeDate, e.CreationDate()), - handler.NewCol(MemberSequence, e.Sequence()), - handler.NewCol(MemberOwnerRemoved, true), - }, + + return crdb.AddDeleteStatement( config.conds, ) } @@ -172,16 +168,14 @@ func memberUserOwnerRemovedCols(e eventstore.Event) []handler.Column { } func reduceMemberUserOwnerRemoved(e eventstore.Event, opts ...reduceMemberOpt) (*handler.Statement, error) { - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - memberUserOwnerRemovedCols(e), memberUserOwnerRemovedConds(e, opts...), ), nil } func multiReduceMemberUserOwnerRemoved(e eventstore.Event, opts ...reduceMemberOpt) func(eventstore.Event) crdb.Exec { - return crdb.AddUpdateStatement( - memberUserOwnerRemovedCols(e), + return crdb.AddDeleteStatement( memberUserOwnerRemovedConds(e, opts...), ) } diff --git a/internal/query/projection/message_text_test.go b/internal/query/projection/message_text_test.go index b48dbed0fd..695829dde4 100644 --- a/internal/query/projection/message_text_test.go +++ b/internal/query/projection/message_text_test.go @@ -698,11 +698,8 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)", + expectedStmt: "DELETE FROM projections.message_texts2 WHERE (instance_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/message_texts.go b/internal/query/projection/message_texts.go index 40d6d5a505..43ede0d07f 100644 --- a/internal/query/projection/message_texts.go +++ b/internal/query/projection/message_texts.go @@ -253,13 +253,8 @@ func (p *messageTextProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-mLsQw", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(MessageTextChangeDateCol, e.CreationDate()), - handler.NewCol(MessageTextSequenceCol, e.Sequence()), - handler.NewCol(MessageTextOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(MessageTextInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(MessageTextAggregateIDCol, e.Aggregate().ID), diff --git a/internal/query/projection/notification_policy.go b/internal/query/projection/notification_policy.go index 628e322cc5..d064d4395a 100644 --- a/internal/query/projection/notification_policy.go +++ b/internal/query/projection/notification_policy.go @@ -172,13 +172,8 @@ func (p *notificationPolicyProjection) reduceOwnerRemoved(event eventstore.Event return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-poxi9a", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(DomainPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(DomainPolicySequenceCol, e.Sequence()), - handler.NewCol(DomainPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(DomainPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(DomainPolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/notification_policy_test.go b/internal/query/projection/notification_policy_test.go index 86a9ed1b65..b61fc6a440 100644 --- a/internal/query/projection/notification_policy_test.go +++ b/internal/query/projection/notification_policy_test.go @@ -227,11 +227,8 @@ func TestNotificationPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.notification_policies SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.notification_policies WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/org.go b/internal/query/projection/org.go index 1906b8977c..8ba5ae4960 100644 --- a/internal/query/projection/org.go +++ b/internal/query/projection/org.go @@ -13,7 +13,7 @@ import ( ) const ( - OrgProjectionTable = "projections.orgs" + OrgProjectionTable = "projections.orgs1" OrgColumnID = "id" OrgColumnCreationDate = "creation_date" @@ -202,13 +202,8 @@ func (p *orgProjection) reduceOrgRemoved(event eventstore.Event) (*handler.State if !ok { return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-DgMSg", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(OrgColumnChangeDate, e.CreationDate()), - handler.NewCol(OrgColumnSequence, e.Sequence()), - handler.NewCol(OrgColumnState, domain.OrgStateRemoved), - }, []handler.Condition{ handler.NewCond(OrgColumnID, e.Aggregate().ID), handler.NewCond(OrgColumnInstanceID, e.Aggregate().InstanceID), diff --git a/internal/query/projection/org_domain.go b/internal/query/projection/org_domain.go index 3211cf7c2c..6436cab38d 100644 --- a/internal/query/projection/org_domain.go +++ b/internal/query/projection/org_domain.go @@ -215,13 +215,8 @@ func (p *orgDomainProjection) reduceOwnerRemoved(event eventstore.Event) (*handl return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dMUKJ", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(OrgDomainChangeDateCol, e.CreationDate()), - handler.NewCol(OrgDomainSequenceCol, e.Sequence()), - handler.NewCol(OrgDomainOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(OrgDomainInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(OrgDomainOrgIDCol, e.Aggregate().ID), diff --git a/internal/query/projection/org_domain_test.go b/internal/query/projection/org_domain_test.go index 4c59cdcdef..99c265ecf0 100644 --- a/internal/query/projection/org_domain_test.go +++ b/internal/query/projection/org_domain_test.go @@ -205,11 +205,8 @@ func TestOrgDomainProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.org_domains2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (org_id = $5)", + expectedStmt: "DELETE FROM projections.org_domains2 WHERE (instance_id = $1) AND (org_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/org_member_test.go b/internal/query/projection/org_member_test.go index b2066ab4c3..b9edf34ba0 100644 --- a/internal/query/projection/org_member_test.go +++ b/internal/query/projection/org_member_test.go @@ -218,21 +218,15 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.org_members3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.org_members3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.org_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)", + expectedStmt: "DELETE FROM projections.org_members3 WHERE (instance_id = $1) AND (user_resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/org_test.go b/internal/query/projection/org_test.go index bae5d6bec6..a5f6795fbc 100644 --- a/internal/query/projection/org_test.go +++ b/internal/query/projection/org_test.go @@ -39,7 +39,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, primary_domain) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.orgs1 SET (change_date, sequence, primary_domain) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -69,7 +69,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.orgs1 SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -99,7 +99,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.orgs1 SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -129,7 +129,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, name) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.orgs1 SET (change_date, sequence, name) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -176,7 +176,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO projections.orgs (id, creation_date, change_date, resource_owner, instance_id, sequence, name, org_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.orgs1 (id, creation_date, change_date, resource_owner, instance_id, sequence, name, org_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "agg-id", anyArg{}, @@ -209,11 +209,8 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "DELETE FROM projections.orgs1 WHERE (id = $1) AND (instance_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - domain.OrgStateRemoved, "agg-id", "instance-id", }, @@ -239,7 +236,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM projections.orgs WHERE (instance_id = $1)", + expectedStmt: "DELETE FROM projections.orgs1 WHERE (instance_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/password_age_policy.go b/internal/query/projection/password_age_policy.go index e8a2a3c958..f03ee0d553 100644 --- a/internal/query/projection/password_age_policy.go +++ b/internal/query/projection/password_age_policy.go @@ -179,13 +179,8 @@ func (p *passwordAgeProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-edLs2", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(AgePolicyChangeDateCol, e.CreationDate()), - handler.NewCol(AgePolicySequenceCol, e.Sequence()), - handler.NewCol(AgePolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(AgePolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(AgePolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/password_age_policy_test.go b/internal/query/projection/password_age_policy_test.go index baff9c2f3d..f6c5e801f9 100644 --- a/internal/query/projection/password_age_policy_test.go +++ b/internal/query/projection/password_age_policy_test.go @@ -236,11 +236,8 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.password_age_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.password_age_policies2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/password_complexity_policy.go b/internal/query/projection/password_complexity_policy.go index dde4f32ca8..b683cd556c 100644 --- a/internal/query/projection/password_complexity_policy.go +++ b/internal/query/projection/password_complexity_policy.go @@ -197,13 +197,8 @@ func (p *passwordComplexityProjection) reduceOwnerRemoved(event eventstore.Event return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-pGTz9", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(ComplexityPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(ComplexityPolicySequenceCol, e.Sequence()), - handler.NewCol(ComplexityPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(ComplexityPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(ComplexityPolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/password_complexity_policy_test.go b/internal/query/projection/password_complexity_policy_test.go index f9d2b1d836..ceac964704 100644 --- a/internal/query/projection/password_complexity_policy_test.go +++ b/internal/query/projection/password_complexity_policy_test.go @@ -260,11 +260,8 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.password_complexity_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.password_complexity_policies2 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/privacy_policy.go b/internal/query/projection/privacy_policy.go index 525363e42f..b577b5eff8 100644 --- a/internal/query/projection/privacy_policy.go +++ b/internal/query/projection/privacy_policy.go @@ -191,13 +191,8 @@ func (p *privacyPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*h return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-bxJCY", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(PrivacyPolicyChangeDateCol, e.CreationDate()), - handler.NewCol(PrivacyPolicySequenceCol, e.Sequence()), - handler.NewCol(PrivacyPolicyOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(PrivacyPolicyInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(PrivacyPolicyResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/privacy_policy_test.go b/internal/query/projection/privacy_policy_test.go index f976c64e9b..630abc6f15 100644 --- a/internal/query/projection/privacy_policy_test.go +++ b/internal/query/projection/privacy_policy_test.go @@ -247,11 +247,8 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.privacy_policies3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.privacy_policies3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/project.go b/internal/query/projection/project.go index c8f286f40a..0848cad6aa 100644 --- a/internal/query/projection/project.go +++ b/internal/query/projection/project.go @@ -231,13 +231,8 @@ func (p *projectProjection) reduceOwnerRemoved(event eventstore.Event) (*handler return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-sbgru", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(ProjectColumnChangeDate, e.CreationDate()), - handler.NewCol(ProjectColumnSequence, e.Sequence()), - handler.NewCol(ProjectColumnOwnerRemoved, true), - }, []handler.Condition{ handler.NewCond(ProjectColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(ProjectColumnResourceOwner, e.Aggregate().ID), diff --git a/internal/query/projection/project_grant.go b/internal/query/projection/project_grant.go index e68d2b6c0f..bb90298a17 100644 --- a/internal/query/projection/project_grant.go +++ b/internal/query/projection/project_grant.go @@ -260,23 +260,13 @@ func (p *projectGrantProjection) reduceOwnerRemoved(event eventstore.Event) (*ha return crdb.NewMultiStatement( e, - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(ProjectGrantColumnChangeDate, e.CreationDate()), - handler.NewCol(ProjectGrantColumnSequence, e.Sequence()), - handler.NewCol(ProjectGrantColumnOwnerRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(ProjectGrantColumnResourceOwner, e.Aggregate().ID), }, ), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(ProjectGrantColumnChangeDate, e.CreationDate()), - handler.NewCol(ProjectGrantColumnSequence, e.Sequence()), - handler.NewCol(ProjectGrantColumnGrantedOrgRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(ProjectGrantColumnGrantedOrgID, e.Aggregate().ID), diff --git a/internal/query/projection/project_grant_member.go b/internal/query/projection/project_grant_member.go index 06523df46f..596db4143f 100644 --- a/internal/query/projection/project_grant_member.go +++ b/internal/query/projection/project_grant_member.go @@ -196,12 +196,7 @@ func (p *projectGrantMemberProjection) reduceOrgRemoved(event eventstore.Event) e, multiReduceMemberOwnerRemoved(e), multiReduceMemberUserOwnerRemoved(e), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(MemberChangeDate, e.CreationDate()), - handler.NewCol(MemberSequence, e.Sequence()), - handler.NewCol(ProjectGrantMemberGrantedOrgRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(ProjectGrantMemberGrantedOrg, e.Aggregate().ID), diff --git a/internal/query/projection/project_grant_member_test.go b/internal/query/projection/project_grant_member_test.go index 133c599264..12a032b9bc 100644 --- a/internal/query/projection/project_grant_member_test.go +++ b/internal/query/projection/project_grant_member_test.go @@ -313,31 +313,22 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.project_grant_members3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.project_grant_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)", + expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (user_resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.project_grant_members3 SET (change_date, sequence, granted_org_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (granted_org = $5)", + expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (granted_org = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/project_grant_test.go b/internal/query/projection/project_grant_test.go index 0c4af2f093..c7ef0532d1 100644 --- a/internal/query/projection/project_grant_test.go +++ b/internal/query/projection/project_grant_test.go @@ -281,21 +281,15 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.project_grants3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, granted_org_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (granted_org_id = $5)", + expectedStmt: "DELETE FROM projections.project_grants3 WHERE (instance_id = $1) AND (granted_org_id = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/project_member_test.go b/internal/query/projection/project_member_test.go index 698cc34b1d..4c0f1ee0c9 100644 --- a/internal/query/projection/project_member_test.go +++ b/internal/query/projection/project_member_test.go @@ -272,21 +272,15 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.project_members3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.project_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)", + expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1) AND (user_resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/project_role.go b/internal/query/projection/project_role.go index 5ee96e9e73..4287414f28 100644 --- a/internal/query/projection/project_role.go +++ b/internal/query/projection/project_role.go @@ -184,13 +184,8 @@ func (p *projectRoleProjection) reduceOwnerRemoved(event eventstore.Event) (*han return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-3XrHY", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(ProjectRoleColumnChangeDate, e.CreationDate()), - handler.NewCol(ProjectRoleColumnSequence, e.Sequence()), - handler.NewCol(ProjectRoleColumnOwnerRemoved, true), - }, []handler.Condition{ handler.NewCond(ProjectRoleColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(ProjectRoleColumnResourceOwner, e.Aggregate().ID), diff --git a/internal/query/projection/project_role_test.go b/internal/query/projection/project_role_test.go index 201c73e686..0f54eb34e0 100644 --- a/internal/query/projection/project_role_test.go +++ b/internal/query/projection/project_role_test.go @@ -203,11 +203,8 @@ func TestProjectRoleProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.project_roles3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.project_roles3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/project_test.go b/internal/query/projection/project_test.go index 3ad1f18e09..a9c05d88c0 100644 --- a/internal/query/projection/project_test.go +++ b/internal/query/projection/project_test.go @@ -241,11 +241,8 @@ func TestProjectProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.projects3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.projects3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/user.go b/internal/query/projection/user.go index 38eed7a711..a7ad4a3450 100644 --- a/internal/query/projection/user.go +++ b/internal/query/projection/user.go @@ -1064,13 +1064,8 @@ func (p *userProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.St return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-NCsdV", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(UserChangeDateCol, e.CreationDate()), - handler.NewCol(UserSequenceCol, e.Sequence()), - handler.NewCol(UserOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(UserInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(UserResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/user_auth_method.go b/internal/query/projection/user_auth_method.go index 13b9c6db79..7e40fcb903 100644 --- a/internal/query/projection/user_auth_method.go +++ b/internal/query/projection/user_auth_method.go @@ -298,13 +298,8 @@ func (p *userAuthMethodProjection) reduceOwnerRemoved(event eventstore.Event) (* return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-FwDZ8", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(UserAuthMethodChangeDateCol, e.CreationDate()), - handler.NewCol(UserAuthMethodSequenceCol, e.Sequence()), - handler.NewCol(UserAuthMethodOwnerRemovedCol, true), - }, []handler.Condition{ handler.NewCond(UserAuthMethodInstanceIDCol, e.Aggregate().InstanceID), handler.NewCond(UserAuthMethodResourceOwnerCol, e.Aggregate().ID), diff --git a/internal/query/projection/user_auth_method_test.go b/internal/query/projection/user_auth_method_test.go index 632f12ae92..6808d62afc 100644 --- a/internal/query/projection/user_auth_method_test.go +++ b/internal/query/projection/user_auth_method_test.go @@ -509,11 +509,8 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.user_auth_methods4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.user_auth_methods4 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/user_grant.go b/internal/query/projection/user_grant.go index d074e16e7a..c02187771b 100644 --- a/internal/query/projection/user_grant.go +++ b/internal/query/projection/user_grant.go @@ -396,45 +396,25 @@ func (p *userGrantProjection) reduceOwnerRemoved(event eventstore.Event) (*handl return crdb.NewMultiStatement( e, - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(UserGrantChangeDate, e.CreationDate()), - handler.NewCol(UserGrantSequence, e.Sequence()), - handler.NewCol(UserGrantOwnerRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID), handler.NewCond(UserGrantResourceOwner, e.Aggregate().ID), }, ), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(UserGrantChangeDate, e.CreationDate()), - handler.NewCol(UserGrantSequence, e.Sequence()), - handler.NewCol(UserGrantUserOwnerRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID), handler.NewCond(UserGrantResourceOwnerUser, e.Aggregate().ID), }, ), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(UserGrantChangeDate, e.CreationDate()), - handler.NewCol(UserGrantSequence, e.Sequence()), - handler.NewCol(UserGrantProjectOwnerRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID), handler.NewCond(UserGrantResourceOwnerProject, e.Aggregate().ID), }, ), - crdb.AddUpdateStatement( - []handler.Column{ - handler.NewCol(UserGrantChangeDate, e.CreationDate()), - handler.NewCol(UserGrantSequence, e.Sequence()), - handler.NewCol(UserGrantGrantedOrgRemoved, true), - }, + crdb.AddDeleteStatement( []handler.Condition{ handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID), handler.NewCond(UserGrantGrantedOrg, e.Aggregate().ID), diff --git a/internal/query/projection/user_grant_test.go b/internal/query/projection/user_grant_test.go index a3e1c49079..a2f98f4bb7 100644 --- a/internal/query/projection/user_grant_test.go +++ b/internal/query/projection/user_grant_test.go @@ -517,41 +517,29 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner_user = $5)", + expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (resource_owner_user = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, project_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner_project = $5)", + expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (resource_owner_project = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, }, { - expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, granted_org_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (granted_org = $5)", + expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1) AND (granted_org = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/user_metadata.go b/internal/query/projection/user_metadata.go index b7513d2d07..d1b06e52ef 100644 --- a/internal/query/projection/user_metadata.go +++ b/internal/query/projection/user_metadata.go @@ -163,13 +163,8 @@ func (p *userMetadataProjection) reduceOwnerRemoved(event eventstore.Event) (*ha return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-oqwul", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(UserMetadataColumnChangeDate, e.CreationDate()), - handler.NewCol(UserMetadataColumnSequence, e.Sequence()), - handler.NewCol(UserMetadataColumnOwnerRemoved, true), - }, []handler.Condition{ handler.NewCond(UserMetadataColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(UserMetadataColumnResourceOwner, e.Aggregate().ID), diff --git a/internal/query/projection/user_metadata_test.go b/internal/query/projection/user_metadata_test.go index e115326f13..923614c41a 100644 --- a/internal/query/projection/user_metadata_test.go +++ b/internal/query/projection/user_metadata_test.go @@ -159,11 +159,8 @@ func TestUserMetadataProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.user_metadata4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.user_metadata4 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/user_personal_access_token.go b/internal/query/projection/user_personal_access_token.go index e44624f725..7ab5e494bd 100644 --- a/internal/query/projection/user_personal_access_token.go +++ b/internal/query/projection/user_personal_access_token.go @@ -155,13 +155,8 @@ func (p *personalAccessTokenProjection) reduceOwnerRemoved(event eventstore.Even return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-zQVhl", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } - return crdb.NewUpdateStatement( + return crdb.NewDeleteStatement( e, - []handler.Column{ - handler.NewCol(PersonalAccessTokenColumnChangeDate, e.CreationDate()), - handler.NewCol(PersonalAccessTokenColumnSequence, e.Sequence()), - handler.NewCol(PersonalAccessTokenColumnOwnerRemoved, true), - }, []handler.Condition{ handler.NewCond(PersonalAccessTokenColumnInstanceID, e.Aggregate().InstanceID), handler.NewCond(PersonalAccessTokenColumnResourceOwner, e.Aggregate().ID), diff --git a/internal/query/projection/user_personal_access_token_test.go b/internal/query/projection/user_personal_access_token_test.go index 778e03d221..a07229d71e 100644 --- a/internal/query/projection/user_personal_access_token_test.go +++ b/internal/query/projection/user_personal_access_token_test.go @@ -129,11 +129,8 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.personal_access_tokens3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.personal_access_tokens3 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/projection/user_test.go b/internal/query/projection/user_test.go index 53d1e81863..7651e75d5c 100644 --- a/internal/query/projection/user_test.go +++ b/internal/query/projection/user_test.go @@ -1713,11 +1713,8 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.users8 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", + expectedStmt: "DELETE FROM projections.users8 WHERE (instance_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ - anyArg{}, - uint64(15), - true, "instance-id", "agg-id", }, diff --git a/internal/query/user_grant_test.go b/internal/query/user_grant_test.go index da54f2008a..bcbd70b4c6 100644 --- a/internal/query/user_grant_test.go +++ b/internal/query/user_grant_test.go @@ -33,14 +33,14 @@ var ( ", projections.users8_humans.avatar_key" + ", projections.login_names2.login_name" + ", projections.user_grants3.resource_owner" + - ", projections.orgs.name" + - ", projections.orgs.primary_domain" + + ", projections.orgs1.name" + + ", projections.orgs1.primary_domain" + ", projections.user_grants3.project_id" + ", projections.projects3.name" + " FROM projections.user_grants3" + " LEFT JOIN projections.users8 ON projections.user_grants3.user_id = projections.users8.id AND projections.user_grants3.instance_id = projections.users8.instance_id" + " LEFT JOIN projections.users8_humans ON projections.user_grants3.user_id = projections.users8_humans.user_id AND projections.user_grants3.instance_id = projections.users8_humans.instance_id" + - " LEFT JOIN projections.orgs ON projections.user_grants3.resource_owner = projections.orgs.id AND projections.user_grants3.instance_id = projections.orgs.instance_id" + + " LEFT JOIN projections.orgs1 ON projections.user_grants3.resource_owner = projections.orgs1.id AND projections.user_grants3.instance_id = projections.orgs1.instance_id" + " LEFT JOIN projections.projects3 ON projections.user_grants3.project_id = projections.projects3.id AND projections.user_grants3.instance_id = projections.projects3.instance_id" + " LEFT JOIN projections.login_names2 ON projections.user_grants3.user_id = projections.login_names2.user_id AND projections.user_grants3.instance_id = projections.login_names2.instance_id" + ` AS OF SYSTEM TIME '-1 ms' ` + @@ -88,15 +88,15 @@ var ( ", projections.users8_humans.avatar_key" + ", projections.login_names2.login_name" + ", projections.user_grants3.resource_owner" + - ", projections.orgs.name" + - ", projections.orgs.primary_domain" + + ", projections.orgs1.name" + + ", projections.orgs1.primary_domain" + ", projections.user_grants3.project_id" + ", projections.projects3.name" + ", COUNT(*) OVER ()" + " FROM projections.user_grants3" + " LEFT JOIN projections.users8 ON projections.user_grants3.user_id = projections.users8.id AND projections.user_grants3.instance_id = projections.users8.instance_id" + " LEFT JOIN projections.users8_humans ON projections.user_grants3.user_id = projections.users8_humans.user_id AND projections.user_grants3.instance_id = projections.users8_humans.instance_id" + - " LEFT JOIN projections.orgs ON projections.user_grants3.resource_owner = projections.orgs.id AND projections.user_grants3.instance_id = projections.orgs.instance_id" + + " LEFT JOIN projections.orgs1 ON projections.user_grants3.resource_owner = projections.orgs1.id AND projections.user_grants3.instance_id = projections.orgs1.instance_id" + " LEFT JOIN projections.projects3 ON projections.user_grants3.project_id = projections.projects3.id AND projections.user_grants3.instance_id = projections.projects3.instance_id" + " LEFT JOIN projections.login_names2 ON projections.user_grants3.user_id = projections.login_names2.user_id AND projections.user_grants3.instance_id = projections.login_names2.instance_id" + ` AS OF SYSTEM TIME '-1 ms' ` + diff --git a/internal/query/user_membership_test.go b/internal/query/user_membership_test.go index 237e21359d..108f5d8601 100644 --- a/internal/query/user_membership_test.go +++ b/internal/query/user_membership_test.go @@ -28,7 +28,7 @@ var ( ", memberships.grant_id" + ", projections.project_grants3.granted_org_id" + ", projections.projects3.name" + - ", projections.orgs.name" + + ", projections.orgs1.name" + ", COUNT(*) OVER ()" + " FROM (" + "SELECT members.user_id" + @@ -88,7 +88,7 @@ var ( " WHERE members.granted_org_removed = $7 AND members.owner_removed = $8 AND members.user_owner_removed = $9" + ") AS memberships" + " LEFT JOIN projections.projects3 ON memberships.project_id = projections.projects3.id AND memberships.instance_id = projections.projects3.instance_id" + - " LEFT JOIN projections.orgs ON memberships.org_id = projections.orgs.id AND memberships.instance_id = projections.orgs.instance_id" + + " LEFT JOIN projections.orgs1 ON memberships.org_id = projections.orgs1.id AND memberships.instance_id = projections.orgs1.instance_id" + " LEFT JOIN projections.project_grants3 ON memberships.grant_id = projections.project_grants3.grant_id AND memberships.instance_id = projections.project_grants3.instance_id" + ` AS OF SYSTEM TIME '-1 ms'`) membershipCols = []string{ diff --git a/internal/webauthn/webauthn.go b/internal/webauthn/webauthn.go index 866f174a2e..8a9709ec86 100644 --- a/internal/webauthn/webauthn.go +++ b/internal/webauthn/webauthn.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "github.com/go-webauthn/webauthn/protocol" "github.com/go-webauthn/webauthn/webauthn" @@ -100,8 +101,7 @@ func (w *Config) FinishRegistration(ctx context.Context, user *domain.Human, web } credentialData, err := protocol.ParseCredentialCreationResponseBody(bytes.NewReader(credData)) if err != nil { - e := *err.(*protocol.Error) - logging.WithFields("error", e).Error("webauthn credential could not be parsed") + logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn credential could not be parsed") return nil, caos_errs.ThrowInternal(err, "WEBAU-sEr8c", "Errors.User.WebAuthN.ErrorOnParseCredential") } sessionData := WebAuthNToSessionData(webAuthN) @@ -116,6 +116,7 @@ func (w *Config) FinishRegistration(ctx context.Context, user *domain.Human, web sessionData, credentialData) if err != nil { + logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn credential could not be created") return nil, caos_errs.ThrowInternal(err, "WEBAU-3Vb9s", "Errors.User.WebAuthN.CreateCredentialFailed") } @@ -139,6 +140,7 @@ func (w *Config) BeginLogin(ctx context.Context, user *domain.Human, userVerific credentials: WebAuthNsToCredentials(webAuthNs, rpID), }, webauthn.WithUserVerification(UserVerificationFromDomain(userVerification))) if err != nil { + logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn login could not be started") return nil, caos_errs.ThrowInternal(err, "WEBAU-4G8sw", "Errors.User.WebAuthN.BeginLoginFailed") } cred, err := json.Marshal(assertion) @@ -157,6 +159,7 @@ func (w *Config) BeginLogin(ctx context.Context, user *domain.Human, userVerific func (w *Config) FinishLogin(ctx context.Context, user *domain.Human, webAuthN *domain.WebAuthNLogin, credData []byte, webAuthNs ...*domain.WebAuthNToken) (*webauthn.Credential, error) { assertionData, err := protocol.ParseCredentialRequestResponseBody(bytes.NewReader(credData)) if err != nil { + logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn assertion could not be parsed") return nil, caos_errs.ThrowInternal(err, "WEBAU-ADgv4", "Errors.User.WebAuthN.ValidateLoginFailed") } webUser := &webUser{ @@ -169,11 +172,12 @@ func (w *Config) FinishLogin(ctx context.Context, user *domain.Human, webAuthN * } credential, err := webAuthNServer.ValidateLogin(webUser, WebAuthNLoginToSessionData(webAuthN), assertionData) if err != nil { + logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn assertion failed") return nil, caos_errs.ThrowInternal(err, "WEBAU-3M9si", "Errors.User.WebAuthN.ValidateLoginFailed") } if credential.Authenticator.CloneWarning { - return credential, caos_errs.ThrowInternal(err, "WEBAU-4M90s", "Errors.User.WebAuthN.CloneWarning") + return credential, caos_errs.ThrowInternal(nil, "WEBAU-4M90s", "Errors.User.WebAuthN.CloneWarning") } return credential, nil } @@ -206,3 +210,11 @@ func (w *Config) config(id, origin string) *webauthn.Config { RPOrigins: []string{origin}, } } + +func tryExtractProtocolErrMsg(err error) string { + var e *protocol.Error + if errors.As(err, &e) { + return e.Details + ": " + e.DevInfo + } + return e.Error() +} diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto index 99cf4893d0..153f3b8f54 100644 --- a/proto/zitadel/admin.proto +++ b/proto/zitadel/admin.proto @@ -844,7 +844,7 @@ service AdminService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags: "Organizations"; summary: "Remove Organization"; - description: "Sets the state of the organization and all its resource (Users, Projects, Grants to and from the org) to remove. Users of this organization will not be able to log in." + description: "Deletes the organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in." responses: { key: "200"; value: { @@ -6494,48 +6494,48 @@ message SetDefaultInitMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Initialize User\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Initialize User\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Initialize User\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; - } - ]; - string text = 6 [ - (validate.rules).string = {max_len: 1000}, - (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "\"This user was created in Zitadel. Use the username {{.PreferredLoginName}} to log in. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it.\"" max_length: 1000; } ]; - string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + string text = 6 [ + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "\"Finish initialization\"" - max_length: 200; + example: "\"This user was created in Zitadel. Use the username {{.PreferredLoginName}} to log in. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it.\"" + max_length: 10000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string button_text = 7 [ + (validate.rules).string = {max_bytes: 4000}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"Finish initialization\"" + max_length: 1000; + } + ]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultInitMessageTextResponse { @@ -6577,48 +6577,48 @@ message SetDefaultPasswordResetMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Reset Password\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Reset Password\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Reset Password\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"We received a password reset request. Please use the button below to reset your password. (Code {{.Code}}) If you didn't ask for this mail, please ignore it.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Reset Password\"" - max_length: 200; + max_length: 500; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultPasswordResetMessageTextResponse { @@ -6660,48 +6660,48 @@ message SetDefaultVerifyEmailMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Verify Email\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Email\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Email\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you didn't add a new email, please ignore this email.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Email\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultVerifyEmailMessageTextResponse { @@ -6743,31 +6743,31 @@ message SetDefaultVerifyPhoneMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Verify Phone\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Phone\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Phone\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ @@ -6778,13 +6778,13 @@ message SetDefaultVerifyPhoneMessageTextRequest { } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Phone\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultVerifyPhoneMessageTextResponse { @@ -6869,48 +6869,48 @@ message SetDefaultVerifyEmailOTPMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - One-time Password\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify One-time Password \"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify One-time Password\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Please use the \\\"Authenticate\\\" button or copy the one-time password {{.OTP}} and paste it to to the authentication screen in order to authenticate at ZITADEL within the next five minutes.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Authenticate\"" - max_length: 200; + max_length: 500; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultVerifyEmailOTPMessageTextResponse { @@ -6952,48 +6952,48 @@ message SetDefaultDomainClaimedMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Domain has been claimed\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Change email / username\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Domain has been claimed\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"The domain {{.Domain}} has been claimed by an organization. Your current user {{.UserName}} is not part of this organization. Therefore you'll have to change your email when you log in. We have created a temporary username ({{.TempUsername}}) for this login.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Login\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultDomainClaimedMessageTextResponse { @@ -7035,48 +7035,48 @@ message SetDefaultPasswordChangeMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Password of the user has changed\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Password Changed\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Password of user has changed\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"The password of your user has changed, if this change was not done by you, please be advised to immediately reset your password.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Login\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_len: 8000}]; } message SetDefaultPasswordChangeMessageTextResponse { @@ -7119,48 +7119,48 @@ message SetDefaultPasswordlessRegistrationMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 500; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"We received a request to add a token for passwordless login. Please use the button below to add your token or device for passwordless login.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Add Passwordless Login\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetDefaultPasswordlessRegistrationMessageTextResponse { diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index 6561ff16ca..5285d2ffdc 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -2027,7 +2027,7 @@ service ManagementService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags: "Organizations"; summary: "Delete Organization"; - description: "Sets the state of my organization and all its resource (Users, Projects, Grants to and from the org) to remove. Users of this organization will not be able to log in." + description: "Deletes my organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in." parameters: { headers: { name: "x-zitadel-orgid"; @@ -8006,6 +8006,7 @@ message UpdateHumanProfileRequest { ]; string display_name = 5 [ (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { min_length: 1; max_length: 200; @@ -10599,48 +10600,48 @@ message SetCustomInitMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Initialize User\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Initialize User\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Initialize User\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"This user was created in Zitadel. Use the username {{.PreferredLoginName}} to log in. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Finish initialization\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomInitMessageTextResponse { @@ -10749,48 +10750,48 @@ message SetCustomPasswordResetMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Reset Password\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Reset Password\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Reset Password\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"We received a password reset request. Please use the button below to reset your password. (Code {{.Code}}) If you didn't ask for this mail, please ignore it.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Reset Password\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomPasswordResetMessageTextResponse { @@ -10829,48 +10830,48 @@ message SetCustomVerifyEmailMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Verify Email\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Email\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Email\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you didn't add a new email, please ignore this email.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Email\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomVerifyEmailMessageTextResponse { @@ -10909,31 +10910,31 @@ message SetCustomVerifyPhoneMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Verify Phone\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Phone\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Phone\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ @@ -10944,13 +10945,13 @@ message SetCustomVerifyPhoneMessageTextRequest { } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify Phone\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomVerifyPhoneMessageTextResponse { @@ -11033,48 +11034,48 @@ message SetCustomVerifyEmailOTPMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - One-time Password\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify One-time Password \"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Verify One-time Password\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Please use the \\\"Authenticate\\\" button or copy the one-time password {{.OTP}} and paste it to to the authentication screen in order to authenticate at ZITADEL within the next five minutes.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Authenticate\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomVerifyEmailOTPMessageTextResponse { @@ -11113,48 +11114,48 @@ message SetCustomDomainClaimedMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Domain has been claimed\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Change email / username\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Domain has been claimed\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"The domain {{.Domain}} has been claimed by an organization. Your current user {{.UserName}} is not part of this organization. Therefore you'll have to change your email when you log in. We have created a temporary username ({{.TempUsername}}) for this login.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Login\"" - max_length: 200; + max_length: 1000; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomDomainClaimedMessageTextResponse { @@ -11194,48 +11195,48 @@ message SetCustomPasswordlessRegistrationMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Password of the user has changed\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Password Changed\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Password of user has changed\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"The password of your user has changed, if this change was not done by you, please be advised to immediately reset your password.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Login\"" - max_length: 200; + max_length: 500; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomPasswordlessRegistrationMessageTextResponse { @@ -11274,48 +11275,48 @@ message SetCustomPasswordChangeMessageTextRequest { } ]; string title = 2 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"ZITADEL - Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; string pre_header = 3 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; string subject = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 2000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; string greeting = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Hello {{.FirstName}} {{.LastName}},\"" - max_length: 200; + max_length: 1000; } ]; string text = 6 [ - (validate.rules).string = {max_len: 800}, + (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"We received a request to add a token for passwordless login. Please use the button below to add your token or device for passwordless login.\"" - max_length: 800; + max_length: 10000; } ]; string button_text = 7 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_bytes: 4000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"Add Passwordless Login\"" - max_length: 200; + max_length: 500; } ]; - string footer_text = 8 [(validate.rules).string = {max_len: 200}]; + string footer_text = 8 [(validate.rules).string = {max_bytes: 8000}]; } message SetCustomPasswordChangeMessageTextResponse { @@ -12656,13 +12657,13 @@ message CreateActionRequest { } ]; string script = 2 [ - (validate.rules).string = {min_len: 1, max_len: 2000}, + (validate.rules).string = {min_len: 1, max_bytes: 40000}, (google.api.field_behavior) = REQUIRED, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"function log(context, calls){console.log(context)}\""; description: "Javascript code that should be executed" min_length: 1; - max_length: 2000; + max_length: 10000; } ]; google.protobuf.Duration timeout = 3 [ @@ -12705,9 +12706,12 @@ message UpdateActionRequest { } ]; string script = 3 [ - (validate.rules).string = {min_len: 1, max_len: 2000}, + (validate.rules).string = {min_len: 1, max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"function log(context, calls){console.log(context)}\""; + description: "Javascript code that should be executed" + min_length: 1; + max_length: 10000; } ]; google.protobuf.Duration timeout = 4 [ diff --git a/proto/zitadel/object/v2alpha/object.proto b/proto/zitadel/object/v2beta/object.proto similarity index 98% rename from proto/zitadel/object/v2alpha/object.proto rename to proto/zitadel/object/v2beta/object.proto index 5150ad7929..75f82d98ae 100644 --- a/proto/zitadel/object/v2alpha/object.proto +++ b/proto/zitadel/object/v2beta/object.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.object.v2alpha; +package zitadel.object.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha;object"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/object/v2beta;object"; import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; diff --git a/proto/zitadel/oidc/v2alpha/authorization.proto b/proto/zitadel/oidc/v2beta/authorization.proto similarity index 98% rename from proto/zitadel/oidc/v2alpha/authorization.proto rename to proto/zitadel/oidc/v2beta/authorization.proto index 69a14a3d07..2c6c562d50 100644 --- a/proto/zitadel/oidc/v2alpha/authorization.proto +++ b/proto/zitadel/oidc/v2beta/authorization.proto @@ -1,12 +1,12 @@ syntax = "proto3"; -package zitadel.oidc.v2alpha; +package zitadel.oidc.v2beta; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha;oidc"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta;oidc"; message AuthRequest{ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { diff --git a/proto/zitadel/oidc/v2alpha/oidc_service.proto b/proto/zitadel/oidc/v2beta/oidc_service.proto similarity index 92% rename from proto/zitadel/oidc/v2alpha/oidc_service.proto rename to proto/zitadel/oidc/v2beta/oidc_service.proto index f4f7fb2452..f6dd78730a 100644 --- a/proto/zitadel/oidc/v2alpha/oidc_service.proto +++ b/proto/zitadel/oidc/v2beta/oidc_service.proto @@ -1,22 +1,22 @@ syntax = "proto3"; -package zitadel.oidc.v2alpha; +package zitadel.oidc.v2beta; -import "zitadel/object/v2alpha/object.proto"; +import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -import "zitadel/oidc/v2alpha/authorization.proto"; +import "zitadel/oidc/v2beta/authorization.proto"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha;oidc"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta;oidc"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "OIDC Service"; - version: "2.0-alpha"; - description: "Get OIDC Auth Request details and create callback URLs. This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login."; + version: "2.0-beta"; + description: "Get OIDC Auth Request details and create callback URLs. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login."; contact:{ name: "ZITADEL" url: "https://zitadel.com" @@ -103,7 +103,7 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { service OIDCService { rpc GetAuthRequest (GetAuthRequestRequest) returns (GetAuthRequestResponse) { option (google.api.http) = { - get: "/v2alpha/oidc/auth_requests/{auth_request_id}" + get: "/v2beta/oidc/auth_requests/{auth_request_id}" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -126,7 +126,7 @@ service OIDCService { rpc CreateCallback (CreateCallbackRequest) returns (CreateCallbackResponse) { option (google.api.http) = { - post: "/v2alpha/oidc/auth_requests/{auth_request_id}" + post: "/v2beta/oidc/auth_requests/{auth_request_id}" body: "*" }; @@ -208,7 +208,7 @@ message Session { } message CreateCallbackResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string callback_url = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { description: "Callback URL where the user should be redirected, using a \"302 FOUND\" status. Contains details for the application to obtain the tokens on success, or error details on failure. Note that this field must be treated as credentials, as the contained code can be used to obtain tokens on behalve of the user."; diff --git a/proto/zitadel/org/v2beta/org_service.proto b/proto/zitadel/org/v2beta/org_service.proto index af10d6c4f5..7ea2581c1b 100644 --- a/proto/zitadel/org/v2beta/org_service.proto +++ b/proto/zitadel/org/v2beta/org_service.proto @@ -3,15 +3,15 @@ syntax = "proto3"; package zitadel.org.v2beta; -import "zitadel/object/v2alpha/object.proto"; +import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -import "zitadel/user/v2alpha/auth.proto"; -import "zitadel/user/v2alpha/email.proto"; -import "zitadel/user/v2alpha/phone.proto"; -import "zitadel/user/v2alpha/idp.proto"; -import "zitadel/user/v2alpha/password.proto"; -import "zitadel/user/v2alpha/user.proto"; -import "zitadel/user/v2alpha/user_service.proto"; +import "zitadel/user/v2beta/auth.proto"; +import "zitadel/user/v2beta/email.proto"; +import "zitadel/user/v2beta/phone.proto"; +import "zitadel/user/v2beta/idp.proto"; +import "zitadel/user/v2beta/password.proto"; +import "zitadel/user/v2beta/user.proto"; +import "zitadel/user/v2beta/user_service.proto"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "google/protobuf/duration.proto"; @@ -24,7 +24,7 @@ option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2beta;org"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "User Service"; - version: "2.0-alpha"; + version: "2.0-beta"; description: "This API is intended to manage organizations in a ZITADEL instance. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login."; contact:{ name: "ZITADEL" @@ -144,7 +144,7 @@ message AddOrganizationRequest{ message Admin { oneof user_type{ string user_id = 1; - zitadel.user.v2alpha.AddHumanUserRequest human = 2; + zitadel.user.v2beta.AddHumanUserRequest human = 2; } // specify Org Member Roles for the provided user (default is ORG_OWNER if roles are empty) repeated string roles = 3; @@ -168,7 +168,7 @@ message AddOrganizationResponse{ optional string email_code = 2; optional string phone_code = 3; } - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string organization_id = 2; repeated CreatedAdmin created_admins = 3; } diff --git a/proto/zitadel/session/v2alpha/challenge.proto b/proto/zitadel/session/v2beta/challenge.proto similarity index 98% rename from proto/zitadel/session/v2alpha/challenge.proto rename to proto/zitadel/session/v2beta/challenge.proto index b8c6b0c089..aa8a5a549b 100644 --- a/proto/zitadel/session/v2alpha/challenge.proto +++ b/proto/zitadel/session/v2beta/challenge.proto @@ -1,13 +1,13 @@ syntax = "proto3"; -package zitadel.session.v2alpha; +package zitadel.session.v2beta; import "google/api/field_behavior.proto"; import "google/protobuf/struct.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha;session"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2beta;session"; enum UserVerificationRequirement { USER_VERIFICATION_REQUIREMENT_UNSPECIFIED = 0; diff --git a/proto/zitadel/session/v2alpha/session.proto b/proto/zitadel/session/v2beta/session.proto similarity index 98% rename from proto/zitadel/session/v2alpha/session.proto rename to proto/zitadel/session/v2beta/session.proto index 5c0bcb3115..ddbe143361 100644 --- a/proto/zitadel/session/v2alpha/session.proto +++ b/proto/zitadel/session/v2beta/session.proto @@ -1,12 +1,12 @@ syntax = "proto3"; -package zitadel.session.v2alpha; +package zitadel.session.v2beta; import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha;session"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2beta;session"; message Session { string id = 1 [ diff --git a/proto/zitadel/session/v2alpha/session_service.proto b/proto/zitadel/session/v2beta/session_service.proto similarity index 94% rename from proto/zitadel/session/v2alpha/session_service.proto rename to proto/zitadel/session/v2beta/session_service.proto index c1f0523418..d29930dcd6 100644 --- a/proto/zitadel/session/v2alpha/session_service.proto +++ b/proto/zitadel/session/v2beta/session_service.proto @@ -1,25 +1,25 @@ syntax = "proto3"; -package zitadel.session.v2alpha; +package zitadel.session.v2beta; -import "zitadel/object/v2alpha/object.proto"; +import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -import "zitadel/session/v2alpha/challenge.proto"; -import "zitadel/session/v2alpha/session.proto"; +import "zitadel/session/v2beta/challenge.proto"; +import "zitadel/session/v2beta/session.proto"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "google/protobuf/struct.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha;session"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2beta;session"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Session Service"; - version: "2.0-alpha"; - description: "This API is intended to manage sessions in a ZITADEL instance. This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login."; + version: "2.0-beta"; + description: "This API is intended to manage sessions in a ZITADEL instance. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login."; contact:{ name: "ZITADEL" url: "https://zitadel.com" @@ -108,7 +108,7 @@ service SessionService { // Search sessions rpc ListSessions (ListSessionsRequest) returns (ListSessionsResponse) { option (google.api.http) = { - post: "/v2alpha/sessions/search" + post: "/v2beta/sessions/search" body: "*" }; @@ -144,7 +144,7 @@ service SessionService { // GetSession a session rpc GetSession (GetSessionRequest) returns (GetSessionResponse) { option (google.api.http) = { - get: "/v2alpha/sessions/{session_id}" + get: "/v2beta/sessions/{session_id}" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -168,7 +168,7 @@ service SessionService { // Create a new session rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) { option (google.api.http) = { - post: "/v2alpha/sessions" + post: "/v2beta/sessions" body: "*" }; @@ -196,7 +196,7 @@ service SessionService { // Update a session rpc SetSession (SetSessionRequest) returns (SetSessionResponse) { option (google.api.http) = { - patch: "/v2alpha/sessions/{session_id}" + patch: "/v2beta/sessions/{session_id}" body: "*" }; @@ -221,7 +221,7 @@ service SessionService { // Terminate a session rpc DeleteSession (DeleteSessionRequest) returns (DeleteSessionResponse) { option (google.api.http) = { - delete: "/v2alpha/sessions/{session_id}" + delete: "/v2beta/sessions/{session_id}" body: "*" }; @@ -245,12 +245,12 @@ service SessionService { } message ListSessionsRequest{ - zitadel.object.v2alpha.ListQuery query = 1; + zitadel.object.v2beta.ListQuery query = 1; repeated SearchQuery queries = 2; } message ListSessionsResponse{ - zitadel.object.v2alpha.ListDetails details = 1; + zitadel.object.v2beta.ListDetails details = 1; repeated Session sessions = 2; } @@ -277,7 +277,7 @@ message CreateSessionRequest{ } message CreateSessionResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string session_id = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { description: "\"id of the session\""; @@ -324,7 +324,7 @@ message SetSessionRequest{ } message SetSessionResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string session_token = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { description: "\"token of the session, which is required for further updates of the session or the request other resources\""; @@ -351,7 +351,7 @@ message DeleteSessionRequest{ } message DeleteSessionResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message Checks { diff --git a/proto/zitadel/settings/v2alpha/branding_settings.proto b/proto/zitadel/settings/v2beta/branding_settings.proto similarity index 96% rename from proto/zitadel/settings/v2alpha/branding_settings.proto rename to proto/zitadel/settings/v2beta/branding_settings.proto index a98b67769a..5ddc4067ce 100644 --- a/proto/zitadel/settings/v2alpha/branding_settings.proto +++ b/proto/zitadel/settings/v2beta/branding_settings.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "zitadel/settings/v2alpha/settings.proto"; +import "zitadel/settings/v2beta/settings.proto"; message BrandingSettings { Theme light_theme = 1; diff --git a/proto/zitadel/settings/v2alpha/domain_settings.proto b/proto/zitadel/settings/v2beta/domain_settings.proto similarity index 92% rename from proto/zitadel/settings/v2alpha/domain_settings.proto rename to proto/zitadel/settings/v2beta/domain_settings.proto index 4eae13dc70..88787867b4 100644 --- a/proto/zitadel/settings/v2alpha/domain_settings.proto +++ b/proto/zitadel/settings/v2beta/domain_settings.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "zitadel/settings/v2alpha/settings.proto"; +import "zitadel/settings/v2beta/settings.proto"; message DomainSettings { bool login_name_includes_domain = 1 [ diff --git a/proto/zitadel/settings/v2alpha/legal_settings.proto b/proto/zitadel/settings/v2beta/legal_settings.proto similarity index 92% rename from proto/zitadel/settings/v2alpha/legal_settings.proto rename to proto/zitadel/settings/v2beta/legal_settings.proto index 3b9d5694e2..b170d5f894 100644 --- a/proto/zitadel/settings/v2alpha/legal_settings.proto +++ b/proto/zitadel/settings/v2beta/legal_settings.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "zitadel/settings/v2alpha/settings.proto"; +import "zitadel/settings/v2beta/settings.proto"; import "validate/validate.proto"; message LegalAndSupportSettings { diff --git a/proto/zitadel/settings/v2alpha/lockout_settings.proto b/proto/zitadel/settings/v2beta/lockout_settings.proto similarity index 89% rename from proto/zitadel/settings/v2alpha/lockout_settings.proto rename to proto/zitadel/settings/v2beta/lockout_settings.proto index 7a5ad6244e..10786c9282 100644 --- a/proto/zitadel/settings/v2alpha/lockout_settings.proto +++ b/proto/zitadel/settings/v2beta/lockout_settings.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "zitadel/settings/v2alpha/settings.proto"; +import "zitadel/settings/v2beta/settings.proto"; message LockoutSettings { uint64 max_password_attempts = 1 [ diff --git a/proto/zitadel/settings/v2alpha/login_settings.proto b/proto/zitadel/settings/v2beta/login_settings.proto similarity index 98% rename from proto/zitadel/settings/v2alpha/login_settings.proto rename to proto/zitadel/settings/v2beta/login_settings.proto index 057d076ce0..bb0d6fa5ec 100644 --- a/proto/zitadel/settings/v2alpha/login_settings.proto +++ b/proto/zitadel/settings/v2beta/login_settings.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "zitadel/settings/v2alpha/settings.proto"; +import "zitadel/settings/v2beta/settings.proto"; import "google/protobuf/duration.proto"; message LoginSettings { diff --git a/proto/zitadel/settings/v2alpha/password_settings.proto b/proto/zitadel/settings/v2beta/password_settings.proto similarity index 93% rename from proto/zitadel/settings/v2alpha/password_settings.proto rename to proto/zitadel/settings/v2beta/password_settings.proto index f5f30be47d..869cbb0ff2 100644 --- a/proto/zitadel/settings/v2alpha/password_settings.proto +++ b/proto/zitadel/settings/v2beta/password_settings.proto @@ -1,11 +1,11 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "zitadel/settings/v2alpha/settings.proto"; +import "zitadel/settings/v2beta/settings.proto"; message PasswordComplexitySettings { uint64 min_length = 1 [ diff --git a/proto/zitadel/settings/v2alpha/settings.proto b/proto/zitadel/settings/v2beta/settings.proto similarity index 83% rename from proto/zitadel/settings/v2alpha/settings.proto rename to proto/zitadel/settings/v2beta/settings.proto index 7131015514..9ad4f0e469 100644 --- a/proto/zitadel/settings/v2alpha/settings.proto +++ b/proto/zitadel/settings/v2beta/settings.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; import "protoc-gen-openapiv2/options/annotations.proto"; diff --git a/proto/zitadel/settings/v2alpha/settings_service.proto b/proto/zitadel/settings/v2beta/settings_service.proto similarity index 80% rename from proto/zitadel/settings/v2alpha/settings_service.proto rename to proto/zitadel/settings/v2beta/settings_service.proto index 8c1acb6ad6..5a5c177eb8 100644 --- a/proto/zitadel/settings/v2alpha/settings_service.proto +++ b/proto/zitadel/settings/v2beta/settings_service.proto @@ -1,27 +1,27 @@ syntax = "proto3"; -package zitadel.settings.v2alpha; +package zitadel.settings.v2beta; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -import "zitadel/object/v2alpha/object.proto"; -import "zitadel/settings/v2alpha/branding_settings.proto"; -import "zitadel/settings/v2alpha/domain_settings.proto"; -import "zitadel/settings/v2alpha/legal_settings.proto"; -import "zitadel/settings/v2alpha/lockout_settings.proto"; -import "zitadel/settings/v2alpha/login_settings.proto"; -import "zitadel/settings/v2alpha/password_settings.proto"; +import "zitadel/object/v2beta/object.proto"; +import "zitadel/settings/v2beta/branding_settings.proto"; +import "zitadel/settings/v2beta/domain_settings.proto"; +import "zitadel/settings/v2beta/legal_settings.proto"; +import "zitadel/settings/v2beta/lockout_settings.proto"; +import "zitadel/settings/v2beta/login_settings.proto"; +import "zitadel/settings/v2beta/password_settings.proto"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha;settings"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta;settings"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "Settings Service"; - version: "2.0-alpha"; - description: "This API is intended to manage settings in a ZITADEL instance. This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login."; + version: "2.0-beta"; + description: "This API is intended to manage settings in a ZITADEL instance. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login."; contact:{ name: "ZITADEL" url: "https://zitadel.com" @@ -110,7 +110,7 @@ service SettingsService { // Get basic information over the instance rpc GetGeneralSettings (GetGeneralSettingsRequest) returns (GetGeneralSettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings" + get: "/v2beta/settings" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -134,7 +134,7 @@ service SettingsService { // Get the login settings rpc GetLoginSettings (GetLoginSettingsRequest) returns (GetLoginSettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings/login" + get: "/v2beta/settings/login" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -158,7 +158,7 @@ service SettingsService { // Get the current active identity providers rpc GetActiveIdentityProviders (GetActiveIdentityProvidersRequest) returns (GetActiveIdentityProvidersResponse) { option (google.api.http) = { - get: "/v2alpha/settings/login/idps" + get: "/v2beta/settings/login/idps" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -182,7 +182,7 @@ service SettingsService { // Get the password complexity settings rpc GetPasswordComplexitySettings (GetPasswordComplexitySettingsRequest) returns (GetPasswordComplexitySettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings/password/complexity" + get: "/v2beta/settings/password/complexity" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -206,7 +206,7 @@ service SettingsService { // Get the current active branding settings rpc GetBrandingSettings (GetBrandingSettingsRequest) returns (GetBrandingSettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings/branding" + get: "/v2beta/settings/branding" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -230,7 +230,7 @@ service SettingsService { // Get the domain settings rpc GetDomainSettings (GetDomainSettingsRequest) returns (GetDomainSettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings/domain" + get: "/v2beta/settings/domain" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -254,7 +254,7 @@ service SettingsService { // Get the legal and support settings rpc GetLegalAndSupportSettings (GetLegalAndSupportSettingsRequest) returns (GetLegalAndSupportSettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings/legal_support" + get: "/v2beta/settings/legal_support" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -278,7 +278,7 @@ service SettingsService { // Get the lockout settings rpc GetLockoutSettings (GetLockoutSettingsRequest) returns (GetLockoutSettingsResponse) { option (google.api.http) = { - get: "/v2alpha/settings/lockout" + get: "/v2beta/settings/lockout" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -301,66 +301,66 @@ service SettingsService { } message GetLoginSettingsRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetLoginSettingsResponse { - zitadel.object.v2alpha.Details details = 1; - zitadel.settings.v2alpha.LoginSettings settings = 2; + zitadel.object.v2beta.Details details = 1; + zitadel.settings.v2beta.LoginSettings settings = 2; } message GetPasswordComplexitySettingsRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetPasswordComplexitySettingsResponse { - zitadel.object.v2alpha.Details details = 1; - zitadel.settings.v2alpha.PasswordComplexitySettings settings = 2; + zitadel.object.v2beta.Details details = 1; + zitadel.settings.v2beta.PasswordComplexitySettings settings = 2; } message GetBrandingSettingsRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetBrandingSettingsResponse { - zitadel.object.v2alpha.Details details = 1; - zitadel.settings.v2alpha.BrandingSettings settings = 2; + zitadel.object.v2beta.Details details = 1; + zitadel.settings.v2beta.BrandingSettings settings = 2; } message GetDomainSettingsRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetDomainSettingsResponse { - zitadel.object.v2alpha.Details details = 1; - zitadel.settings.v2alpha.DomainSettings settings = 2; + zitadel.object.v2beta.Details details = 1; + zitadel.settings.v2beta.DomainSettings settings = 2; } message GetLegalAndSupportSettingsRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetLegalAndSupportSettingsResponse { - zitadel.object.v2alpha.Details details = 1; - zitadel.settings.v2alpha.LegalAndSupportSettings settings = 2; + zitadel.object.v2beta.Details details = 1; + zitadel.settings.v2beta.LegalAndSupportSettings settings = 2; } message GetLockoutSettingsRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetLockoutSettingsResponse { - zitadel.object.v2alpha.Details details = 1; - zitadel.settings.v2alpha.LockoutSettings settings = 2; + zitadel.object.v2beta.Details details = 1; + zitadel.settings.v2beta.LockoutSettings settings = 2; } message GetActiveIdentityProvidersRequest { - zitadel.object.v2alpha.RequestContext ctx = 1; + zitadel.object.v2beta.RequestContext ctx = 1; } message GetActiveIdentityProvidersResponse { - zitadel.object.v2alpha.ListDetails details = 1; - repeated zitadel.settings.v2alpha.IdentityProvider identity_providers = 2; + zitadel.object.v2beta.ListDetails details = 1; + repeated zitadel.settings.v2beta.IdentityProvider identity_providers = 2; } message GetGeneralSettingsRequest {} diff --git a/proto/zitadel/user/v2alpha/auth.proto b/proto/zitadel/user/v2beta/auth.proto similarity index 97% rename from proto/zitadel/user/v2alpha/auth.proto rename to proto/zitadel/user/v2beta/auth.proto index 92ac47b5f4..dd5a214063 100644 --- a/proto/zitadel/user/v2alpha/auth.proto +++ b/proto/zitadel/user/v2beta/auth.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; diff --git a/proto/zitadel/user/v2alpha/email.proto b/proto/zitadel/user/v2beta/email.proto similarity index 97% rename from proto/zitadel/user/v2alpha/email.proto rename to proto/zitadel/user/v2beta/email.proto index 3022ffc2a6..6e0c3ada0b 100644 --- a/proto/zitadel/user/v2alpha/email.proto +++ b/proto/zitadel/user/v2beta/email.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; diff --git a/proto/zitadel/user/v2alpha/idp.proto b/proto/zitadel/user/v2beta/idp.proto similarity index 99% rename from proto/zitadel/user/v2alpha/idp.proto rename to proto/zitadel/user/v2beta/idp.proto index 2ced1ebb4c..c8b5c27ae6 100644 --- a/proto/zitadel/user/v2alpha/idp.proto +++ b/proto/zitadel/user/v2beta/idp.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; import "google/api/field_behavior.proto"; import "google/protobuf/struct.proto"; diff --git a/proto/zitadel/user/v2alpha/password.proto b/proto/zitadel/user/v2beta/password.proto similarity index 97% rename from proto/zitadel/user/v2alpha/password.proto rename to proto/zitadel/user/v2beta/password.proto index cb5415b12d..c019bde098 100644 --- a/proto/zitadel/user/v2alpha/password.proto +++ b/proto/zitadel/user/v2beta/password.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; diff --git a/proto/zitadel/user/v2alpha/phone.proto b/proto/zitadel/user/v2beta/phone.proto similarity index 94% rename from proto/zitadel/user/v2alpha/phone.proto rename to proto/zitadel/user/v2beta/phone.proto index 775bb87300..75bb80c4b2 100644 --- a/proto/zitadel/user/v2alpha/phone.proto +++ b/proto/zitadel/user/v2beta/phone.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; diff --git a/proto/zitadel/user/v2alpha/user.proto b/proto/zitadel/user/v2beta/user.proto similarity index 96% rename from proto/zitadel/user/v2alpha/user.proto rename to proto/zitadel/user/v2beta/user.proto index e82f3f968e..ab1b5c5241 100644 --- a/proto/zitadel/user/v2alpha/user.proto +++ b/proto/zitadel/user/v2beta/user.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; import "google/api/field_behavior.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; @@ -59,7 +59,7 @@ message SetHumanProfile { example: "\"en\""; } ]; - optional zitadel.user.v2alpha.Gender gender = 6 [ + optional zitadel.user.v2beta.Gender gender = 6 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"GENDER_FEMALE\""; } diff --git a/proto/zitadel/user/v2alpha/user_service.proto b/proto/zitadel/user/v2beta/user_service.proto similarity index 93% rename from proto/zitadel/user/v2alpha/user_service.proto rename to proto/zitadel/user/v2beta/user_service.proto index 4168251712..47f491f2d0 100644 --- a/proto/zitadel/user/v2alpha/user_service.proto +++ b/proto/zitadel/user/v2beta/user_service.proto @@ -1,15 +1,15 @@ syntax = "proto3"; -package zitadel.user.v2alpha; +package zitadel.user.v2beta; -import "zitadel/object/v2alpha/object.proto"; +import "zitadel/object/v2beta/object.proto"; import "zitadel/protoc_gen_zitadel/v2/options.proto"; -import "zitadel/user/v2alpha/auth.proto"; -import "zitadel/user/v2alpha/email.proto"; -import "zitadel/user/v2alpha/phone.proto"; -import "zitadel/user/v2alpha/idp.proto"; -import "zitadel/user/v2alpha/password.proto"; -import "zitadel/user/v2alpha/user.proto"; +import "zitadel/user/v2beta/auth.proto"; +import "zitadel/user/v2beta/email.proto"; +import "zitadel/user/v2beta/phone.proto"; +import "zitadel/user/v2beta/idp.proto"; +import "zitadel/user/v2beta/password.proto"; +import "zitadel/user/v2beta/user.proto"; import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "google/protobuf/duration.proto"; @@ -17,13 +17,13 @@ import "google/protobuf/struct.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; -option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha;user"; +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v2beta;user"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title: "User Service"; - version: "2.0-alpha"; - description: "This API is intended to manage users in a ZITADEL instance. This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login."; + version: "2.0-beta"; + description: "This API is intended to manage users in a ZITADEL instance. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login."; contact:{ name: "ZITADEL" url: "https://zitadel.com" @@ -112,7 +112,7 @@ service UserService { // Create a new human user rpc AddHumanUser (AddHumanUserRequest) returns (AddHumanUserResponse) { option (google.api.http) = { - post: "/v2alpha/users/human" + post: "/v2beta/users/human" body: "*" }; @@ -141,7 +141,7 @@ service UserService { // Change the email of a user rpc SetEmail (SetEmailRequest) returns (SetEmailResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/email" + post: "/v2beta/users/{user_id}/email" body: "*" }; @@ -166,7 +166,7 @@ service UserService { // Verify the email with the provided code rpc VerifyEmail (VerifyEmailRequest) returns (VerifyEmailResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/email/verify" + post: "/v2beta/users/{user_id}/email/verify" body: "*" }; @@ -191,7 +191,7 @@ service UserService { // Change the phone of a user rpc SetPhone(SetPhoneRequest) returns (SetPhoneResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/phone" + post: "/v2beta/users/{user_id}/phone" body: "*" }; @@ -202,8 +202,8 @@ service UserService { }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { - summary: "Change the user phone"; - description: "Change the phone number of a user. If the state is set to not verified, a verification code will be generated, which can be either returned or sent to the user by sms." + summary: "Set the user phone"; + description: "Set the phone number of a user. If the state is set to not verified, a verification code will be generated, which can be either returned or sent to the user by sms." responses: { key: "200" value: { @@ -216,7 +216,7 @@ service UserService { // Verify the phone with the provided code rpc VerifyPhone (VerifyPhoneRequest) returns (VerifyPhoneResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/phone/verify" + post: "/v2beta/users/{user_id}/phone/verify" body: "*" }; @@ -240,7 +240,7 @@ service UserService { rpc RegisterPasskey (RegisterPasskeyRequest) returns (RegisterPasskeyResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/passkeys" + post: "/v2beta/users/{user_id}/passkeys" body: "*" }; @@ -262,7 +262,7 @@ service UserService { } rpc VerifyPasskeyRegistration (VerifyPasskeyRegistrationRequest) returns (VerifyPasskeyRegistrationResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/passkeys/{passkey_id}" + post: "/v2beta/users/{user_id}/passkeys/{passkey_id}" body: "*" }; @@ -284,7 +284,7 @@ service UserService { } rpc CreatePasskeyRegistrationLink (CreatePasskeyRegistrationLinkRequest) returns (CreatePasskeyRegistrationLinkResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/passkeys/registration_link" + post: "/v2beta/users/{user_id}/passkeys/registration_link" body: "*" }; @@ -307,7 +307,7 @@ service UserService { rpc RegisterU2F (RegisterU2FRequest) returns (RegisterU2FResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/u2f" + post: "/v2beta/users/{user_id}/u2f" body: "*" }; @@ -330,7 +330,7 @@ service UserService { rpc VerifyU2FRegistration (VerifyU2FRegistrationRequest) returns (VerifyU2FRegistrationResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/u2f/{u2f_id}" + post: "/v2beta/users/{user_id}/u2f/{u2f_id}" body: "*" }; @@ -353,7 +353,7 @@ service UserService { rpc RegisterTOTP (RegisterTOTPRequest) returns (RegisterTOTPResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/totp" + post: "/v2beta/users/{user_id}/totp" body: "*" }; @@ -376,7 +376,7 @@ service UserService { rpc VerifyTOTPRegistration (VerifyTOTPRegistrationRequest) returns (VerifyTOTPRegistrationResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/totp/verify" + post: "/v2beta/users/{user_id}/totp/verify" body: "*" }; @@ -399,7 +399,7 @@ service UserService { rpc AddOTPSMS (AddOTPSMSRequest) returns (AddOTPSMSResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/otp_sms" + post: "/v2beta/users/{user_id}/otp_sms" body: "*" }; @@ -422,7 +422,7 @@ service UserService { rpc RemoveOTPSMS (RemoveOTPSMSRequest) returns (RemoveOTPSMSResponse) { option (google.api.http) = { - delete: "/v2alpha/users/{user_id}/otp_sms" + delete: "/v2beta/users/{user_id}/otp_sms" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -444,7 +444,7 @@ service UserService { rpc AddOTPEmail (AddOTPEmailRequest) returns (AddOTPEmailResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/otp_email" + post: "/v2beta/users/{user_id}/otp_email" body: "*" }; @@ -467,7 +467,7 @@ service UserService { rpc RemoveOTPEmail (RemoveOTPEmailRequest) returns (RemoveOTPEmailResponse) { option (google.api.http) = { - delete: "/v2alpha/users/{user_id}/otp_email" + delete: "/v2beta/users/{user_id}/otp_email" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -490,7 +490,7 @@ service UserService { // Start an IDP authentication (for external login, registration or linking) rpc StartIdentityProviderIntent (StartIdentityProviderIntentRequest) returns (StartIdentityProviderIntentResponse) { option (google.api.http) = { - post: "/v2alpha/idp_intents" + post: "/v2beta/idp_intents" body: "*" }; @@ -514,7 +514,7 @@ service UserService { rpc RetrieveIdentityProviderIntent (RetrieveIdentityProviderIntentRequest) returns (RetrieveIdentityProviderIntentResponse) { option (google.api.http) = { - post: "/v2alpha/idp_intents/{idp_intent_id}" + post: "/v2beta/idp_intents/{idp_intent_id}" body: "*" }; @@ -539,7 +539,7 @@ service UserService { // Link an IDP to an existing user rpc AddIDPLink (AddIDPLinkRequest) returns (AddIDPLinkResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/links" + post: "/v2beta/users/{user_id}/links" body: "*" }; @@ -564,7 +564,7 @@ service UserService { // Request password reset rpc PasswordReset (PasswordResetRequest) returns (PasswordResetResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/password_reset" + post: "/v2beta/users/{user_id}/password_reset" body: "*" }; @@ -589,7 +589,7 @@ service UserService { // Change password rpc SetPassword (SetPasswordRequest) returns (SetPasswordResponse) { option (google.api.http) = { - post: "/v2alpha/users/{user_id}/password" + post: "/v2beta/users/{user_id}/password" body: "*" }; @@ -614,7 +614,7 @@ service UserService { // List all possible authentication methods of a user rpc ListAuthenticationMethodTypes (ListAuthenticationMethodTypesRequest) returns (ListAuthenticationMethodTypesResponse) { option (google.api.http) = { - get: "/v2alpha/users/{user_id}/authentication_methods" + get: "/v2beta/users/{user_id}/authentication_methods" }; option (zitadel.protoc_gen_zitadel.v2.options) = { @@ -655,7 +655,7 @@ message AddHumanUserRequest{ example: "\"minnie-mouse\""; } ]; - zitadel.object.v2alpha.Organisation organisation = 3; + zitadel.object.v2beta.Organisation organisation = 3; SetHumanProfile profile = 4 [ (validate.rules).message.required = true, (google.api.field_behavior) = REQUIRED @@ -675,7 +675,7 @@ message AddHumanUserRequest{ message AddHumanUserResponse { string user_id = 1; - zitadel.object.v2alpha.Details details = 2; + zitadel.object.v2beta.Details details = 2; optional string email_code = 3; optional string phone_code = 4; } @@ -708,7 +708,7 @@ message SetEmailRequest{ } message SetEmailResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; // in case the verification was set to return_code, the code will be returned optional string verification_code = 2; } @@ -736,7 +736,7 @@ message VerifyEmailRequest{ } message VerifyEmailResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message SetPhoneRequest{ @@ -767,7 +767,7 @@ message SetPhoneRequest{ } message SetPhoneResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; // in case the verification was set to return_code, the code will be returned optional string verification_code = 2; } @@ -795,7 +795,7 @@ message VerifyPhoneRequest{ } message VerifyPhoneResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message RegisterPasskeyRequest{ @@ -826,7 +826,7 @@ message RegisterPasskeyRequest{ } message RegisterPasskeyResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string passkey_id = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"163840776835432705\"" @@ -881,7 +881,7 @@ message VerifyPasskeyRegistrationRequest{ } message VerifyPasskeyRegistrationResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message RegisterU2FRequest{ @@ -902,7 +902,7 @@ message RegisterU2FRequest{ } message RegisterU2FResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string u2f_id = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"163840776835432705\"" @@ -957,7 +957,7 @@ message VerifyU2FRegistrationRequest{ } message VerifyU2FRegistrationResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message RegisterTOTPRequest { @@ -973,7 +973,7 @@ message RegisterTOTPRequest { } message RegisterTOTPResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; string uri = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"otpauth://totp/ZITADEL:gigi@acme.zitadel.cloud?algorithm=SHA1&digits=6&issuer=ZITADEL&period=30&secret=TJOPWSDYILLHXFV4MLKNNJOWFG7VSDCK\""; @@ -1007,7 +1007,7 @@ message VerifyTOTPRegistrationRequest { } message VerifyTOTPRegistrationResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message AddOTPSMSRequest { @@ -1023,7 +1023,7 @@ message AddOTPSMSRequest { } message AddOTPSMSResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message RemoveOTPSMSRequest { @@ -1039,7 +1039,7 @@ message RemoveOTPSMSRequest { } message RemoveOTPSMSResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message AddOTPEmailRequest { @@ -1055,7 +1055,7 @@ message AddOTPEmailRequest { } message AddOTPEmailResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message RemoveOTPEmailRequest { @@ -1071,7 +1071,7 @@ message RemoveOTPEmailRequest { } message RemoveOTPEmailResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message CreatePasskeyRegistrationLinkRequest{ @@ -1092,7 +1092,7 @@ message CreatePasskeyRegistrationLinkRequest{ } message CreatePasskeyRegistrationLinkResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; // in case the medium was set to return_code, the code will be returned optional PasskeyRegistrationCode code = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -1119,7 +1119,7 @@ message StartIdentityProviderIntentRequest{ } message StartIdentityProviderIntentResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; oneof next_step { string auth_url = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -1157,7 +1157,7 @@ message RetrieveIdentityProviderIntentRequest{ } message RetrieveIdentityProviderIntentResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; IDPInformation idp_information = 2; } @@ -1175,7 +1175,7 @@ message AddIDPLinkRequest{ } message AddIDPLinkResponse { - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } @@ -1197,7 +1197,7 @@ message PasswordResetRequest{ } message PasswordResetResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; // in case the medium was set to return_code, the code will be returned optional string verification_code = 2; } @@ -1239,7 +1239,7 @@ message SetPasswordRequest{ } message SetPasswordResponse{ - zitadel.object.v2alpha.Details details = 1; + zitadel.object.v2beta.Details details = 1; } message ListAuthenticationMethodTypesRequest{ @@ -1255,7 +1255,7 @@ message ListAuthenticationMethodTypesRequest{ } message ListAuthenticationMethodTypesResponse{ - zitadel.object.v2alpha.ListDetails details = 1; + zitadel.object.v2beta.ListDetails details = 1; repeated AuthenticationMethodType auth_method_types = 2; } diff --git a/release-channels.yaml b/release-channels.yaml index 4ab97932e9..31ac38ef9c 100644 --- a/release-channels.yaml +++ b/release-channels.yaml @@ -1 +1 @@ -stable: "v2.21.4" +stable: "v2.35.1"