Merge branch 'main' into next

This commit is contained in:
Livio Spring 2023-09-15 15:46:06 +02:00
commit b688d6f842
No known key found for this signature in database
GPG Key ID: 26BB1C2FA5952CF0
240 changed files with 2182 additions and 1678 deletions

View File

@ -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"

View File

@ -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

View File

@ -21,8 +21,8 @@
<img src="https://codecov.io/gh/zitadel/zitadel/branch/main/graph/badge.svg" /></a>
<a href="https://github.com/zitadel/zitadel/graphs/contributors" alt="Release">
<img alt="GitHub contributors" src="https://img.shields.io/github/contributors/zitadel/zitadel"></a>
<a href="https://discord.gg/erh5Brh7jE" alt="Discord Chat">
<img src="https://badgen.net/discord/online-members/erh5Brh7jE" /></a>
<a href="https://discord.gg/YgjEuJzZ3x" alt="Discord Chat">
<img src="https://badgen.net/discord/online-members/YgjEuJzZ3x" /></a>
</p>
<p align="center">

View File

@ -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"

View File

@ -31,14 +31,9 @@
<div class="col">
<span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span>
<span class="loginname">{{ session.loginName }}</span>
<span
class="state"
[ngClass]="{
active: session.authState === UserState.USER_STATE_ACTIVE,
inactive: session.authState === UserState.USER_STATE_INACTIVE
}"
>{{ 'USER.STATE.' + session.authState | translate }}</span
>
<span class="state inactive" *ngIf="session.authState === UserState.USER_STATE_INACTIVE">{{
'USER.STATE.' + session.authState | translate
}}</span>
</div>
<mat-icon>keyboard_arrow_right</mat-icon>
</a>

View File

