Merge branch 'main' into rename-topt

This commit is contained in:
Tim Möhlmann 2023-06-23 19:09:39 +03:00 committed by GitHub
commit 1461977d93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 2684 additions and 2864 deletions

4826
console/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,18 +12,18 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^16.0.1",
"@angular/cdk": "^16.0.1",
"@angular/common": "^16.0.1",
"@angular/compiler": "^16.0.1",
"@angular/core": "^16.0.1",
"@angular/forms": "^16.0.1",
"@angular/material": "^16.0.1",
"@angular/material-moment-adapter": "^16.0.1",
"@angular/platform-browser": "^16.0.1",
"@angular/platform-browser-dynamic": "^16.0.1",
"@angular/router": "^16.0.1",
"@angular/service-worker": "^16.0.1",
"@angular/animations": "^16.1.2",
"@angular/cdk": "^16.1.2",
"@angular/common": "^16.1.2",
"@angular/compiler": "^16.1.2",
"@angular/core": "^16.1.2",
"@angular/forms": "^16.1.2",
"@angular/material": "^16.1.2",
"@angular/material-moment-adapter": "^16.1.2",
"@angular/platform-browser": "^16.1.2",
"@angular/platform-browser-dynamic": "^16.1.2",
"@angular/router": "^16.1.2",
"@angular/service-worker": "^16.1.2",
"@ctrl/ngx-codemirror": "^6.1.0",
"@grpc/grpc-js": "^1.8.14",
"@ngx-translate/core": "^14.0.0",
@ -41,7 +41,8 @@
"libphonenumber-js": "^1.10.30",
"material-design-icons-iconfont": "^6.1.1",
"moment": "^2.29.4",
"ngx-color": "^8.0.3",
"opentype.js": "^1.3.4",
"ngx-color": "^9.0.0",
"rxjs": "~7.8.0",
"tinycolor2": "^1.6.0",
"tslib": "^2.4.1",
@ -49,25 +50,26 @@
"zone.js": "~0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.0.1",
"@angular-devkit/build-angular": "^16.1.1",
"@angular-eslint/builder": "16.0.1",
"@angular-eslint/eslint-plugin": "16.0.1",
"@angular-eslint/eslint-plugin-template": "16.0.1",
"@angular-eslint/schematics": "16.0.1",
"@angular-eslint/template-parser": "16.0.1",
"@angular/cli": "^16.0.1",
"@angular/compiler-cli": "^16.0.1",
"@angular/language-service": "^16.0.1",
"@angular/cli": "^16.1.1",
"@angular/compiler-cli": "^16.1.2",
"@angular/language-service": "^16.1.2",
"@bufbuild/buf": "^1.18.0-1",
"@types/file-saver": "^2.0.2",
"@types/google-protobuf": "^3.15.3",
"@types/jasmine": "~4.3.0",
"@types/jasmine": "~4.3.3",
"@types/jasminewd2": "~2.0.10",
"@types/jsonwebtoken": "^9.0.1",
"@types/node": "^18.15.11",
"@types/opentype.js": "^1.3.4",
"@types/qrcode": "^1.5.0",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.5",
"codelyzer": "^6.0.2",
"eslint": "^8.39.0",

View File

@ -492,7 +492,9 @@
</cnsl-info-section>
<div class="font-preview" *ngIf="previewData.fontUrl; else addFontButton">
<mat-icon class="icon">text_fields</mat-icon>
<span class="font-name" [ngStyle]="fontName ? { 'font-family': 'brandingFont' } : { '': '' }">{{
fontName
}}</span>
<span class="fill-space"></span>
<button
@ -634,6 +636,7 @@
class="preview"
[ngClass]="{ darkmode: theme === Theme.DARK, lightmode: theme === Theme.LIGHT }"
[policy]="view === View.PREVIEW ? previewData : data"
[ngStyle]="fontName ? { 'font-family': 'brandingFont' } : { '': '' }"
>
</cnsl-preview>
</div>

View File

