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}", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": { "features": {
"ghcr.io/devcontainers/features/go:1": { "ghcr.io/devcontainers/features/go:1": {
"version": "1.20" "version": "1.21"
}, },
"ghcr.io/devcontainers/features/node:1": { "ghcr.io/devcontainers/features/node:1": {
"version": "18" "version": "18"

View File

@ -3,7 +3,7 @@ gen_authopt_path := "$(go_bin)/protoc-gen-authoption"
gen_zitadel_path := "$(go_bin)/protoc-gen-zitadel" gen_zitadel_path := "$(go_bin)/protoc-gen-zitadel"
now := $(shell date --rfc-3339=seconds | sed 's/ /T/') now := $(shell date --rfc-3339=seconds | sed 's/ /T/')
VERSION ?= development VERSION ?= development-$(now)
COMMIT_SHA ?= $(shell git rev-parse HEAD) COMMIT_SHA ?= $(shell git rev-parse HEAD)
.PHONY: compile .PHONY: compile

View File

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

View File

@ -415,7 +415,7 @@ SystemDefaults:
# https://passlib.readthedocs.io/en/stable/modular_crypt_format.html # https://passlib.readthedocs.io/en/stable/modular_crypt_format.html
# #
# Supported verifiers: (uncomment to enable) # Supported verifiers: (uncomment to enable)
# Verifiers: Verifiers:
# - "argon2" # verifier for both argon2i and argon2id. # - "argon2" # verifier for both argon2i and argon2id.
# - "bcrypt" # - "bcrypt"
# - "md5" # - "md5"

View File

@ -31,14 +31,9 @@
<div class="col"> <div class="col">
<span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span> <span class="user-title">{{ session.displayName ? session.displayName : session.userName }} </span>
<span class="loginname">{{ session.loginName }}</span> <span class="loginname">{{ session.loginName }}</span>
<span <span class="state inactive" *ngIf="session.authState === UserState.USER_STATE_INACTIVE">{{
class="state" 'USER.STATE.' + session.authState | translate
[ngClass]="{ }}</span>
active: session.authState === UserState.USER_STATE_ACTIVE,
inactive: session.authState === UserState.USER_STATE_INACTIVE
}"
>{{ 'USER.STATE.' + session.authState | translate }}</span
>
</div> </div>
<mat-icon>keyboard_arrow_right</mat-icon> <mat-icon>keyboard_arrow_right</mat-icon>
</a> </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 { FormControl, FormGroup } from '@angular/forms';
import { import {
MatLegacyDialog as MatDialog, MatLegacyDialog as MatDialog,
@ -7,7 +7,7 @@ import {
} from '@angular/material/legacy-dialog'; } from '@angular/material/legacy-dialog';
import { Duration } from 'google-protobuf/google/protobuf/duration_pb'; 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 { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
import { Action } from 'src/app/proto/generated/zitadel/action_pb'; import { Action } from 'src/app/proto/generated/zitadel/action_pb';
import { CreateActionRequest, UpdateActionRequest } from 'src/app/proto/generated/zitadel/management_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', templateUrl: './add-action-dialog.component.html',
styleUrls: ['./add-action-dialog.component.scss'], styleUrls: ['./add-action-dialog.component.scss'],
}) })
export class AddActionDialogComponent implements OnInit { export class AddActionDialogComponent implements OnInit, OnDestroy {
public id: string = ''; public id: string = '';
public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true)); public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true));
private destroy$: Subject<void> = new Subject();
private showAllowedToFailWarning: boolean = true;
public form: FormGroup = new FormGroup({ public form: FormGroup = new FormGroup({
name: new FormControl<string>('', []), name: new FormControl<string>('', []),
script: new FormControl<string>('', []), script: new FormControl<string>('', []),
durationInSec: new FormControl<number>(10, []), durationInSec: new FormControl<number>(10, []),
allowedToFail: new FormControl<boolean>(false, []), allowedToFail: new FormControl<boolean>(true, []),
}); });
constructor( constructor(
private toast: ToastService, private toast: ToastService,
@ -47,6 +50,21 @@ export class AddActionDialogComponent implements OnInit {
}); });
this.id = action.id; 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 { ngOnInit(): void {
@ -71,6 +89,11 @@ export class AddActionDialogComponent implements OnInit {
}); });
} }
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
private showUnsavedDialog(): void { private showUnsavedDialog(): void {
const unsavedChangesDialogRef = this.unsavedChangesDialog.open(WarnDialogComponent, { const unsavedChangesDialogRef = this.unsavedChangesDialog.open(WarnDialogComponent, {
data: { data: {

View File

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

View File

@ -427,20 +427,22 @@
<div class="app-info-row"> <div class="app-info-row">
<div class="app-info-wrapper" *ngFor="let wellKnownV of wellKnownMap$ | async | keyvalue"> <div class="app-info-wrapper" *ngFor="let wellKnownV of wellKnownMap$ | async | keyvalue">
<p class="app-info-row-title cnsl-secondary-text">{{ wellKnownV.key }}</p> <ng-container *ngIf="wellKnownV.key.endsWith('endpoint')">
<div class="app-copy-row"> <p class="app-info-row-title cnsl-secondary-text">{{ wellKnownV.key }}</p>
<div *ngIf="wellKnownV.value" class="environment"> <div class="app-copy-row">
<button <div *ngIf="wellKnownV.value" class="environment">
[disabled]="copied === wellKnownV.value" <button
[matTooltip]="(copied !== wellKnownV.value ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate" [disabled]="copied === wellKnownV.value"
cnslCopyToClipboard [matTooltip]="(copied !== wellKnownV.value ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
[valueToCopy]="wellKnownV.value" cnslCopyToClipboard
(copiedValue)="copied = wellKnownV.key" [valueToCopy]="wellKnownV.value"
> (copiedValue)="copied = wellKnownV.key"
{{ wellKnownV.value }} >
</button> {{ wellKnownV.value }}
</div> </button>
</div> </div>
</div></ng-container
>
</div> </div>
</div> </div>
</cnsl-card> </cnsl-card>

View File

@ -60,6 +60,7 @@ export class ProjectListComponent implements OnInit, OnDestroy {
public ProjectState: any = ProjectState; public ProjectState: any = ProjectState;
public ProjectType: any = ProjectType; public ProjectType: any = ProjectType;
private destroy$: Subject<void> = new Subject(); private destroy$: Subject<void> = new Subject();
public INITIAL_PAGE_SIZE: number = 20;
constructor( constructor(
public translate: TranslateService, public translate: TranslateService,
@ -84,7 +85,7 @@ export class ProjectListComponent implements OnInit, OnDestroy {
break; break;
} }
this.getData(type); this.getData(type, this.INITIAL_PAGE_SIZE, 0);
}); });
} }

View File

@ -28,7 +28,7 @@ interface WellKnown {
}) })
export class EnvironmentService { export class EnvironmentService {
private environmentJsonPath = './assets/environment.json'; private environmentJsonPath = './assets/environment.json';
private wellknownPath = '/.well-known/openid-configuration`'; private wellknownPath = '/.well-known/openid-configuration';
public auth!: AuthServiceClient; public auth!: AuthServiceClient;
public mgmt!: ManagementServiceClient; public mgmt!: ManagementServiceClient;
public admin!: AdminServiceClient; public admin!: AdminServiceClient;

View File

@ -736,6 +736,10 @@
"TIMEOUT": "Време за изчакване", "TIMEOUT": "Време за изчакване",
"TIMEOUTINSEC": "Изчакване в секунди", "TIMEOUTINSEC": "Изчакване в секунди",
"ALLOWEDTOFAIL": "Разрешено да се провали", "ALLOWEDTOFAIL": "Разрешено да се провали",
"ALLOWEDTOFAILWARN": {
"TITLE": "Предупреждение",
"DESCRIPTION": "Ако деактивирате тази настройка, това може да доведе до това, че потребителите на вашата организация няма да могат да се регистрират. Освен това няма да можете да получите достъп до конзолата, за да деактивирате действието. Препоръчваме ви да създадете администраторски потребител в отделна организация или да тествате скриптове първо в среда за разработка или тестова организация."
},
"SCRIPT": "Скрипт", "SCRIPT": "Скрипт",
"FLOWTYPE": "Тип поток", "FLOWTYPE": "Тип поток",
"TRIGGERTYPE": "Тип тригер", "TRIGGERTYPE": "Тип тригер",
@ -957,8 +961,7 @@
"STATE": { "STATE": {
"0": "Не е дефинирано", "0": "Не е дефинирано",
"1": "Активен", "1": "Активен",
"2": "Деактивиран", "2": "Деактивиран"
"3": "Премахнато"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Мениджъри на организации", "TITLE": "Мениджъри на организации",

View File

@ -742,6 +742,10 @@
"TIMEOUT": "Timeout", "TIMEOUT": "Timeout",
"TIMEOUTINSEC": "Timeout in Sekunden", "TIMEOUTINSEC": "Timeout in Sekunden",
"ALLOWEDTOFAIL": "Scheitern erlaubt", "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", "SCRIPT": "Script",
"FLOWTYPE": "Flow Typ", "FLOWTYPE": "Flow Typ",
"TRIGGERTYPE": "Trigger Typ", "TRIGGERTYPE": "Trigger Typ",
@ -963,8 +967,7 @@
"STATE": { "STATE": {
"0": "Nicht definiert", "0": "Nicht definiert",
"1": "Aktiv", "1": "Aktiv",
"2": "Inaktiv", "2": "Inaktiv"
"3": "Entfernt"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Manager der Organisation verwalten", "TITLE": "Manager der Organisation verwalten",

View File

@ -743,6 +743,10 @@
"TIMEOUT": "Timeout", "TIMEOUT": "Timeout",
"TIMEOUTINSEC": "Timeout in seconds", "TIMEOUTINSEC": "Timeout in seconds",
"ALLOWEDTOFAIL": "Allowed To Fail", "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", "SCRIPT": "Script",
"FLOWTYPE": "Flow Type", "FLOWTYPE": "Flow Type",
"TRIGGERTYPE": "Trigger Type", "TRIGGERTYPE": "Trigger Type",
@ -964,8 +968,7 @@
"STATE": { "STATE": {
"0": "Not defined", "0": "Not defined",
"1": "Active", "1": "Active",
"2": "Deactivated", "2": "Deactivated"
"3": "Removed"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Organization Managers", "TITLE": "Organization Managers",

View File

@ -743,6 +743,10 @@
"TIMEOUT": "Timeout", "TIMEOUT": "Timeout",
"TIMEOUTINSEC": "Timeout en segundos", "TIMEOUTINSEC": "Timeout en segundos",
"ALLOWEDTOFAIL": "Permitido el fallo", "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", "SCRIPT": "Script",
"FLOWTYPE": "Tipo de flujo", "FLOWTYPE": "Tipo de flujo",
"TRIGGERTYPE": "Tipo de disparador", "TRIGGERTYPE": "Tipo de disparador",
@ -964,8 +968,7 @@
"STATE": { "STATE": {
"0": "No definida", "0": "No definida",
"1": "Activa", "1": "Activa",
"2": "Desactivada", "2": "Desactivada"
"3": "Eliminada"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Mánagers de la organización", "TITLE": "Mánagers de la organización",

View File

@ -742,6 +742,10 @@
"TIMEOUT": "Délai d'attente", "TIMEOUT": "Délai d'attente",
"TIMEOUTINSEC": "Délai en secondes", "TIMEOUTINSEC": "Délai en secondes",
"ALLOWEDTOFAIL": "Autorisé à échouer", "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", "SCRIPT": "Script",
"FLOWTYPE": "Type de flux", "FLOWTYPE": "Type de flux",
"TRIGGERTYPE": "Type de déclencheur", "TRIGGERTYPE": "Type de déclencheur",
@ -963,8 +967,7 @@
"STATE": { "STATE": {
"0": "Non défini", "0": "Non défini",
"1": "Actif", "1": "Actif",
"2": "Désactivé", "2": "Désactivé"
"3": "Supprimé"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Gestionnaires de l'organisation", "TITLE": "Gestionnaires de l'organisation",

View File

@ -741,6 +741,10 @@
"TIMEOUT": "Timeout", "TIMEOUT": "Timeout",
"TIMEOUTINSEC": "Timeout in secondi", "TIMEOUTINSEC": "Timeout in secondi",
"ALLOWEDTOFAIL": "Può fallire", "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", "SCRIPT": "Script",
"FLOWTYPE": "Tipo processo", "FLOWTYPE": "Tipo processo",
"TRIGGERTYPE": "Tipo trigger", "TRIGGERTYPE": "Tipo trigger",
@ -963,8 +967,7 @@
"STATE": { "STATE": {
"0": "Non definito", "0": "Non definito",
"1": "Attivo", "1": "Attivo",
"2": "Disattivato", "2": "Disattivato"
"3": "Rimosso"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Manager dell'organizzazione", "TITLE": "Manager dell'organizzazione",

View File

@ -743,6 +743,10 @@
"TIMEOUT": "タイムアウト", "TIMEOUT": "タイムアウト",
"TIMEOUTINSEC": "数秒でタイムアウト", "TIMEOUTINSEC": "数秒でタイムアウト",
"ALLOWEDTOFAIL": "失敗を許可", "ALLOWEDTOFAIL": "失敗を許可",
"ALLOWEDTOFAILWARN": {
"TITLE": "警告",
"DESCRIPTION": "この設定を無効にすると、組織のユーザーがログインできなくなる可能性があります。さらに、アクションを無効にするためにコンソールにアクセスできなくなります。開発環境または開発組織でスクリプトを最初にテストするか、別の組織で管理者ユーザーを作成することをお勧めします。"
},
"SCRIPT": "スクリプトp", "SCRIPT": "スクリプトp",
"FLOWTYPE": "フロータイプ", "FLOWTYPE": "フロータイプ",
"TRIGGERTYPE": "トリガータイプ", "TRIGGERTYPE": "トリガータイプ",
@ -964,8 +968,7 @@
"STATE": { "STATE": {
"0": "未定義", "0": "未定義",
"1": "アクティブ", "1": "アクティブ",
"2": "非アクティブ", "2": "非アクティブ"
"3": "削除"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "組織マネージャー", "TITLE": "組織マネージャー",

View File

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

View File

@ -742,6 +742,10 @@
"TIMEOUT": "Timeout", "TIMEOUT": "Timeout",
"TIMEOUTINSEC": "Timeout w sekundach", "TIMEOUTINSEC": "Timeout w sekundach",
"ALLOWEDTOFAIL": "Dozwolone na porażkę", "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", "SCRIPT": "Skrypt",
"FLOWTYPE": "Typ Przepływu", "FLOWTYPE": "Typ Przepływu",
"TRIGGERTYPE": "Typ Wyzwalacza", "TRIGGERTYPE": "Typ Wyzwalacza",
@ -963,8 +967,7 @@
"STATE": { "STATE": {
"0": "Nieokreślone", "0": "Nieokreślone",
"1": "Aktywne", "1": "Aktywne",
"2": "Dezaktywowane", "2": "Dezaktywowane"
"3": "Usunięte"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "Menadżerowie organizacji", "TITLE": "Menadżerowie organizacji",

View File

@ -743,6 +743,10 @@
"TIMEOUT": "Tempo Limite", "TIMEOUT": "Tempo Limite",
"TIMEOUTINSEC": "Tempo Limite em segundos", "TIMEOUTINSEC": "Tempo Limite em segundos",
"ALLOWEDTOFAIL": "Permitido Falhar", "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", "SCRIPT": "Script",
"FLOWTYPE": "Tipo de Fluxo", "FLOWTYPE": "Tipo de Fluxo",
"TRIGGERTYPE": "Tipo de Gatilho", "TRIGGERTYPE": "Tipo de Gatilho",

View File

@ -742,6 +742,10 @@
"TIMEOUT": "超时时间", "TIMEOUT": "超时时间",
"TIMEOUTINSEC": "以秒为单位的超时时间", "TIMEOUTINSEC": "以秒为单位的超时时间",
"ALLOWEDTOFAIL": "允许失败", "ALLOWEDTOFAIL": "允许失败",
"ALLOWEDTOFAILWARN": {
"TITLE": "警告",
"DESCRIPTION": "如果您禁用此设置,可能会导致您的组织中的用户无法登录。此外,您将无法再访问控制台以禁用该操作。我们建议您在单独的组织中创建管理员用户,或在开发环境或开发组织中先测试脚本。"
},
"SCRIPT": "脚本", "SCRIPT": "脚本",
"FLOWTYPE": "流程类型", "FLOWTYPE": "流程类型",
"TRIGGERTYPE": "触发器类型", "TRIGGERTYPE": "触发器类型",
@ -963,8 +967,7 @@
"STATE": { "STATE": {
"0": "未定义", "0": "未定义",
"1": "启用", "1": "启用",
"2": "停用", "2": "停用"
"3": "移除"
}, },
"MEMBER": { "MEMBER": {
"TITLE": "组织管理者", "TITLE": "组织管理者",

View File

@ -43,10 +43,10 @@ title: Objects
## user grant ## user grant
- `projectId` *string* - `projectID` *string*
Required. Id of the project to be granted Required. Id of the project to be granted
- `projectGrantId` *string* - `projectGrantID` *string*
If the grant is for a project grant Optional. If the grant is for a project grant, include projectGrantID
- `roles` Array of *string* - `roles` Array of *string*
Containing the roles Containing the roles

View File

@ -6,38 +6,72 @@ sidebar_label: Overview
import { ApiCard } from "../../src/components/apicard"; import { ApiCard } from "../../src/components/apicard";
import Column from "../../src/components/column"; 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. 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).
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.
### 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"> <ApiCard title="Authentication" type="AUTH">
<Column> <Column>
<div> <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. 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>
<div className="apicard-right"> <div className="apicard-right">
### GRPC #### GRPC
Endpoint: Endpoint:
$ZITADEL_DOMAIN/zitadel.auth.v1.AuthService/ $ZITADEL_DOMAIN/zitadel.auth.v1.AuthService/
@ -45,7 +79,7 @@ $ZITADEL_DOMAIN/zitadel.auth.v1.AuthService/
Definition: Definition:
[Auth Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/auth.proto) [Auth Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/auth.proto)
### REST #### REST
Endpoint: Endpoint:
$ZITADEL_DOMAIN/auth/v1/ $ZITADEL_DOMAIN/auth/v1/
@ -62,7 +96,7 @@ API Reference:
<div> <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. 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. 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>
<div className="apicard-right"> <div className="apicard-right">
### GRPC #### GRPC
Endpoint: Endpoint:
$ZITADEL_DOMAIN/zitadel.management.v1.ManagementService/ $ZITADEL_DOMAIN/zitadel.management.v1.ManagementService/
@ -78,7 +112,7 @@ $ZITADEL_DOMAIN/zitadel.management.v1.ManagementService/
Definition: Definition:
[Management Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/management.proto) [Management Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/management.proto)
### REST #### REST
Endpoint: Endpoint:
$ZITADEL_DOMAIN/management/v1/ $ZITADEL_DOMAIN/management/v1/
@ -94,14 +128,14 @@ API Reference:
<Column> <Column>
<div> <div>
## Administration ### Administration
This API is intended to configure and manage one ZITADEL instance itself. This API is intended to configure and manage one ZITADEL instance itself.
</div> </div>
<div className="apicard-right"> <div className="apicard-right">
### GRPC #### GRPC
Endpoint: Endpoint:
$ZITADEL_DOMAIN/zitadel.admin.v1.AdminService/ $ZITADEL_DOMAIN/zitadel.admin.v1.AdminService/
@ -109,7 +143,7 @@ $ZITADEL_DOMAIN/zitadel.admin.v1.AdminService/
Definition: Definition:
[Admin Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/admin.proto) [Admin Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/admin.proto)
### REST #### REST
Endpoint: Endpoint:
$ZITADEL_DOMAIN/admin/v1/ $ZITADEL_DOMAIN/admin/v1/
@ -125,7 +159,7 @@ API Reference:
<Column> <Column>
<div> <div>
## System ### System
This API is intended to manage the different ZITADEL instances within the 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>
<div className="apicard-right"> <div className="apicard-right">
### GRPC #### GRPC
Endpoint: Endpoint:
$ZITADEL_DOMAIN/zitadel.system.v1.SystemService/ $ZITADEL_DOMAIN/zitadel.system.v1.SystemService/
@ -142,7 +176,7 @@ $ZITADEL_DOMAIN/zitadel.system.v1.SystemService/
Definition: Definition:
[System Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/system.proto) [System Proto](https://github.com/zitadel/zitadel/blob/main/proto/zitadel/system.proto)
### REST #### REST
Endpoint: Endpoint:
$ZITADEL_DOMAIN/system/v1/ $ZITADEL_DOMAIN/system/v1/
@ -158,14 +192,14 @@ API Reference:
<Column> <Column>
<div> <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. 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>
<div> <div>
### REST #### REST
Endpoint: Endpoint:
$ZITADEL_DOMAIN/assets/v1/ $ZITADEL_DOMAIN/assets/v1/
@ -177,11 +211,36 @@ Definition:
</Column> </Column>
</ApiCard> </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**. See below for an example with the call **GetMyUser**.
```Go ```go
//User //User
rpc GetMyUser(google.protobuf.Empty) returns (UserView) { rpc GetMyUser(google.protobuf.Empty) returns (UserView) {
option (google.api.http) = { 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` 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/`. 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. 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. For easy copying to your reverse proxy configuration, here is the list of URL path prefixes, ZITADEL uses.
``` ```yaml
/zitadel.admin.v1.AdminService/ /zitadel.admin.v1.AdminService/
/admin/v1/ /admin/v1/
/zitadel.auth.v1.AuthService/ /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/ /oidc/v1/
/saml/v2/ /saml/v2/
/oauth/v2/ /oauth/v2/
/device
/oidc/v1/
/.well-known/openid-configuration /.well-known/openid-configuration
/openapi/ /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). Users can setup and delete a second factor and FIDO Passkeys (Passwordless).
Available authenticators are: 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.) - FIDO Universal Second Factor (U2F) (Security Keys, Device, etc.)
- FIDO2 WebAuthN (Passkeys) - FIDO2 WebAuthN (Passkeys)

View File

@ -2,18 +2,23 @@
title: SDKs title: SDKs
--- ---
## ZITADEL SDK On this page you find our official SDKs, links to supporting frameworks and providers, and resources to help with SDKs.
The SDKs wrap either our [gRPC or REST APIs](/docs/apis/introduction) to provide the client with User Authentication and Management for resources.
| Language / Framework | Link Github | User Authentication | Manage resources | Notes | ## ZITADEL SDKs
|--- | --- | --- | --- | --- |
| .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` |
## Missing an SDK | Language / Framework | Link Github | User Authentication | Manage resources | Notes |
|----------------------|---------------------------------------------------------------| --- | --- | --- |
| .NET | [zitadel-net](https://github.com/smartive/zitadel-net) | ✔️ | ✔️ | `community` |
| Elixir | [zitadel_api](https://github.com/jshmrtn/zitadel_api) | ✔️ | ✔️ | `community` |
| Go | [zitadel-go](https://github.com/zitadel/zitadel-go) | ❌ | ✔️ | `official` |
| JVM | 🚧 [WIP](https://github.com/zitadel/zitadel/discussions/3650) | ❓ | ❓ | TBD |
| Python | 🚧 [WIP](https://github.com/zitadel/zitadel/issues/3675) | ❓ | ❓ | TBD |
| NodeJS | [@zitadel/node](https://www.npmjs.com/package/@zitadel/node) | ❌ | ✔️ | `community` |
| Dart | [zitadel-dart](https://github.com/smartive/zitadel-dart) | ❌ | ✔️ | `community` |
| Rust | [zitadel-rust](https://github.com/smartive/zitadel-rust) | ✔️ | ✔️ | `community` |
## Missing SDK
Is your language/framework missing? Fear not, you can generate your gRPC API Client with ease. 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. 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 - [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) - [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. 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

@ -6,4 +6,4 @@ In ZITADEL you can connect an Identity Provider (IdP) like {props.provider} to y
Also, you can register the IdP to a specific organization only. Also, you can register the IdP to a specific organization only.
If you allow so, your organizations members can do the same in self-service. If you allow so, your organizations members can do the same in self-service.
</p> </p>
::: :::

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 ```bash
curl --request GET \ curl --request GET \
--url https://$ZITADEL_DOMAIN/v2alpha/settings/login \ --url https://$ZITADEL_DOMAIN/v2beta/settings/login \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' --header 'Authorization: Bearer '"$TOKEN"''
``` ```

View File

@ -7,7 +7,7 @@ Send the session token in the body of the request.
```bash ```bash
curl --request DELETE \ curl --request DELETE \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/218480890961985793 \ --url https://$ZITADEL_DOMAIN/v2beta/sessions/218480890961985793 \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --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 ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/search \ --url https://$ZITADEL_DOMAIN/v2beta/sessions/search \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --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 ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/idp_intents \ --url https://$ZITADEL_DOMAIN/v2beta/idp_intents \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -71,7 +71,7 @@ To get the information of the provider, make a request to ZITADEL.
### Request ### Request
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -127,7 +127,7 @@ This check requires that the previous step ended on the successful page and didn
#### Request #### Request
```bash ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \ --url https://$ZITADEL_DOMAIN/v2beta/sessions \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
@ -158,7 +158,7 @@ The display name is used to list the linkings on the users.
#### Request #### Request
```bash ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/human \ --url https://$ZITADEL_DOMAIN/v2beta/users/human \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --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 #### Request
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \

View File

@ -5,13 +5,17 @@ sidebar_label: Multi-Factor (MFA)
import MfaOptions from './_list-mfa-options.mdx'; import MfaOptions from './_list-mfa-options.mdx';
import BrowserRegisterWebAuthN from './_browser_register_webauthn.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. 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. 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 - 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. - Universal Second Factor (U2F), which is authentication with your device like Windows Hello, Apple FaceID, Fingerprint, FIDO2 keys, Yubikey, etc.
## TOTP Registration ## TOTP Registration
@ -37,7 +41,7 @@ Request Example:
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' --header 'Authorization: Bearer '"$TOKEN"''
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -69,7 +73,7 @@ Request Example:
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' --header 'Authorization: Bearer '"$TOKEN"''
--header 'Content-Type: application/json' \ --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 ## U2F Registration
### Flow ### Flow
@ -99,7 +389,7 @@ Request Example:
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' --header 'Authorization: Bearer '"$TOKEN"''
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -170,7 +460,7 @@ Example Request:
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -181,7 +471,7 @@ curl --request POST \
"rawId": "pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00", "rawId": "pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00",
"response": { "response": {
"attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIgRKS3VpeE9tfExXRzkoUKnG4rQWPvtSSt4YtDGgTx32oCIQDPey-2YJ4uIg-QCM4jj6aE2U3tgMFM_RP7Efx6xRu3JGhhdXRoRGF0YVikSZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFAAAAADju76085Yhmlt1CEOHkwLQAIKWsFWqxeMT8SxZnwp0ZMF1nk6yhs2m3AIvdixCNVgtNpQECAyYgASFYIMGUDSP2FAQn2MIfPMy7cyB_Y30VqixVgGULTBtFjfRiIlggjUGfQo3_-CrMmH3S-ZQkFKWKnNBQEAMkFtG-9A4zqW0", "attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIgRKS3VpeE9tfExXRzkoUKnG4rQWPvtSSt4YtDGgTx32oCIQDPey-2YJ4uIg-QCM4jj6aE2U3tgMFM_RP7Efx6xRu3JGhhdXRoRGF0YVikSZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFAAAAADju76085Yhmlt1CEOHkwLQAIKWsFWqxeMT8SxZnwp0ZMF1nk6yhs2m3AIvdixCNVgtNpQECAyYgASFYIMGUDSP2FAQn2MIfPMy7cyB_Y30VqixVgGULTBtFjfRiIlggjUGfQo3_-CrMmH3S-ZQkFKWKnNBQEAMkFtG-9A4zqW0",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQlhXdHh0WGxJeFZZa0pHT1dVaUVmM25zby02aXZKdWw2YmNmWHdMVlFIayIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAifQ" "clientDataJSON": "eyJ0eXBlJjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQlhXdHh0WGxJeFZZa0pHT1dVaUVmM25zby02aXZKdWw2YmNmWHdMVlFIayIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAifQ"
} }
}, },
"tokenName": "Google Pixel" "tokenName": "Google Pixel"
@ -189,3 +479,65 @@ curl --request POST \
``` ```
You have successfully registered a new U2F to the user. 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 ```bash
curl --request GET \ 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"''\ --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. 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 ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \

View File

@ -3,6 +3,10 @@ title: Passkeys
sidebar_label: 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. 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. 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/) . 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 ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --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 ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -181,7 +185,7 @@ Example Request:
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --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) ![Passkey Login](/img/guides/login-ui/passkey-login-flow.png)
### Create Session ### Create Session
First step is to ask the user for his username and create a new session with the ZITADEL API. 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: Example Request:
```bash ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \ --url https://$ZITADEL_DOMAIN/v2beta/sessions \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -273,43 +276,11 @@ Example Response:
### Signing in Browser ### Signing in Browser
After starting the passkey authentication on the side of ZITADEL you have to challenge the browser. <BrowserSigninWebAuthN/>
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 ### Update Session with WebAuthN
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": {}
}
}
}'
```
<UpdateSessionWebAuthN/>

View File

@ -28,7 +28,7 @@ Make sure to also include the URL Template to customize the reset link in the em
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --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 #### Request
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
@ -95,7 +95,7 @@ In this case it requires additionally the current password instead of the verifi
```bash ```bash
curl --request POST \ 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 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --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 ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/human \ --url https://$ZITADEL_DOMAIN/v2beta/users/human \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --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. To check what is allowed on your instance, call the settings service for more information.
The following requests can be useful for registration: 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 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](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 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 ## 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. 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. 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) - [Create new session Documentation](/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) - [Update an existing session Documentation](/apis/resources/session_service/session-service-set-session)
- [Get Session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-get-session) - [Get Session Documentation](/apis/resources/session_service/session-service-get-session)
### Request ### Request
```bash ```bash
curl --request POST \ curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \ --url https://$ZITADEL_DOMAIN/v2beta/sessions \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --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 ```bash
curl --request PATCH \ curl --request PATCH \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/$SESSION_ID \ --url https://$ZITADEL_DOMAIN/v2beta/sessions/$SESSION_ID \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --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

@ -1,16 +1,14 @@
--- ---
title: Quick start guide title: Quick start guide
--- ---
import VSCodeFolderView from "../../../static/img/guides/quickstart/vscode1.png"; import VSCodeFolderView from "../../../static/img/guides/quickstart/vscode1.png";
## Introduction ## 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. 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.
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 ## ZITADEL terminology: instances, organizations, projects, users, roles, authorizations and apps
@ -18,15 +16,48 @@ In ZITADEL, instances, organizations, projects, users, roles, and apps are the m
The order of creation for the above components would typically be as follows: The order of creation for the above components would typically be as follows:
<ul> <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>
<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> <b>Instance</b>: An instance is a top-level entity in ZITADEL that
<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> represents a deployment of ZITADEL for a registered account. An instance can
<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> have one or more organizations.
<li><b>Roles</b>: Roles are the sets of permissions and privileges that are assigned to users within a project.</li> </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>
<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> <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> </ul>
The order of creation for the above components may vary depending on the specific needs and requirements of the organization. The order of creation for the above components may vary depending on the specific needs and requirements of the organization.
@ -43,11 +74,11 @@ The order of creation for the above components may vary depending on the specifi
![Registration Page](/img/guides/quickstart/2.png) ![Registration Page](/img/guides/quickstart/2.png)
3. You will receive a verification email to verify the user for the Customer Portal. Click the “Sign in” button. 3. You will receive a verification email to verify the user for the Customer Portal. Click the “Sign in” button.
![Congratulations Page](/img/guides/quickstart/3.png) ![Congratulations Page](/img/guides/quickstart/3.png)
4. You will be prompted for a code, which has been emailed to you. 4. You will be prompted for a code, which has been emailed to you.
![Code](/img/guides/quickstart/4.png) ![Code](/img/guides/quickstart/4.png)
@ -55,7 +86,7 @@ The order of creation for the above components may vary depending on the specifi
![Inbox](/img/guides/quickstart/5.png) ![Inbox](/img/guides/quickstart/5.png)
6. Paste the code and add a password as shown below. Click on the “next” button. 6. Paste the code and add a password as shown below. Click on the “next” button.
![Code](/img/guides/quickstart/6.png) ![Code](/img/guides/quickstart/6.png)
@ -63,11 +94,11 @@ The order of creation for the above components may vary depending on the specifi
![User Activated](/img/guides/quickstart/7.png) ![User Activated](/img/guides/quickstart/7.png)
8. Login with the username and password that you provided. Click “next”. 8. Login with the username and password that you provided. Click “next”.
![Login](/img/guides/quickstart/8.png) ![Login](/img/guides/quickstart/8.png)
9. You should set up 2-factor authentication. However, we will skip this step for now. Click on “skip”. 9. You should set up 2-factor authentication. However, we will skip this step for now. Click on “skip”.
![2-factor Authentication](/img/guides/quickstart/9.png) ![2-factor Authentication](/img/guides/quickstart/9.png)
@ -77,13 +108,13 @@ The order of creation for the above components may vary depending on the specifi
### 2. Create your first instance ### 2. Create your first instance
As a user of the ZITADEL Cloud Customer Portal, you now can create multiple instances to suit your specific needs. This includes instances for development, production, or user acceptance testing, as well as instances for different clients or applications. For example, you might create an instance for each product in a B2C scenario, or an instance for each tenant or customer in a B2B scenario. The possibilities are endless. You can create a pay-as-you-go instance for production purposes. As a user of the ZITADEL Cloud Customer Portal, you now can create multiple instances to suit your specific needs. This includes instances for development, production, or user acceptance testing, as well as instances for different clients or applications. For example, you might create an instance for each product in a B2C scenario, or an instance for each tenant or customer in a B2B scenario. The possibilities are endless. You can create a pay-as-you-go instance for production purposes.
1. Lets create an instance. Click on “Create new instance”. 1. Lets create an instance. Click on “Create new instance”.
![Create Instance](/img/guides/quickstart/10.png) ![Create Instance](/img/guides/quickstart/10.png)
2. Provide a name for your instance, select the “Free” plan and click on the “Continue” button at the bottom of this screen. 2. Provide a name for your instance, select the “Free” plan and click on the “Continue” button at the bottom of this screen.
![Select Tier](/img/guides/quickstart/v2_1.png) ![Select Tier](/img/guides/quickstart/v2_1.png)
@ -91,19 +122,19 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst
![Instance Details](/img/guides/quickstart/v2_2.png) ![Instance Details](/img/guides/quickstart/v2_2.png)
4. The instance creation process will take a few seconds. 4. The instance creation process will take a few seconds.
![Instance Details](/img/guides/quickstart/v2_3.png) ![Instance Details](/img/guides/quickstart/v2_3.png)
5. Now you will see the details of your first instance. You can click on "Visit" at the top right to go to your instance. 5. Now you will see the details of your first instance. You can click on "Visit" at the top right to go to your instance.
![Instance Details](/img/guides/quickstart/v2_4.png) ![Instance Details](/img/guides/quickstart/v2_4.png)
6. To log in to your instance, provide the username and password, and click “next”. 6. To log in to your instance, provide the username and password, and click “next”.
![Instance Details](/img/guides/quickstart/v2_5.png) ![Instance Details](/img/guides/quickstart/v2_5.png)
7. Skip the 2-factor authentication for now by clicking “skip”. 7. Skip the 2-factor authentication for now by clicking “skip”.
![Instance Details](/img/guides/quickstart/v2_6.png) ![Instance Details](/img/guides/quickstart/v2_6.png)
@ -113,7 +144,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst
### 3. Create your first project ### 3. Create your first project
1. To create a project in the instance you just created, click on “Create Project”. 1. To create a project in the instance you just created, click on “Create Project”.
![Create Project](/img/guides/quickstart/19.png) ![Create Project](/img/guides/quickstart/19.png)
@ -129,19 +160,19 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst
[Skip optional steps](quickstart/#7-create-an-application-in-your-project) and jump directly to the create application step. [Skip optional steps](quickstart/#7-create-an-application-in-your-project) and jump directly to the create application step.
1. To add users, click on “Users” at the top menu. You will see that the user you already created is listed as a user here. Click on the “New” button to create a new user. 1. To add users, click on “Users” at the top menu. You will see that the user you already created is listed as a user here. Click on the “New” button to create a new user.
![Add User](/img/guides/quickstart/26.png) ![Add User](/img/guides/quickstart/26.png)
2. Lets add another user as shown below. Fill in the user details as shown below and click on the “Create” button when you are done. 2. Lets add another user as shown below. Fill in the user details as shown below and click on the “Create” button when you are done.
![Add User](/img/guides/quickstart/27.png) ![Add User](/img/guides/quickstart/27.png)
3. The newly created user details will be displayed as shown below. 3. The newly created user details will be displayed as shown below.
![User Info](/img/guides/quickstart/28.png) ![User Info](/img/guides/quickstart/28.png)
4. Once you navigate back to the "Users" view, you will see a list of all the users that have been added to your instance. If you need to add more users, you can do so. 4. Once you navigate back to the "Users" view, you will see a list of all the users that have been added to your instance. If you need to add more users, you can do so.
![User Info](/img/guides/quickstart/29.png) ![User Info](/img/guides/quickstart/29.png)
@ -177,7 +208,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst
![Add Authorization](/img/guides/quickstart/32.png) ![Add Authorization](/img/guides/quickstart/32.png)
4. Lets select the role “sales”. Click on “Save”. 4. Lets select the role “sales”. Click on “Save”.
![Add Authorization](/img/guides/quickstart/33.png) ![Add Authorization](/img/guides/quickstart/33.png)
@ -195,9 +226,9 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst
### 7. Create an application in your project ### 7. Create an application in your project
We will now create an application in the project, which will allow our React client application to access protected resources through the use of the OpenID Connect (OIDC) protocol. We will now create an application in the project, which will allow our React client application to access protected resources through the use of the OpenID Connect (OIDC) protocol.
1. Go to “Projects” and click on “Project1”. 1. Go to “Projects” and click on “Project1”.
![Add Application](/img/guides/quickstart/38.png) ![Add Application](/img/guides/quickstart/38.png)
@ -209,15 +240,15 @@ We will now create an application in the project, which will allow our React cli
![Add Application](/img/guides/quickstart/41.png) ![Add Application](/img/guides/quickstart/41.png)
4. Select “PKCE” because we recommend the use of [Authorization Code](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) for all web applications. More about the different app types can be found [here](https://zitadel.com/docs/guides/integrate/oauth-recommended-flows#different-client-profiles). Click on "Continue". 4. Select “PKCE” because we recommend the use of [Authorization Code](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](https://zitadel.com/docs/apis/openidoauth/grant-types#authorization-code) for all web applications. More about the different app types can be found [here](https://zitadel.com/docs/guides/integrate/oauth-recommended-flows#different-client-profiles). Click on "Continue".
![Add Application](/img/guides/quickstart/42.png) ![Add Application](/img/guides/quickstart/42.png)
5. The Redirect URL in your application is where the ZITADEL authorization server redirects the user after they have been authenticated. Set your “Redirect URI” to [http://localhost:3000/callback](http://localhost:3000/callback) and “Post Logout URI” to [http://localhost:3000/](http://localhost:3000/). Click on “Continue”. 5. The Redirect URL in your application is where the ZITADEL authorization server redirects the user after they have been authenticated. Set your “Redirect URI” to [http://localhost:3000/callback](http://localhost:3000/callback) and “Post Logout URI” to [http://localhost:3000/](http://localhost:3000/). Click on “Continue”.
![Add Application](/img/guides/quickstart/43.png) ![Add Application](/img/guides/quickstart/43.png)
6. Now you will be presented with the details of your application for review. Click on “Create”. 6. Now you will be presented with the details of your application for review. Click on “Create”.
![Add Application](/img/guides/quickstart/44.png) ![Add Application](/img/guides/quickstart/44.png)
@ -229,7 +260,7 @@ We will now create an application in the project, which will allow our React cli
![Add Application](/img/guides/quickstart/46.png) ![Add Application](/img/guides/quickstart/46.png)
9. To proceed with HTTP, go to “Redirect Settings” on the left. 9. To proceed with HTTP, go to “Redirect Settings” on the left.
![Add Application](/img/guides/quickstart/47.png) ![Add Application](/img/guides/quickstart/47.png)
@ -242,11 +273,12 @@ We will now create an application in the project, which will allow our React cli
![Add Application](/img/guides/quickstart/50.png) ![Add Application](/img/guides/quickstart/50.png)
### 8. Obtain ClientId and OIDC endpoints for your application {#referred1} ### 8. Obtain ClientId and OIDC endpoints for your application {#referred1}
You will need the ClientId and the OIDC endpoints (issuer and userinfo) when building your React application. The issuer URL is the base URL for the OIDC provider and includes the path to the OIDC discovery document, which contains information about the OIDC provider, including the authorization and token endpoints. By providing the issuer URL, you can use the OIDC library to automatically determine the endpoints for these requests.
The authorization endpoint is used to initiate the authorization process, the token endpoint is used to exchange authorization codes for access tokens, and the userinfo endpoint is used to retrieve information about the user. You need an access token to access the userinfo endpoint and other protected resources. You will need the ClientId and the OIDC endpoints (issuer and userinfo) when building your React application. The issuer URL is the base URL for the OIDC provider and includes the path to the OIDC discovery document, which contains information about the OIDC provider, including the authorization and token endpoints. By providing the issuer URL, you can use the OIDC library to automatically determine the endpoints for these requests.
1. Click on “Configurations” to access the Client ID as shown below: The authorization endpoint is used to initiate the authorization process, the token endpoint is used to exchange authorization codes for access tokens, and the userinfo endpoint is used to retrieve information about the user. You need an access token to access the userinfo endpoint and other protected resources.
1. Click on “Configurations” to access the Client ID as shown below:
![Get URLs](/img/guides/quickstart/51.png) ![Get URLs](/img/guides/quickstart/51.png)
@ -260,19 +292,19 @@ And with that, configuring ZITADEL for our application is complete. Now we can m
### 1. Functional requirements of the application ### 1. Functional requirements of the application
1. The user navigates to the React app (client) and clicks the "login" button. 1. The user navigates to the React app (client) and clicks the "login" button.
2. The app initiates the authorization process by redirecting the users browser to the authorization endpoint of the ZITADEL instance, along with the PKCE parameters (code challenge, and code challenge method). 2. The app initiates the authorization process by redirecting the users browser to the authorization endpoint of the ZITADEL instance, along with the PKCE parameters (code challenge, and code challenge method).
3. The user will see the ZITADEL login page, where the user can enter their credentials. 3. The user will see the ZITADEL login page, where the user can enter their credentials.
4. After successful authentication, ZITADEL generates an authorization code and redirects the user back to the React app. 4. After successful authentication, ZITADEL generates an authorization code and redirects the user back to the React app.
5. The React app sends a request to the ZITADEL token endpoint, along with the authorization code and code verifier. 5. The React app sends a request to the ZITADEL token endpoint, along with the authorization code and code verifier.
6. ZITADEL verifies the code verifier to ensure that the authorization request is coming from the same client that initiated it. If it is valid, ZITADEL returns an access token to the React app. 6. ZITADEL verifies the code verifier to ensure that the authorization request is coming from the same client that initiated it. If it is valid, ZITADEL returns an access token to the React app.
7. The React app uses the access token to make a request to the userinfo endpoint, which is protected by the OIDC protocol. 7. The React app uses the access token to make a request to the userinfo endpoint, which is protected by the OIDC protocol.
8. The userinfo endpoint returns information about the logged-in user, such as their name and email address. 8. The userinfo endpoint returns information about the logged-in user, such as their name and email address.
9. The React app displays this information to the user. 9. The React app displays this information to the user.
10. When the user wants to log out, the React app sends a request to the ZITADEL logout endpoint, which clears the access token and ends the user's session. 10. When the user wants to log out, the React app sends a request to the ZITADEL logout endpoint, which clears the access token and ends the user's session.
11. The user will be redirected to the login page of the app. 11. The user will be redirected to the login page of the app.
***The scope of this application for this quick start guide is limited to user authentication and doesn't include role-based authentication, even though we previously discussed adding roles and users.*** **_The scope of this application for this quick start guide is limited to user authentication and doesn't include role-based authentication, even though we previously discussed adding roles and users._**
### 2. Prerequisites ### 2. Prerequisites
@ -282,37 +314,37 @@ To install React, you will need to have Node.js installed on your system. You ca
To install Visual Studio Code, go to their [website](https://code.visualstudio.com/) and download and install the version for your operating system. 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 ### 3. Development
#### 1. Create project #### 1. Create project
1. Open a new terminal window in Visual Studio Code. 1. Open a new terminal window in Visual Studio Code.
2. Navigate to the folder where you want to create the React app. 2. Navigate to the folder where you want to create the React app.
3. Run the following command to create a new React app named "react-oidc-zitadel": 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: 4. Navigate to the "react-oidc-zitadel" folder:
``` cd react-oidc-zitadel ``` `cd react-oidc-zitadel`
This will create the following files in your project: This will create the following files in your project:
<img src={VSCodeFolderView} width="40%" height="40%" /> <img src={VSCodeFolderView} width="40%" height="40%" />
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: 5. The dependencies for this project include react-router-dom and oidc-client-ts. To include them in your React application, you will need to run the following command in your terminal:
``` npm install react-router-dom oidc-client-ts ``` `npm install react-router-dom oidc-client-ts`
#### 2. Add source files
#### 2. Add source files
The code needed to run this project can be found [here](https://github.com/zitadel/react-user-authentication). The code needed to run this project can be found [here](https://github.com/zitadel/react-user-authentication).
1. Replace the content in your App.js file with the one provided below: 1. Replace the content in your App.js file with the one provided below:
[src/App.js](https://github.com/zitadel/react-user-authentication/blob/main/src/App.js): [src/App.js](https://github.com/zitadel/react-user-authentication/blob/main/src/App.js):
``` ```
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom"; import { BrowserRouter, Routes, Route } from "react-router-dom";
import Login from "./components/Login"; import Login from "./components/Login";
@ -372,23 +404,23 @@ function App() {
); );
} }
export default App; export default App;
``` ```
The App.js file is the root component of the React app that initializes the OIDC flow and manages the user's session. It does this by: 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. - 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. - 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 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. - 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. - 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. - 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. 2. Create a folder named components in the src directory. Create two files named Login.js and Callback.js.
3. Paste the following code to Login.js. 3. Paste the following code to Login.js.
[src/components/Login.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Login.js) [src/components/Login.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Login.js)
``` ```
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
@ -417,11 +449,12 @@ const Login = ({ auth, handleLogin, userManager }) => {
export default Login; export default Login;
``` ```
The ```/``` route corresponds to the login page, which is rendered by the Login component. The Login(Login.js) component is a functional component that displays the login button and calls the ```handleLogin``` function (which corresponds to the ```authorize``` function defined in the App component) when the button is clicked. This initiates the OIDC flow by redirecting the user to the authorization endpoint.
4. Paste the following code to Callback.js. The `/` route corresponds to the login page, which is rendered by the Login component. The Login(Login.js) component is a functional component that displays the login button and calls the `handleLogin` function (which corresponds to the `authorize` function defined in the App component) when the button is clicked. This initiates the OIDC flow by redirecting the user to the authorization endpoint.
[src/components/Callback.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Callback.js) 4. Paste the following code to Callback.js.
[src/components/Callback.js](https://github.com/zitadel/react-user-authentication/blob/main/src/components/Callback.js)
``` ```
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
@ -451,6 +484,20 @@ const Callback = ({ auth, setAuth, userManager, userInfo, setUserInfo, handleLog
}).catch((error) => { }).catch((error) => {
setAuth(false); 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]); }, [auth, userManager, setAuth]);
@ -478,11 +525,11 @@ const Callback = ({ auth, setAuth, userManager, userInfo, setUserInfo, handleLog
export default Callback; export default Callback;
``` ```
The ```/callback``` route corresponds to the callback page, which is rendered by the Callback(Callback.js) component. The Callback component is also a functional component that handles the callback from the authorization server after the user logs in. It retrieves the authorization code from the URL, exchanges it for an access token and id token, and retrieves the user's information from the userinfo endpoint. It also sets the ```authenticated``` and ```userInfo``` state variables in the App(App.js) component and displays the ```logout``` button. When the ```logout``` button is clicked, the ```clearAuth``` function is called and the user's session is ended. The ```clearAuth``` function is defined in the App component and is called with no arguments. It initiates the end session flow by redirecting the user to the end session endpoint. The `/callback` route corresponds to the callback page, which is rendered by the Callback(Callback.js) component. The Callback component is also a functional component that handles the callback from the authorization server after the user logs in. It retrieves the authorization code from the URL, exchanges it for an access token and id token, and retrieves the user's information from the userinfo endpoint. It also sets the `authenticated` and `userInfo` state variables in the App(App.js) component and displays the `logout` button. When the `logout` button is clicked, the `clearAuth` function is called and the user's session is ended. The `clearAuth` function is defined in the App component and is called with no arguments. It initiates the end session flow by redirecting the user to the end session endpoint.
5. Create a new file in the src folder named authConfig.js and paste the following code to it. 5. Create a new file in the src folder named authConfig.js and paste the following code to it.
[src/authConfig.js](https://github.com/zitadel/react-user-authentication/blob/main/src/authConfig.js) [src/authConfig.js](https://github.com/zitadel/react-user-authentication/blob/main/src/authConfig.js)
``` ```
const authConfig = { const authConfig = {
@ -498,26 +545,27 @@ const authConfig = {
}; };
export default 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: 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).*** - 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) - redirect_uri (the URL to redirect to after the authorization flow is complete)
- response_type (the type of response expected from the authorization server) - response_type (the type of response expected from the authorization server)
- scope (the permissions requested from the user) - scope (the permissions requested from the user)
- post_logout_redirect_uri (the URL to redirect to after the user logs out) - 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) - response_mode (the method to use to send the authorization response)
- code_challenge_method (the method to use to generate the code challenge). - code_challenge_method (the method to use to generate the code challenge).
Note that the oidc-client-ts library automatically handles the generation of the code verifier and code challenge when the user clicks on the login button, eliminating the need for the application to manually generate and include these values in the requests. Note that the oidc-client-ts library automatically handles the generation of the code verifier and code challenge when the user clicks on the login button, eliminating the need for the application to manually generate and include these values in the requests.
In the PKCE flow, the code verifier is a random string generated by the client application, and the code challenge is a transformed version of the code verifier using the SHA-256 hashing algorithm. In the PKCE flow, the code verifier is a random string generated by the client application, and the code challenge is a transformed version of the code verifier using the SHA-256 hashing algorithm.
6. Add a file called style.css to the src folder to apply CSS styling to the pages. 6. Add a file called style.css to the src folder to apply CSS styling to the pages.
[src/style.css](https://github.com/zitadel/react-user-authentication/blob/main/src/style.css) [src/style.css](https://github.com/zitadel/react-user-authentication/blob/main/src/style.css)
``` ```
/* The body element covers the entire page, so setting the background color here /* The body element covers the entire page, so setting the background color here
@ -529,14 +577,14 @@ In the PKCE flow, the code verifier is a random string generated by the client a
/* Center the text in the body element */ /* Center the text in the body element */
text-align: center; text-align: center;
} }
/* The h1, h2, and h3 elements are used for headings */ /* The h1, h2, and h3 elements are used for headings */
h1, h2, h3 { h1, h2, h3 {
/* The hex code for the dark blue color from the image is #2c3e50 */ /* The hex code for the dark blue color from the image is #2c3e50 */
color: #2c3e50; color: #2c3e50;
text-align: center; text-align: center;
} }
/* The button element represents a clickable button */ /* The button element represents a clickable button */
button { button {
/* The hex code for the light purple color from the image is #9b59b6 */ /* The hex code for the light purple color from the image is #9b59b6 */
@ -549,17 +597,16 @@ In the PKCE flow, the code verifier is a random string generated by the client a
/* Add some hover effect to the button */ /* Add some hover effect to the button */
cursor: pointer; cursor: pointer;
} }
button:hover { button:hover {
/* The hex code for the dark purple color from the image is #8e44ad */ /* The hex code for the dark purple color from the image is #8e44ad */
background-color: #8e44ad; background-color: #8e44ad;
} }
``` ```
7. Go to index.js and replace `import './index.css';` with `import './style.css'`. Your index.js file should look like this:
7. Go to index.js and replace ```import './index.css';``` with ```import './style.css'```. Your index.js file should look like this: [src/index.js](https://github.com/zitadel/react-user-authentication/blob/main/src/index.js)
[src/index.js](https://github.com/zitadel/react-user-authentication/blob/main/src/index.js)
``` ```
import React from 'react'; import React from 'react';
@ -583,13 +630,13 @@ reportWebVitals();
### 4. Running the application ### 4. Running the application
1. Run ```npm start``` to start the development server. 1. Run `npm start` to start the development server.
2. Open your browser and navigate to ```http://localhost:3000/``` to view the app. 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. 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) ![Login](/img/guides/quickstart/login1.png)
4. You will be redirected to the ZITADEL login page. Add your username/email and click on “next”. 4. You will be redirected to the ZITADEL login page. Add your username/email and click on “next”.
![Redirect](/img/guides/quickstart/login2.png) ![Redirect](/img/guides/quickstart/login2.png)
@ -601,22 +648,20 @@ reportWebVitals();
![Redirect](/img/guides/quickstart/login4.png) ![Redirect](/img/guides/quickstart/login4.png)
7. You can click on “Log out” to log out of the application and you will be taken to the landing page. 7. You can click on “Log out” to log out of the application and you will be taken to the landing page.
![Redirect](/img/guides/quickstart/login1.png) ![Redirect](/img/guides/quickstart/login1.png)
8. To see if the user has been successfully logged out and the user session has been terminated, click on “Please log in”, which brings you to the following page. Select the same user you logged in with earlier. 8. To see if the user has been successfully logged out and the user session has been terminated, click on “Please log in”, which brings you to the following page. Select the same user you logged in with earlier.
![Redirect](/img/guides/quickstart/login5.png) ![Redirect](/img/guides/quickstart/login5.png)
9. You will see that since the login session was terminated after logging out, the user has to enter his password again. 9. You will see that since the login session was terminated after logging out, the user has to enter his password again.
![Redirect](/img/guides/quickstart/login6.png) ![Redirect](/img/guides/quickstart/login6.png)
And this brings us to the end of this quick start guide!
And this brings us to the end of this quick start guide! This tutorial covered how to configure ZITADEL and how to use React to build an app that communicates with ZITADEL to access secured resources.
This tutorial covered how to configure ZITADEL and how to use React to build an app that communicates with ZITADEL to access secured resources.
We hope you enjoyed the tutorial and encourage you to check out the ZITADEL [documentation](https://zitadel.com/docs) for more information on how to use the ZITADEL platform to its full potential. Thanks for joining us! 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 title: Technical Advisory 10000
--- ---
## Date and Version
Version: 2.32.0
Date: Calendar Week 32
## Description ## Description
Currently, by default, users are directed to the "Select Account Page" on the ZITADEL login. 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 ## 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) 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 ## Mitigation

View File

@ -2,6 +2,12 @@
title: Technical Advisory 10001 title: Technical Advisory 10001
--- ---
## Date and Version
Version: 2.35.0
Date: Calendar Week 34
## Description ## Description
Currently, disabling the `Allow Register` setting in the Login Policy, will disable any registration - local and through External Identity Providers (IDP). 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 ## Statement
This behaviour change is tracked in the following PR: [Restrict AllowRegistration check to local registration](https://github.com/zitadel/zitadel/pull/5939). This behaviour change was 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. The change was part of version [v2.35.0](https://github.com/zitadel/zitadel/releases/tag/v2.35.0)
## Mitigation ## 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

@ -2,13 +2,12 @@
title: Technical Advisory title: Technical Advisory
--- ---
Technical advisories are notices that report major issues with ZITADEL Self-Hosted or the ZITADEL Cloud platform that could potentially impact security or stability in production environments. Technical advisories are notices that report major issues with ZITADEL Self-Hosted or the ZITADEL Cloud platform that could potentially impact security or stability in production environments.
These advisories may include details about the nature of the issue, its potential impact, and recommended mitigation actions. These advisories may include details about the nature of the issue, its potential impact, and recommended mitigation actions.
Users are strongly encouraged to evaluate these advisories and consider the recommended mitigation actions independently from their version upgrade schedule. Users are strongly encouraged to evaluate these advisories and consider the recommended mitigation actions independently from their version upgrade schedule.
We understand that these advisories may include breaking changes, and we aim to provide clear guidance on how to address these changes. We understand that these advisories may include breaking changes, and we aim to provide clear guidance on how to address these changes.
<table> <table>
<tr> <tr>
<th>Advisory</th> <th>Advisory</th>
@ -19,20 +18,56 @@ We understand that these advisories may include breaking changes, and we aim to
<th>Date</th> <th>Date</th>
</tr> </tr>
<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>Reusing user session</td>
<td>Breaking Behaviour Change</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>2.32.0</td>
<td>Calendar week 32</td> <td>Calendar week 32</td>
</tr> </tr>
<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>Login Policy - Allow Register</td>
<td>Breaking Behaviour Change</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>TBD</td>
<td>Calendar week 34/35</td> <td>Calendar week 40/41</td>
</tr> </tr>
</table> </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. 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. 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. 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). 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 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: The two scenarios should help you troubleshoot this issue:

View File

@ -261,28 +261,28 @@ module.exports = {
}, },
}, },
user: { 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", outputDir: "docs/apis/resources/user_service",
sidebarOptions: { sidebarOptions: {
groupPathsBy: "tag", groupPathsBy: "tag",
}, },
}, },
session: { 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", outputDir: "docs/apis/resources/session_service",
sidebarOptions: { sidebarOptions: {
groupPathsBy: "tag", groupPathsBy: "tag",
}, },
}, },
oidc: { 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", outputDir: "docs/apis/resources/oidc_service",
sidebarOptions: { sidebarOptions: {
groupPathsBy: "tag", groupPathsBy: "tag",
}, },
}, },
settings: { 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", outputDir: "docs/apis/resources/settings_service",
sidebarOptions: { sidebarOptions: {
groupPathsBy: "tag", groupPathsBy: "tag",

View File

@ -144,6 +144,13 @@ module.exports = {
type: "category", type: "category",
label: "Authenticate users", label: "Authenticate users",
collapsed: true, 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: [ items: [
"guides/integrate/login-users", "guides/integrate/login-users",
"guides/integrate/oauth-recommended-flows", "guides/integrate/oauth-recommended-flows",
@ -231,11 +238,11 @@ module.exports = {
"guides/integrate/identity-providers/azure-ad", "guides/integrate/identity-providers/azure-ad",
"guides/integrate/identity-providers/github", "guides/integrate/identity-providers/github",
"guides/integrate/identity-providers/gitlab", "guides/integrate/identity-providers/gitlab",
"guides/integrate/identity-providers/apple",
"guides/integrate/identity-providers/ldap", "guides/integrate/identity-providers/ldap",
"guides/integrate/identity-providers/openldap", "guides/integrate/identity-providers/openldap",
"guides/integrate/identity-providers/migrate", "guides/integrate/identity-providers/migrate",
"guides/integrate/identity-providers/google-oidc", "guides/integrate/identity-providers/okta",
"guides/integrate/identity-providers/azuread-oidc",
], ],
}, },
{ {
@ -275,20 +282,20 @@ module.exports = {
}, },
collapsed: true, collapsed: true,
items: [ items: [
"guides/integrate/services/gitlab-self-hosted", {
"guides/integrate/services/cloudflare-oidc", type: 'autogenerated',
"guides/integrate/services/aws-saml", dirName: 'guides/integrate/services',
"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: 'link', type: 'link',
label: 'Nextcloud', label: 'Nextcloud',
href: 'https://zitadel.com/blog/zitadel-as-sso-provider-for-selfhosting', 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', type: 'link',
label: 'Cloudflare workers', label: 'Cloudflare workers',
@ -309,6 +316,11 @@ module.exports = {
label: 'Netbird (netbird.io)', label: 'Netbird (netbird.io)',
href: 'https://docs.netbird.io/selfhosted/identity-providers', 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", type: "category",
label: "Core Resources", label: "Core Resources",
collapsed: false, collapsed: false,
link: {
type: "generated-index",
title: "Core Resources",
slug: "/apis/resources/",
description:
"Resource based API definitions",
},
items: [ items: [
{ {
type: "category", type: "category",
@ -493,57 +512,57 @@ module.exports = {
}, },
{ {
type: "category", type: "category",
label: "User lifecycle (alpha)", label: "User lifecycle (Beta)",
link: { link: {
type: "generated-index", type: "generated-index",
title: "User service API (Alpha)", title: "User service API (Beta)",
slug: "/apis/resources/user_service", slug: "/apis/resources/user_service",
description: description:
"This API is intended to manage users in a ZITADEL instance.\n"+ "This API is intended to manage users in a ZITADEL instance.\n"+
"\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"), items: require("./docs/apis/resources/user_service/sidebar.js"),
}, },
{ {
type: "category", type: "category",
label: "Session lifecycle (Alpha)", label: "Session lifecycle (Beta)",
link: { link: {
type: "generated-index", type: "generated-index",
title: "Session service API (Alpha)", title: "Session service API (Beta)",
slug: "/apis/resources/session_service", slug: "/apis/resources/session_service",
description: description:
"This API is intended to manage sessions in a ZITADEL instance.\n"+ "This API is intended to manage sessions in a ZITADEL instance.\n"+
"\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"), items: require("./docs/apis/resources/session_service/sidebar.js"),
}, },
{ {
type: "category", type: "category",
label: "OIDC lifecycle (Alpha)", label: "OIDC lifecycle (Beta)",
link: { link: {
type: "generated-index", type: "generated-index",
title: "OIDC service API (Alpha)", title: "OIDC service API (Beta)",
slug: "/apis/resources/oidc_service", slug: "/apis/resources/oidc_service",
description: description:
"Get OIDC Auth Request details and create callback URLs.\n"+ "Get OIDC Auth Request details and create callback URLs.\n"+
"\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"), items: require("./docs/apis/resources/oidc_service/sidebar.js"),
}, },
{ {
type: "category", type: "category",
label: "Settings lifecycle (alpha)", label: "Settings lifecycle (Beta)",
link: { link: {
type: "generated-index", type: "generated-index",
title: "Settings service API (Alpha)", title: "Settings service API (Beta)",
slug: "/apis/resources/settings_service", slug: "/apis/resources/settings_service",
description: description:
"This API is intended to manage settings in a ZITADEL instance.\n"+ "This API is intended to manage settings in a ZITADEL instance.\n"+
"\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"), 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'; import { Context } from 'support/commands';
const orgPath = `/org`; const orgPath = `/org`;
const orgsPath = `/orgs`;
const orgsPathCreate = `/orgs/create`;
const orgNameOnCreation = 'e2eorgrename'; const orgNameOnCreation = 'e2eorgrename';
const testOrgNameChange = uuidv4(); const testOrgNameChange = uuidv4();
const newOrg = uuidv4();
beforeEach(() => { beforeEach(() => {
cy.context().as('ctx'); cy.context().as('ctx');
}); });
describe('organizations', () => { 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', () => { describe('rename', () => {
beforeEach(() => { beforeEach(() => {
cy.get<Context>('@ctx').then((ctx) => { 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 != "" { if policy.FontColor != "" {
cssContent += fmt.Sprintf("--zitadel-color-label: %s;", policy.FontColor)
palette := m.generateColorPaletteRGBA255(policy.FontColor) palette := m.generateColorPaletteRGBA255(policy.FontColor)
for i, color := range palette { for i, color := range palette {
cssContent += fmt.Sprintf("--zitadel-color-text-%v: %s;", i, color) 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 != "" { if policy.FontColorDark != "" {
cssContent += fmt.Sprintf("--zitadel-color-label: %s;", policy.FontColorDark)
palette := m.generateColorPaletteRGBA255(policy.FontColorDark) palette := m.generateColorPaletteRGBA255(policy.FontColorDark)
for i, color := range palette { for i, color := range palette {
cssContent += fmt.Sprintf("--zitadel-color-text-%v: %s;", i, color) 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/api/authz"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "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 { 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/domain"
"github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/query" "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) { 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/stretchr/testify/require"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2alpha" oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta"
session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
) )
var ( var (

View File

@ -12,7 +12,7 @@ import (
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "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) { 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/api/grpc/server"
"github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/query" "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) 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 return org_pb.OrgState_ORG_STATE_ACTIVE
case domain.OrgStateInactive: case domain.OrgStateInactive:
return org_pb.OrgState_ORG_STATE_INACTIVE return org_pb.OrgState_ORG_STATE_INACTIVE
case domain.OrgStateRemoved:
return org_pb.OrgState_ORG_STATE_REMOVED
default: default:
return org_pb.OrgState_ORG_STATE_UNSPECIFIED return org_pb.OrgState_ORG_STATE_UNSPECIFIED
} }
@ -116,8 +114,6 @@ func OrgStateToDomain(state org_pb.OrgState) domain.OrgState {
return domain.OrgStateActive return domain.OrgStateActive
case org_pb.OrgState_ORG_STATE_INACTIVE: case org_pb.OrgState_ORG_STATE_INACTIVE:
return domain.OrgStateInactive return domain.OrgStateInactive
case org_pb.OrgState_ORG_STATE_REMOVED:
return domain.OrgStateRemoved
case org_pb.OrgState_ORG_STATE_UNSPECIFIED: case org_pb.OrgState_ORG_STATE_UNSPECIFIED:
fallthrough fallthrough
default: default:

View File

@ -15,7 +15,7 @@ import (
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
org "github.com/zitadel/zitadel/pkg/grpc/org/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"
) )
var ( var (

View File

@ -12,9 +12,9 @@ import (
"github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors" 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" 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) { func Test_addOrganizationRequestToCommand(t *testing.T) {

View File

@ -11,7 +11,6 @@ import (
grpc_util "github.com/zitadel/zitadel/internal/api/grpc" grpc_util "github.com/zitadel/zitadel/internal/api/grpc"
"github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/telemetry/tracing" "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 { 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 var orgDomain string
orgID := grpc_util.GetHeader(authCtx, http.ZitadelOrgID) orgID := grpc_util.GetHeader(authCtx, http.ZitadelOrgID)
if o, ok := req.(OrganisationFromRequest); ok { if o, ok := req.(OrganisationFromRequest); ok {
orgID = o.OrganisationFromRequest().GetOrgId() orgID = o.OrganisationFromRequest().ID
orgDomain = o.OrganisationFromRequest().GetOrgDomain() orgDomain = o.OrganisationFromRequest().Domain
} }
ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod) ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod)
if err != nil { if err != nil {
return nil, err return nil, err
@ -50,5 +48,10 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
} }
type OrganisationFromRequest interface { 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/command"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "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) var _ session.SessionServiceServer = (*Server)(nil)

View File

@ -12,7 +12,7 @@ import (
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors" caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/query" "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) { 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" "google.golang.org/grpc/metadata"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
) )
var ( var (

View File

@ -14,8 +14,8 @@ import (
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors" caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/query"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
session "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha" session "github.com/zitadel/zitadel/pkg/grpc/session/v2beta"
) )
func Test_sessionsToPb(t *testing.T) { 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/api/grpc/server"
"github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/query" "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) 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/object/v2"
"github.com/zitadel/zitadel/internal/api/grpc/text" "github.com/zitadel/zitadel/internal/api/grpc/text"
"github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/query"
object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
"github.com/zitadel/zitadel/pkg/grpc/settings/v2alpha" "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta"
) )
func (s *Server) GetLoginSettings(ctx context.Context, req *settings.GetLoginSettingsRequest) (*settings.GetLoginSettingsResponse, error) { 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/domain"
"github.com/zitadel/zitadel/internal/query" "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 { 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/api/grpc"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "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"} var ignoreTypes = []protoreflect.FullName{"google.protobuf.Duration"}

View File

@ -7,8 +7,8 @@ import (
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors" 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"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
) )
func (s *Server) SetEmail(ctx context.Context, req *user.SetEmailRequest) (resp *user.SetEmailResponse, err error) { 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/muhlemmer/gu"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "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" "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) { 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/authz"
"github.com/zitadel/zitadel/internal/api/grpc/object/v2" "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) { 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/stretchr/testify/require"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
) )
func TestServer_AddOTPSMS(t *testing.T) { 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/api/grpc/object/v2"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors" caos_errs "github.com/zitadel/zitadel/internal/errors"
object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
) )
func (s *Server) RegisterPasskey(ctx context.Context, req *user.RegisterPasskeyRequest) (resp *user.RegisterPasskeyResponse, err error) { 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/muhlemmer/gu"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "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" "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) { func TestServer_RegisterPasskey(t *testing.T) {

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