@ -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<void> = new Subject();
private showAllowedToFailWarning: boolean = true;
public form: FormGroup = new FormGroup({
name: new FormControl<string>('', []),
script: new FormControl<string>('', []),
durationInSec: new FormControl<number>(10, []),
allowedToFail: new FormControl<boolean>(false, []),
allowedToFail: new FormControl<boolean>(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: {

View File

@ -170,7 +170,7 @@
<div class="content">
<cnsl-form-field class="formfield">
<cnsl-label>{{ 'ORG_DETAIL.DETAIL.NAME' | translate }}</cnsl-label>
<input cnslInput formControlName="name" />
<input cnslInput formControlName="name" data-e2e="org-name-input" />
</cnsl-form-field>
</div>
@ -182,6 +182,7 @@
class="big-button"
cdkFocusInitial
type="submit"
data-e2e="create-org-button"
>
{{ 'ACTIONS.CREATE' | translate }}
</button>

View File

@ -427,6 +427,7 @@
<div class="app-info-row">
<div class="app-info-wrapper" *ngFor="let wellKnownV of wellKnownMap$ | async | keyvalue">
<ng-container *ngIf="wellKnownV.key.endsWith('endpoint')">
<p class="app-info-row-title cnsl-secondary-text">{{ wellKnownV.key }}</p>
<div class="app-copy-row">
<div *ngIf="wellKnownV.value" class="environment">
@ -440,7 +441,8 @@
{{ wellKnownV.value }}
</button>
</div>
</div>
</div></ng-container
>
</div>
</div>
</cnsl-card>

View File

@ -60,6 +60,7 @@ export class ProjectListComponent implements OnInit, OnDestroy {
public ProjectState: any = ProjectState;
public ProjectType: any = ProjectType;
private destroy$: Subject<void> = 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);
});
}

View File

@ -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;

View File

@ -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": "Мениджъри на организации",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "組織マネージャー",

View File

@ -743,6 +743,10 @@
"TIMEOUT": "Временски лимит",
"TIMEOUTINSEC": "Временски лимит во секунди",
"ALLOWEDTOFAIL": "Дозволено да не успее",
"ALLOWEDTOFAILWARN": {
"TITLE": "Предупредување",
"DESCRIPTION": "Ако ја деактивирате оваа поставка, тоа може да доведе до тоа што корисниците на вашата организација нема да можат да се најават. Покрај тоа, нема да можете повеќе да пристапите до конзолата за да ја деактивирате акцијата. Препорачуваме да создадете администраторски корисник во посебна организација или да ги тестирате скриптите прво во развојна средина или развојна организација."
},
"SCRIPT": "Скрипта",
"FLOWTYPE": "Тип на Flow",
"TRIGGERTYPE": "Тип на тригер",

View File

@ -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",

View File

@ -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",

View File

@ -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": "组织管理者",

View File

@ -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

View File

@ -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).
:::
<ApiCard title="Authentication" type="AUTH">
<Column>
<div>
## 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.
</div>
<div className="apicard-right">
### 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:
<div>
## 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
</div>
<div className="apicard-right">
### 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:
<Column>
<div>
## Administration
### Administration
This API is intended to configure and manage one ZITADEL instance itself.
</div>
<div className="apicard-right">
### 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:
<Column>
<div>
## 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
</div>
<div className="apicard-right">
### 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:
<Column>
<div>
## 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.
</div>
<div>
### REST
#### REST
Endpoint:
$ZITADEL_DOMAIN/assets/v1/
@ -177,11 +211,36 @@ Definition:
</Column>
</ApiCard>
## 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/
```

View File

@ -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)

View File

@ -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.
## ZITADEL SDKs
| 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 an SDK
## 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.

View File

@ -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:
<li><b>Name</b> {props.name}</li>
<li><b>Issuer</b> {props.issuer}</li>
<li><b>Client-ID</b> {props.clientid}</li>
<li><b>Scopes</b>: (openid, profile, email is preconfigured)</li>

View File

@ -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';
<Intro provider="Apple"/>
## 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
<CustomLoginPolicy/>
### Go to the IdP Providers Overview
<IDPsOverview templates="Apple"/>
### 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.
<GeneralConfigDescription provider_account="Apple account" />
![Apple Provider](/img/guides/zitadel_apple_create_provider.png)
### Activate IdP
<Activate/>
![Activate the Apple Provider](/img/guides/zitadel_activate_apple.png)
## Test the setup
<TestSetup loginscreen="your Apple login"/>
![Apple Button](/img/guides/zitadel_login_apple.png)
![Apple Login](/img/guides/apple_login.png)

View File

@ -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)

View File

@ -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: <https://console.cloud.google.com/apis/credentials>
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.

View File

@ -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';
<Intro provider="OKTA"/>
## OKTA Configuration
### Register a new client
1. Login to your OKTA Account and go to the applications list: <OKTA-DOMAIN/admin/apps/active>
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
<CustomLoginPolicy/>
### Go to the IdP Providers Overview
<IDPsOverview templates="Generic OIDC"/>
### Create a new Generic OIDC Provider
<GenericOIDC
name=": e.g. OKTA"
issuer=": The domain of your OKTA account, Example: https://trial-1925566.okta.com"
clientid=": Client id from the application previously created in your OKTA account"
/>
<GeneralConfigDescription provider_account="OKTA account" />
![OKTA Provider](/img/guides/zitadel_okta_create_provider.png)
### Activate IdP
<Activate/>
![Activate the OKTA Provider](/img/guides/zitadel_activate_okta.png)
## Test the setup
<TestSetup loginscreen="your OKTA login"/>
<!-- TODO: Image highlights GitHub -->
![OKTA Button](/img/guides/zitadel_login_okta.png)
![OKTA Login](/img/guides/okta_login.png)

View File

@ -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".

View File

@ -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"''
```

View File

@ -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' \

View File

@ -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' \

View File

@ -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": {}
}
}
}'
```

View File

@ -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' \

View File

@ -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
<MfaOptions/>
### 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
<MfaOptions/>
### 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
<BrowserSigninWebAuthN/>
### Update Session with WebAuthN
<UpdateSessionWebAuthN/>

View File

@ -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: <userid>``` 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' \

View File