@ -243,8 +243,6 @@
}
.font-preview {
height: 70px;
width: 70px;
display: flex;
align-items: center;
justify-content: center;
@ -252,22 +250,17 @@
margin-bottom: 1rem;
border: 1px solid map-get($foreground, divider);
position: relative;
padding: 1rem 0.5rem 1rem 0.75rem;
.icon {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
.font-name {
margin-left: 0.5rem;
font-size: 16px;
}
.dl-btn {
z-index: 2;
position: absolute;
right: 0;
top: 0;
cursor: pointer;
visibility: hidden;
transform: translateX(50%) translateY(-50%);
}
&:hover {

View File

@ -31,6 +31,7 @@ import {
} from 'src/app/services/theme.service';
import { ToastService } from 'src/app/services/toast.service';
import * as opentype from 'opentype.js';
import { InfoSectionType } from '../../info-section/info-section.component';
import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component';
import { PolicyComponentServiceType } from '../policy-component-types.enum';
@ -88,6 +89,8 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
public ColorType: any = ColorType;
public AssetType: any = AssetType;
public fontName = '';
public refreshPreview: EventEmitter<void> = new EventEmitter();
public org!: Org.AsObject;
public InfoSectionType: any = InfoSectionType;
@ -180,6 +183,10 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
if (file) {
const formData = new FormData();
formData.append('file', file);
this.getFontName(file);
this.previewNewFont(file);
switch (this.serviceType) {
case PolicyComponentServiceType.MGMT:
return this.handleFontUploadPromise(this.assetService.upload(AssetEndpoint.MGMTFONT, formData, this.org.id));
@ -199,6 +206,7 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
this.getPreviewData().then((data) => {
if (data.policy) {
this.previewData = data.policy;
this.fontName = '';
}
});
}, 1000);
@ -374,6 +382,11 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
.then((data) => {
if (data.policy) {
this.previewData = data.policy;
if (this.previewData?.fontUrl) {
this.fetchFontMetadataAndPreview(this.previewData.fontUrl);
} else {
this.fontName = 'Could not parse font name';
}
this.loading = false;
}
})
@ -385,6 +398,11 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
.then((data) => {
if (data.policy) {
this.data = data.policy;
if (this.data?.fontUrl) {
this.fetchFontMetadataAndPreview(this.data?.fontUrl);
} else {
this.fontName = 'Could not parse font name';
}
this.loading = false;
}
})
@ -678,6 +696,45 @@ export class PrivateLabelingPolicyComponent implements OnInit, OnDestroy {
});
}
private fetchFontMetadataAndPreview(url: string): void {
fetch(url)
.then((res) => res.blob())
.then((blob) => {
this.getFontName(blob);
this.previewNewFont(blob);
});
}
private getFontName(blob: Blob): void {
const reader = new FileReader();
reader.onload = (e) => {
if (e.target && e.target.result) {
try {
const font = opentype.parse(e.target.result);
this.fontName = font.names.fullName['en'];
} catch (e) {
this.fontName = 'Could not parse font name';
}
}
};
reader.readAsArrayBuffer(blob);
}
private previewNewFont(blob: Blob): void {
const reader = new FileReader();
reader.onload = (e) => {
if (e.target) {
let customFont = new FontFace('brandingFont', `url(${e.target.result})`);
// typescript complains that add is not found but
// indeed it is https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/add
// @ts-ignore
document.fonts.add(customFont);
}
};
reader.readAsDataURL(blob);
}
// /**
// * defaults to false because urls are distinct anyway
// */

View File

@ -0,0 +1,20 @@
When your user is done using your application and clicks on the logout button, you have to send a request to the terminate session endpoint.
[Terminate Session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-delete-session)
Send the session token in the body of the request.
### Request
```bash
curl --request DELETE \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/218480890961985793 \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"sessionToken": "blGKerGQPKv8jN21p6E9GB1B-vl6_EyKlvTd5UALu8-aQmjucgZxHSXJx3XMFTwT9_Y3VnbOo3gC_Q"
}'
```
Terminating a session means to delete it.
If you try to read the session afterwards, you will get an error “Session does not exist”.

View File

@ -0,0 +1,80 @@
If you want to build your own select account/account picker, you have to cache the session IDs.
We recommend storing a list of the session Ids with the corresponding session token in a cookie.
The list of session IDs can be sent in the “search sessions” request to get a detailed list of sessions for the account selection.
[Search Sessions Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-list-sessions)
### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/_search \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"query": {
"offset": "0",
"limit": 100,
"asc": true
},
"queries": [
{
"idsQuery": {
"ids": [
"218380657934467329", "218480890961985793"
]
}
}
]
}'
```
### Response
```bash
{
"details": {
"totalResult": "2",
"processedSequence": "582",
"timestamp": "2023-06-14T05:42:11.644220Z"
},
"sessions": [
{
"id": "218380657934467329",
"creationDate": "2023-06-13T12:56:56.683629Z",
"changeDate": "2023-06-13T12:56:56.724450Z",
"sequence": "574",
"factors": {
"user": {
"verifiedAt": "2023-06-13T12:56:55.440850Z",
"id": "218380659823356328",
"loginName": "minnie-mouse@fabi.zitadel.app",
"displayName": "Minnie Mouse"
},
"password": {
"verifiedAt": "2023-06-13T12:56:56.675359Z"
}
}
},
{
"id": "218480890961985793",
"creationDate": "2023-06-14T05:32:38.977954Z",
"changeDate": "2023-06-14T05:42:11.631901Z",
"sequence": "582",
"factors": {
"user": {
"verifiedAt": "2023-06-14T05:32:38.972712Z",
"id": "218380659823356328",
"loginName": "minnie-mouse@fabi.zitadel.app",
"displayName": "Minnie Mouse"
},
"password": {
"verifiedAt": "2023-06-14T05:42:11.619484Z"
}
}
}
]
}
```

View File

@ -0,0 +1,209 @@
---
title: Handle External Login
sidebar_label: External Identity Provider
---
## Flow
The prerequisite for adding an external login (social and enterprise) to your user account is a registered identity provider on your ZITADEL instance or the organization of the user.
If you havent added a provider yet, have a look at the following guide first: [Identity Providers](https://zitadel.com/docs/guides/integrate/identity-providers)
![Identity Provider Flow](/img/guides/login-ui/external-login-flow.png)
## Start the Provider Flow
ZITADEL will handle as much as possible from the authentication flow with the external provider.
This requires you to initiate the flow with your desired provider.
Send the following two URLs in the request body:
1. SuccessURL: Page that should be shown when the login was successful
2. ErrorURL: Page that should be shown when an error happens during the authentication
In the response, you will get an authentication URL of the provider you like.
[Start Identity Provider Flow Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-start-identity-provider-flow)
### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/idps/$IDP_ID/start \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"successUrl": "https://custom.com/login/idp/success",
"failureUrl": "https://custom.com/login/idp/fail"
}'
```
### Response
```bash
{
"details": {
"sequence": "592",
"changeDate": "2023-06-14T12:51:29.654819Z",
"resourceOwner": "163840776835432705"
},
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth?client_id=Test&prompt=select_account&redirect_uri=https%3A%2F%2F$ZITADEL_DOMAIN%2Fidps%2Fcallback&response_type=code&scope=openid+profile+email&state=218525066445455617"
}
```
## Call Provider
The next step is to call the auth URL you got in the response from the previous step.
This will open up the login page of the given provider. In this guide, it is Google Login.
```bash
https://accounts.google.com/o/oauth2/v2/auth?client_id=Test&prompt=select_account&redirect_uri=https%3A%2F%2F$ZITADEL_DOMAIN%2Fidps%2Fcallback&response_type=code&scope=openid+profile+email&state=218525066445455617
```
After the user has successfully authenticated, a redirect to the ZITADEL backend /idps/callback will automatically be performed.
## Get Provider Information
ZITADEL will take the information of the provider. After this, a redirect will be made to either the success page in case of a successful login or to the error page in case of a failure will be performed. In the parameters, you will provide the intentID, a token, and optionally, if a user could be found, a user ID.
To get the information of the provider, make a request to ZITADEL.
[Get Identity Provider Information Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-retrieve-identity-provider-information)
### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/intents/$INTENT_ID/information \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"token": "k50WQmDaPIazQDJsyKaEPaQPwgsytxqgQ3K1ifQeQtAmeQ"
}'
```
### Response
```bash
{
"details": {
"sequence": "599",
"changeDate": "2023-06-15T06:44:26.039444Z",
"resourceOwner": "163840776835432705"
},
"idpInformation": {
"oauth": {
"accessToken": "ya29.a0AWY7CknrOORopcJK2XX2fQXV9NQpp8JdkKYx-mQZNrR-wktWWhc3QsepT6kloSCgFPS9N0beEBlEYoY5oYUhfc7VlLHTQz5iECE386pyx5YmTueyeQ9GXk1dAw89gi8KRyjNlJApFsfLJaoiLIvKJLf23eAyXgaCgYKAUMSARESFQG1tDrpnTJ2su8BBO24zfmzgneARw0165",
"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg1YmE5MzEzZmQ3YTdkNGFmYTg0ODg0YWJjYzg0MDMwMDQzNjMxODAiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIxODI5MDIwMjY1MDgtdW1taXQ3dHZjbHBnM2NxZmM4b2ljdGE1czI1aGtudWwuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiIxODI5MDIwMjY1MDgtdW1taXQ3dHZjbHBnM2NxZmM4b2ljdGE1czI1aGtudWwuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTEzOTI4MDU5NzU3MTU4NTY2MzciLCJoZCI6InJvb3RkLmNoIiwiZW1haWwiOiJmYWJpZW5uZUByb290ZC5jaCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhdF9oYXNoIjoidGN5X25JTkZHNnFhRTBZTWFsQzZGdyIsIm5hbWUiOiJGYWJpZW5uZSBCw7xobGVyIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FBY0hUdGY5NzNRNk5IOEt6S1RNRVpFTFBVOWx4NDVXcFE5RlJCdXhGZFBiPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkZhYmllbm5lIiwiZmFtaWx5X25hbWUiOiJCw7xobGVyIiwibG9jYWxlIjoiZGUiLCJpYXQiOjE2ODY4MTE0NjUsImV4cCI6MTY4NjgxNTA2NX0.PwlAHRM44e8eYyHzdfotOrcq5GZc4D15mWvN3rGdoDmu2RRgb4T0nDgkY6AVq2vNJxPfbiB1jFtNP6dgX-OgLIxNXg_tJJhwFh-eFPA37cIiv1CEcgEC-q1zXFIa3HrwHLreeU6i7C9JkDrKpkS-AKat1krf27QXxrxHLrWehi5F2l1OZuAKFWYaYmJOd0sVTDBA2o5SDcAiQs_D4-Q-kSl5f0gh607YVHLv7zjyfHtAOs7xPEkNEUVcqGBke2Zy9kAYIgiMriNxLA2EDxFtSyWnf-bCXKnuVX2hwEY0T0lUPrOAVkz7MEOKiacE2xAOczoQvl-wECU0UofLi8XZqg"
},
"idpId": "218528353504723201",
"rawInformation": {
"User": {
"email": "fabienne@rootd.ch",
"email_verified": true,
"family_name": "Bühler",
"given_name": "Fabienne",
"hd": "rootd.ch",
"locale": "de",
"name": "Fabienne Bühler",
"picture": "https://lh3.googleusercontent.com/a/AAcKTtf973Q6NH8KzKTMEZELPU9lx45WpQ9FRBuxFdPb=s96-c",
"sub": "111392805975715856637"
}
}
}
}
```
## Handle Provider Information
After successfully authenticating using your identity provider, you have three possible options.
1. Login
2. Register user
3. Add social login to existing user
### Login
If you did get a user ID in the parameters when calling your success page, you know that a user is already linked with the used identity provider and you are ready to perform the login.
Create a new session and include the intent ID and the token in the checks.
This check requires that the previous step ended on the successful page and didn'tt result in an error.
#### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"checks": {
"user": {
"userId": "218662596918640897"
},
"intent": {
"intentId": "219647325729980673",
"token": "k86ihn-VLMMUGKy1q1b5i_foECspKYqei1l4mS8LT7Xzjw"
}
}
}'
```
### Register
If you didn't get a user ID in the parameters of your success page, you know that there is no existing user in ZITADEL with that provider, and you can register a new user or link it to an existing account (read the next section).
Fill the IdP links in the create user request to add a user with an external login provider.
The idpId is the ID of the provider in ZITADEL, the idpExternalId is the ID of the user in the external identity provider; usually, this is sent in the “sub”.
The display name is used to list the linkings on the users.
[Create User API Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-add-human-user)
#### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/human \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"username": "minni-mouse@mouse.com",
"profile": {
"firstName": "Minnie",
"lastName": "Mouse",
"nickName": "Mini",
"displayName": "Minnie Mouse",
"preferredLanguage": "en",
"gender": "GENDER_FEMALE"
},
"email": {
"email": "minni-mouse@mouse.com",
"isVerified": true
},
"idpLinks": [
{
"idpId": "218528353504723201",
"idpExternalId": "111392805975715856637",
"displayName": "Minnie Mouse"
}
]
}'
```
### Add External Login to Existing User
If you didn't get a user ID in the parameters to your success page, you know that there is no existing user in ZITADEL with that provider and you can register a new user (read previous section), or link it to an existing account.
If you want to link/connect to an existing account you can perform the add identity provider link request.
[Add IDP Link to existing user documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-add-idp-link)
#### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/users/218385419895570689/links \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"idpLink": {
"idpId": "218528353504723201",
"idpExternalId": "1113928059757158566371",
"displayName": "Minnie Mouse"
}
}'
```

View File

@ -0,0 +1,7 @@
---
title: Logout
---
import Logout from './_logout.mdx';
<Logout/>

View File

@ -0,0 +1,26 @@
---
title: OIDC Standard
---
:::info
Not yet implemented, but should give you a general impression of how it will work
Subscribe to the following issue: https://github.com/orgs/zitadel/projects/2/views/1?filterQuery=oidc&pane=issue&itemId=23181369
:::
To build your own login ui for your own application it is not necessary to have the OIDC standard included or any additional work that has to be done.
However, it might make sense, if you want to connect your login to different applications especially if they are not in your control and they rely on the standard.
The following flow shows you the different components you need to enable OIDC for your login.
![OIDC Flow](/img/guides/login-ui/oidc-flow.png)
1. Your application makes an authorization request to your login UI
2. The login UI takes the requests and sends them to the ZITADEL API. In the request to the ZITADEL API, a header to authenticate your client is needed.
3. The ZITADEL API parses the request and does what it needs to interpret certain parameters (e.g., organization scope, etc.)
4. Redirect to a predefined, relative URL of the login UI that includes the authrequest ID
5. Request to ZITADEL API to get all the information from the auth request
6. Create and update the session till the login flow is complete and the user is authenticated. Make sure to include the auth Request ID in the session
7. Read the callback URL from the ZITADEL API
8. Redirect to your application with the callback URL you got in the previous request
9. All OIDC-specific endpoints have to be accepted in the Login UI and should be proxied and sent to the ZITADEL API