@ -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.
<BrowserSigninWebAuthN/>
```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
<UpdateSessionWebAuthN/>

View File

@ -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' \

View File

@ -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' \

View File

@ -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
<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="${ENTITYID}">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol">
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="${ACSURL}" index="0"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
```
Set or replace the variables with the values from the next screen as follows:
- `${ENTITYID}`: google.com/a/<your_domain>
- `${ACSURL}`: https://www.google.com/a/<your_domain>/acs
`<your_domain>` 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/<your_domain>
- Enter your username and credentials
- You should be redirected to Gmail and logged in
`<your_domain>` 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
<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="${ENTITYID}">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol">
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="${ACSURL}" index="0"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
```
Set or replace the variables with the values from the next screen as follows:
- `${ENTITYID}`: https://accounts.google.com/samlrp/metadata?rpid=<your_value>
- `${ACSURL}`: https://accounts.google.com/samlrp/acs?rpid=<your_value>
Replace `<your_value>` 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/<your_domain>
- Enter your username and credentials
- You should be redirected to Gmail and logged in
`<your_domain>` 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.

View File

@ -4,29 +4,60 @@ title: Quick start guide
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.
## ZITADEL terminology: instances, organizations, projects, users, roles, authorizations and apps
In ZITADEL, instances, organizations, projects, users, roles, and apps are the main components that make up the platform.
The order of creation for the above components would typically be as follows:
<ul>
<li><b>Instance</b>: 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.</li>
<li><b>Organization</b>: 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.</li>
<li><b>Project</b>: A project is a logical separation within an organization and is a container for apps, roles and authorization policies for the resources it contains.</li>
<li><b>Users</b>: 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.</li>
<li><b>Roles</b>: Roles are the sets of permissions and privileges that are assigned to users within a project.</li>
<li><b>Authorizations</b>: 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.</li>
<li><b>Apps</b>: 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.</li>
<li>
<b>Instance</b>: 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.
</li>
<li>
<b>Organization</b>: 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.
</li>
<li>
<b>Project</b>: A project is a logical separation within an organization and
is a container for apps, roles and authorization policies for the resources
it contains.
</li>
<li>
<b>Users</b>: 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.
</li>
<li>
<b>Roles</b>: Roles are the sets of permissions and privileges that are
assigned to users within a project.
</li>
<li>
<b>Authorizations</b>: 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.
</li>
<li>
<b>Apps</b>: 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.
</li>
</ul>
The order of creation for the above components may vary depending on the specific needs and requirements of the organization.
@ -242,6 +273,7 @@ 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.
@ -272,7 +304,7 @@ And with that, configuring ZITADEL for our application is complete. Now we can m
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.
***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,18 +314,19 @@ 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.
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:
@ -301,8 +334,7 @@ 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
@ -377,12 +409,12 @@ 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.
@ -417,7 +449,8 @@ 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.
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.
@ -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,7 +525,7 @@ 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.
@ -500,14 +547,15 @@ 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). ***Dont 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). ***Dont 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). **_Dont 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). **_Dont 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). ***Dont 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). **_Dont 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).
@ -556,8 +604,7 @@ In the PKCE flow, the code verifier is a random string generated by the client a
}
```
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)
@ -583,8 +630,8 @@ 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.
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)
@ -613,10 +660,8 @@ reportWebVitals();
![Redirect](/img/guides/quickstart/login6.png)
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.
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!

View File

@ -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

View File

@ -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

View File

@ -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.
:::

View File

@ -8,7 +8,6 @@ These advisories may include details about the nature of the issue, its potentia
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.
<table>
<tr>
<th>Advisory</th>
@ -19,20 +18,56 @@ We understand that these advisories may include breaking changes, and we aim to
<th>Date</th>
</tr>
<tr>
<td><a href="./advisory/a10000">A-10000</a></td>
<td>
<a href="./advisory/a10000">A-10000</a>
</td>
<td>Reusing user session</td>
<td>Breaking Behaviour Change</td>
<td>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.</td>
<td>
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.
</td>
<td>2.32.0</td>
<td>Calendar week 32</td>
</tr>
<tr>
<td><a href="./advisory/a10001">A-10001</a></td>
<td>
<a href="./advisory/a10001">A-10001</a>
</td>
<td>Login Policy - Allow Register</td>
<td>Breaking Behaviour Change</td>
<td>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.</td>
<td>
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.
</td>
<td>2.35.0</td>
<td>Calendar week 34</td>
</tr>
<tr>
<td>
<a href="./advisory/a10002">A-10002</a>
</td>
<td>Console - Branding</td>
<td>Breaking Design Change</td>
<td>
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.
</td>
<td>TBD</td>
<td>Calendar week 34/35</td>
<td>Calendar week 40/41</td>
</tr>
</table>
@ -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.

View File

@ -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:

View File

@ -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",

View File

@ -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"),
},

BIN
docs/static/img/guides/apple_login.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

BIN
docs/static/img/guides/okta_add_app.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

BIN
docs/static/img/guides/okta_login.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 KiB

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

View File

@ -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<Context>('@ctx').then((ctx) => {

View File

@ -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)

View File

@ -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 {

View File

@ -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) {

View File

@ -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 (

View File

@ -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) {

View File

@ -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)

View File

@ -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:

View File

@ -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 (

View File

@ -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) {

View File

@ -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
}

View File

@ -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)

View File

@ -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) {

View File

@ -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 (

View File

@ -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) {

View File

@ -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)

View File

@ -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) {

View File

@ -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 {

View File

@ -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"}

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

Some files were not shown because too many files have changed in this diff Show More