View File

@ -0,0 +1,7 @@
---
title: Select Account
---
import SelectAccount from './_select-account.mdx';
<SelectAccount/>

View File

@ -0,0 +1,236 @@
---
title: Register and Login User with Password
sidebar_label: Username and Password
---
## Flow
![Register and Login Flow](/img/guides/login-ui/username-password-flow.png)
## Register
First, we create a new user with a username and password. In the example below we add a user with profile data, a verified email address, and a password.
[Create User Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-add-human-user)
### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/users/human \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \
--data '{
"userId": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
"username": "minnie-mouse",
"profile": {
"firstName": "Minnie",
"lastName": "Mouse",
"nickName": "Mini",
"displayName": "Minnie Mouse",
"preferredLanguage": "en",
"gender": "GENDER_FEMALE"
},
"email": {
"email": "mini@mouse.com",
"isVerified": true
},
"metadata": [
{
"key": "my-key",
"value": "VGhpcyBpcyBteSB0ZXN0IHZhbHVl"
}
],
"password": {
"password": "Secr3tP4ssw0rd!",
"changeRequired": false
}
}'
```
### Response
```bash
{
"userId": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
"details": {
"sequence": "570",
"changeDate": "2023-06-13T12:44:36.967851Z",
"resourceOwner": "163840776835432705"
}
}
```
If you want the user to verify the email address you can either choose that ZITADEL sends a verification email to the user by adding a urlTemplate into the sendCode, or ask for a return code to send your own emails.
Send Email by ZITADEL:
```bash
"sendCode": {
"urlTemplate": "https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}"
},
```
Return Code:
```bash
"email": {
"email": "mini@mouse.com",
"returnCode": {}
},
```
To check what is allowed on your instance, call the settings service for more information.
The following requests can be useful for registration:
- [Get Login Settings](https://zitadel.com/docs/apis/resources/settings_service/settings-service-get-login-settings) To find out which authentication possibilities are enabled (password, identity provider, etc.)
- [Get Password Complexity Settings](https://zitadel.com/docs/apis/resources/settings_service/settings-service-get-password-complexity-settings) to find out how the password should look like (length, characters, etc.)
## Create Session with User Check
After you have created a new user, you can redirect him to your login screen.
You can either create a new empty session as soon as the first login screen is shown or update it with each piece of information you get throughout the process.
Or you can create a new session with the first credentials a user enters.
In the following example, we assume that the login flow asks for the username in the first step, and in the second for the password.
In API requests, this means creating a new session with a username and updating it with the password.
If you already have the userId from a previous register, you can send it directly to skip the username and show the password screen directly.
The create and update session endpoints will always return a session ID and an opaque session 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.
- [Create new session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-create-session)
- [Update an existing session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-set-session)
- [Get Session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-get-session)
### Request
```bash
curl --request POST \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \
--data '{
"checks": {
"user": {
"loginName": "minnie-mouse@fabi.zitadel.app"
}
}
}'
```
### Response
```bash
{
"details": {
"sequence": "580",
"changeDate": "2023-06-14T05:32:39.007096Z",
"resourceOwner": "163840776835432705"
},
"sessionId": "218480890961985793",
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg"
}
```
### Session State
If you read the newly created session, it will look like the following.
You can see the creation and change date.
In the factors, you will see all the checks that have been made.
In this case, the user has been checked.
```bash
{
"session": {
"id": "218480890961985793",
"creationDate": "2023-06-14T05:32:38.977954Z",
"changeDate": "2023-06-14T05:32:39.007096Z",
"sequence": "580",
"factors": {
"user": {
"verifiedAt": "2023-06-14T05:32:38.972712Z",
"id": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
"loginName": "minnie-mouse@fabi.zitadel.app",
"displayName": "Minnie Mouse"
}
}
}
}
```
## Update Session with Password
Your session already has a username check.
The next step is to check the password.
To update an existing session, add the session ID to the URL and the session token you got in the previous step to the request body.
### Request
```bash
curl --request PATCH \
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/$SESSION_ID \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \
--data '{
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg",
"checks": {
"password": {
"password": "Secr3tP4ssw0rd!"
}
}
}'
```
### Response
The response of the create and update session token looks the same.
Make sure to always use the session token of the last response you got, as the values may be updated.
```bash
{
"details": {
"sequence": "582",
"changeDate": "2023-06-14T05:42:11.631901Z",
"resourceOwner": "163840776835432705"
},
"sessionToken": "blGKerGQPKv8jN21p6E9GB1B-vl6_EyKlvTd5UALu8-aQmjucgZxHSXJx3XMFTwT9_Y3VnbOo3gC_Q"
}
```
### Session State
If you read your session after the password check, you will see that the check has been added to the factors with the verification date.
```bash
{
"session": {
"id": "218480890961985793",
"creationDate": "2023-06-14T05:32:38.977954Z",
"changeDate": "2023-06-14T05:42:11.631901Z",
"sequence": "582",
"factors": {
"user": {
"verifiedAt": "2023-06-14T05:32:38.972712Z",
"id": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
"loginName": "minnie-mouse@fabi.zitadel.app",
"displayName": "Minnie Mouse"
},
"password": {
"verifiedAt": "2023-06-14T05:42:11.619484Z"
}
}
}
}
```
## List the Sessions (Account Chooser)
import SelectAccount from './_select-account.mdx';
<SelectAccount/>
## Logout User
import Logout from './_logout.mdx';
<Logout/>

View File

@ -167,6 +167,26 @@ module.exports = {
"guides/integrate/pat",
],
},
{
type: "category",
label: "Build your own Login-UI",
link: {
type: "generated-index",
title: "Build your own Login-UI",
slug: "/guides/integrate/login-ui",
description:
"In the following guides you will learn how to create your own login ui with our APIs. The different scenarios like username/password, external identity provider, etc will be shown.",
},
collapsed: true,
items: [
"guides/integrate/login-ui/username-password",
"guides/integrate/login-ui/external-login",
"guides/integrate/login-ui/select-account",
"guides/integrate/login-ui/logout",
"guides/integrate/login-ui/oidc-standard"
],
},
{
type: "category",
label: "Configure identity providers",

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB