mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-12 17:15:15 +00:00
docs: introduce versioned docs and migrate to fuma (#11166)
## Todos for release - [x] Configure Env in docs project on vercel - [x] Configure Root Path in the docs project on vercel - [ ] Remove old CSP https://github.com/zitadel/website/pull/1592 ## What we did This pull request migrates the project documentation from the old `docs/` directory to the new `apps/docs/` directory, introduces a new documentation system built with Next.js and Fumadocs, and updates all relevant references, configuration files, and documentation to reflect this change. It also adds new configuration and ignore files for the new documentation app, updates CI and linting to exclude the new docs from certain checks, and revises the contributing guidelines accordingly. **Documentation System Migration and New Docs App** * Migrated all documentation from `docs/` to `apps/docs/`, and updated all references in `README.md`, `CONTRIBUTING.md`, and other files to point to the new location. [[1]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L585-L640) [[2]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L660-R607) [[3]](diffhunk://#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055L740-R687) [[4]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L2-R3) [[5]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L30-R30) * Added a new Next.js/Fumadocs-based documentation app under `apps/docs/`, including core app files, layouts, routing, search API, and a comprehensive `README.md` with development and contribution instructions. [[1]](diffhunk://#diff-5a1b07344a2c1b4d3f37b23ff1388b62cd9f57dea3c1cd23d8a0412b7602b132R1-R74) [[2]](diffhunk://#diff-462b9ad1eabbb7d1c29bb9c36e4931eb180fd7190900e6d2babf8f4d66ad1c28R1-R39) [[3]](diffhunk://#diff-e16ae25660ded787b10ac35dea96d5ecaacf895dae0afc8a9bd4382dc79a8c87R1-R7) [apps/docs/app/[[...slug]]/layout.tsxR1-R81](diffhunk://#diff-59e08acde4e805b7aeccef1dcf98f1d71dfc550777e6b9402085cee0e9fa4e0aR1-R81), [apps/docs/app/[[...slug]]/page.tsxR1-R79](diffhunk://#diff-e5df3f80d0fa01e12d63d81f29c57a9d14e846c78fd3beabb2ef768e38fd9580R1-R79), [[4]](diffhunk://#diff-389b34918e040cacaa87cd7201ffa462cc2b0b716736f537e3d3c660ac69353bR1-R7) [[5]](diffhunk://#diff-d3b03416d1c457b19f1c27b26f2db741412df841b875c26ccadc36e4522247f4R1-R29) [[6]](diffhunk://#diff-c8fb8339570a5305809be7c618e14705fd86390dc278e6ce8ba224a7bc8b0c3cR1-R25) **Configuration and Tooling Updates** * Updated `.github/workflows/codeql.yml`, `.golangci.yaml`, and `.github/dependabot.yml` to properly handle the new docs app: excluded `apps/docs` from certain checks, added npm dependency updates for the docs app, and excluded generated content. [[1]](diffhunk://#diff-12783128521e452af0cfac94b99b8d250413c516ec71fe6d97dbea666ff7ba27L8-R14) [[2]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R5-R6) [[3]](diffhunk://#diff-9917ddc9f1c3304218f7269265b746d997c5c0615478177b5fceecd33ef47cb5R126-R129) [[4]](diffhunk://#diff-dd4fbda47e51f1e35defb9275a9cd9c212ecde0b870cba89ddaaae65c5f3cd28R89-R106) * Updated `.devcontainer/devcontainer.json` to use the latest Go 1.25.3 version for consistency. **Licensing and Miscellaneous** * Added `apps/docs/` to the list of licensed directories in `LICENSING.md`. These changes ensure the documentation is now maintained in a modern, scalable system and all project tooling is updated to support the new structure. --------- Co-authored-by: Federico Coppede <[email protected]>
This commit is contained in:
co-authored by
Federico Coppede
parent
7b6395c348
commit
d8ea041c56
@@ -0,0 +1,17 @@
|
||||
Per default the login ui of the default organization is shown.
|
||||
To allow users of a specific organization to register with their IDP (e.g Entra ID) you have two options.
|
||||
|
||||
1. Identify organization with organization scope
|
||||
|
||||
By sending the organization scope in the authorization request to ZITADEL the specified organization will directly be triggered.
|
||||
The configured settings of that organization such as IDPs will directly be shown.
|
||||
If only one IDP is configured and local accounts are disabled the user will directly be redirected to the external provider.
|
||||
```
|
||||
urn:zitadel:iam:org:id:{id}
|
||||
```
|
||||
|
||||
2. Domain Discovery
|
||||
|
||||
When domain discovery is enabled, ZITADEL is able to identify the entered domain of a user and match it to a specific organization.
|
||||
If you want to know more about domain discovery and how to set it up please read the following guide:
|
||||
[Domain Discovery in ZITADEL](/guides/solution-scenarios/domain-discovery)
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: Onboard B2B customers using organizations
|
||||
sidebar_label: Onboard B2B customer
|
||||
---
|
||||
|
||||
In this guide we will explain how you can create and set up new organizations in ZITADEL to help you with your onboarding flows.
|
||||
Creating a new organization is the best choice for multi-tenancy use cases that require separation of customers, teams, or groups of users.
|
||||
|
||||
We will also explain how to leverage [Managers](/guides/manage/console/managers) to delegate self-service team management and configuration of policies to users of each organization.
|
||||
|
||||
When you want to build an onboarding process for your business customers you have to go through the following steps:
|
||||
|
||||
1. Create an organization: The organization represents the customer or a team
|
||||
2. Create the first administrator user: This user is the account for your customer, which should be able to configure settings such as SSO, MFA, etc.
|
||||
3. Give the user permission to configure settings, create users and assign roles to users in ZITADEL
|
||||
|
||||
As soon as you have successfully created the organization and added an administrator, then your customer is able to start managing the organization and users themselves.
|
||||
The first actions they typically want to take are the following:
|
||||
1. Invite Team member
|
||||
2. Configure SSO
|
||||
3. Configure Security Settings
|
||||
4. Configure Branding
|
||||
|
||||
ZITADEL does have multiple possibilities to achieve that process.
|
||||
|
||||
## Onboard customers through the ZITADEL Management Console
|
||||
|
||||
Each ZITADEL instance does automatically bring a management console with it. The [console](/guides/manage/console/console-overview) can be used to manage all your resources through a UI.
|
||||
You can access it by calling the following URL: `${CUSTOM-DOMAIN}/ui/`
|
||||
Make sure that your admins have a [Administrator role](/guides/manage/console/managers) with permissions on an instance level such as "INSTANCE_OWNER"
|
||||
|
||||
### Create a customer
|
||||
|
||||
You do have two different options to create a new Organization.
|
||||
1. If you are on a specific organization, click the dropdown in the header and press click "+ New Organization"
|
||||
|
||||
<img src="/docs/img/guides/solution-scenarios/create-org-dropdown.png" alt="Create Organization Dropdown"/>
|
||||
|
||||
2. If you are on the instance level, go to the Organization tab and click the "+ New" button above the Organization list.
|
||||
|
||||
<img src="/docs/img/guides/solution-scenarios/org-list-add-new.png" alt="Organization List - Add new Organization"/>
|
||||
|
||||
No matter which option you choose you will be redirected to the create organization screen.
|
||||
If the setting "Use your personal account as organization owner" is enabled, your user will automatically get the role "ORG_OWNER" in the organization.
|
||||
Give the organization a name and create it.
|
||||
|
||||
<img src="/docs/img/guides/solution-scenarios/create-organization.png" alt="Create Organization"/>
|
||||
|
||||
Click on the newly created organization in the list and you will switch your context to that organization.
|
||||
|
||||
### Add First Administrator
|
||||
|
||||
Create the first user for your customer and ensure the user has enough permissions to self-manage the needed configuration.
|
||||
|
||||
#### Create User
|
||||
|
||||
import CreateUser from "../../../guides/manage/console/_create-user.mdx";
|
||||
|
||||
<CreateUser components={props.components} />
|
||||
|
||||
#### Add Administrator Role to User
|
||||
|
||||
Now you need to assign the right administrator role to your user. In this case we want to give "ORG_OWNER".
|
||||
If you do want to know more about the roles check out the [ZITADEL Managers Guide with the Role List](/guides/manage/console/managers)
|
||||
|
||||
Go to the detail page of the organization and select the "+" button in the top right corner, where you already see a list of existing managers.
|
||||
<img alt="Managers" src="/docs/img/guides/console/managers.png" width="200px" />
|
||||
|
||||
import AddManager from "../../../guides/manage/console/_add_manager.mdx";
|
||||
|
||||
<AddManager components={props.components} name="AddManager" />
|
||||
|
||||
### Invite Team Members
|
||||
|
||||
The first user of your customer is now ready to authenticate and manage resources in ZITADEL.
|
||||
First task will be inviting a team member.
|
||||
|
||||
We are now switching to the view of your customer's administrator user.
|
||||
|
||||
<Callout>
|
||||
The following actions can also be configured by an Instance Administrator for their customer.
|
||||
To show how you can use the self-management possibilities it is shown from the customer's administrator.
|
||||
</Callout>
|
||||
|
||||
The Administrator user received an initialization e-mail after the user was created.
|
||||
With the link in the email the admin will be able to setup a password and optionally some multi-factors.
|
||||
|
||||
As the administrator only has permission for its own organization the ZITADEL Management Console UI does look slightly different.
|
||||
|
||||
To invite a team member the admin has to repeat the steps you did before.
|
||||
1. [Create User](#create-user)
|
||||
2. [Add role "ORG_OWNER" to the user](#add-administrator-role-to-user)
|
||||
|
||||
### Setup Single-Sign-On (SSO)
|
||||
|
||||
Your next step is to configure SSO so your users can authenticate with an existing user into ZITADEL.
|
||||
|
||||
First go to the Login Behavior and Security Settings.
|
||||
Make sure that the "External IDP allowed" is enabled.
|
||||
This setting does generally allow users to authenticate with an external provider.
|
||||
|
||||
1. Go to the Settings Page
|
||||
2. Navigate to Identity Providers
|
||||
You might see already a list of activated providers here. If so, this is because some default providers are configured on the ZITADEL instances.
|
||||
3. Configure the identity provider you need.
|
||||
Follow our detailed configuration description of the different providers we have: [Configure the needed identity provider](/guides/integrate/identity-providers/introduction)
|
||||
|
||||
#### Auto-register users with SSO
|
||||
|
||||
Let's assume you have configured Entra ID as an identity provider, and you want to allow all your employees to login with the corresponding user without having to register.
|
||||
This does need some specific configuration on your provider.
|
||||
|
||||
1. Go to the detail page of your configured identity provider (In this example Entra ID)
|
||||
2. Enable "Automatic creation" in the optional settings. Optionally if you want to update the user information in ZITADEL, when they have changed in the Entra ID additionally enable "Automatic update"
|
||||
3. Enable the "Account creation allowed" if it is not already
|
||||
4. If you also want to allow users to link to an existing account, if they already have an account in ZITADEL, enable "Account linking allowed"
|
||||
|
||||
<Callout>
|
||||
It is only possible to automatically create accounts, that send all the required information to register a new user.
|
||||
If your provider does not send all the required fields that ZITADEL needs to create a user, make sure to fill them in the background with an Action.
|
||||
[Example for prefilling user data automatically](/guides/integrate/identity-providers/additional-information#automatically-pre-fill-user-data)
|
||||
</Callout>
|
||||
|
||||
#### Login with your user
|
||||
|
||||
Last step is that your user can login to ZITADEL and use the SSO account.
|
||||
|
||||
import OrgLoginDescription from "./_org_login_description.mdx";
|
||||
|
||||
<OrgLoginDescription components={props.components} name="OrgLodinDescription" />
|
||||
|
||||
Your user is now ready to login with SSO.
|
||||
<img src="/docs/img/guides/solution-scenarios/user-login-with-external-idp.png" alt="User Login with SSO"/>
|
||||
|
||||
## Automated onboarding for your customers
|
||||
|
||||
If you want to start automating the process of onboarding your customers the following sections give you some guidance.
|
||||
|
||||
### Built-in register organization form
|
||||
|
||||
A basic form that allows a customer to enter an organization name and a user account is hosted on the following URL:
|
||||
`{custom-domain}/ui/login/register/org`
|
||||
|
||||
When a user registers through this form, an organization and a user are created.
|
||||
The user will automatically get the role "ORG_OWNER" withing ZITADEL and is able to manage the whole organization.
|
||||
You can read more about the managers, roles and their meanings [here](/guides/manage/console/managers)
|
||||
|
||||
<img src="/docs/img/guides/solution-scenarios/register-organization.png" alt="Register Organization Form"/>
|
||||
|
||||
#### Disable built-in register organization form
|
||||
|
||||
If you do not want to allow users to register organizations with this form, you can disable it with the following request27: [Restrict the instance features](/reference/api/admin/zitadel.admin.v1.AdminService.SetRestrictions)
|
||||
|
||||
Disabling the form makes sense, if your administrators manage new customers themselves or if you build your own form.
|
||||
|
||||
### Build your own form with setup organization request
|
||||
|
||||
If the built-in register form doesn't fulfill your needs we recommend building your own form.
|
||||
|
||||
The administration API of ZITADEL, allows you to setup a new organization with a first administrator user.
|
||||
The setup organization requests, has the possibility to specify an organization with its name and a domain.
|
||||
You can directly send a human user with all the needed information like the profile, email, password. etc.
|
||||
This request allows you only to setup a user with password authentication at the moment.
|
||||
By specifying the roles you can define, which permission the user should have within ZITADEL.
|
||||
Per default the user will automatically get "ORG_OWNER".
|
||||
|
||||
<img src="/docs/img/guides/solution-scenarios/register-team-graphic.png" alt="Setup Organization with Admin User Graphic"/>
|
||||
|
||||
#### Example Request
|
||||
|
||||
```bash
|
||||
curl -L -X POST 'https://${CUSTOM_DOMAIN}/admin/v1/orgs/_setup' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Authorization: Bearer <TOKEN>' \
|
||||
--data-raw '{
|
||||
"org": {
|
||||
"name": "Organisation C",
|
||||
"domain": "org-c.com"
|
||||
},
|
||||
"human": {
|
||||
"userName": "gigi-giraffe",
|
||||
"profile": {
|
||||
"firstName": "Gigi",
|
||||
"lastName": "Giraffe",
|
||||
"nickName": "gigi-giraffe",
|
||||
"displayName": "Gigi Giraffe",
|
||||
"preferredLanguage": "en",
|
||||
"gender": "GENDER_UNSPECIFIED"
|
||||
},
|
||||
"email": {
|
||||
"email": "[email protected]",
|
||||
"isEmailVerified": true
|
||||
},
|
||||
"phone": {
|
||||
"phone": "+41 71 000 00 00",
|
||||
"isPhoneVerified": true
|
||||
},
|
||||
"password": "my_53cr3t-P4$$w0rd"
|
||||
},
|
||||
"roles": [
|
||||
"string"
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
Detailed description of [Setup Organization](/reference/api/admin/zitadel.admin.v1.AdminService.SetUpOrg)
|
||||
|
||||
If you need to add custom data to either the organization or the user you can use the metadata.
|
||||
Metadata is a key value construct that allows you to store any additional information to the resources.
|
||||
The set organization metadata request allows you to add one key value pair to an organization:
|
||||
[Set Organization Metadata](/reference/api/management/zitadel.management.v1.ManagementService.SetOrgMetadata)
|
||||
If you have more than one field, you can use the bulk add request:
|
||||
[Bulk Set Organization Metadata](/reference/api/management/zitadel.management.v1.ManagementService.BulkSetOrgMetadata)
|
||||
|
||||
The same requests also exist on the user resource:
|
||||
[Set User Metadata](/reference/api/management/zitadel.management.v1.ManagementService.SetUserMetadata)
|
||||
[Bulk Set User Metadata](/reference/api/management/zitadel.management.v1.ManagementService.BulkSetUserMetadata)
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: Onboard Users
|
||||
sidebar_label: Onboard Users
|
||||
---
|
||||
|
||||
import CreateUser from "../../../guides/manage/console/_create-user.mdx";
|
||||
import OrgLoginDescription from "./_org_login_description.mdx";
|
||||
|
||||
End Users have three different possibilities on how to login with ZITADEL.
|
||||
|
||||
1. Local Account with Username, Password, MFA, Passkey, etc
|
||||
2. Social Login like Google, Apple, Github, etc
|
||||
3. External Identity Provider hosted/managed by Organization like Entra ID, LDAP, Okta etc
|
||||
|
||||
You can either use the hosted login of ZITADEL to let users register themselves, or you can build your own UI and use the existing APIs.
|
||||
|
||||
## Manually add/invite users
|
||||
|
||||
<CreateUser components={props.components} />
|
||||
|
||||
## Automated / Self-registration possibilities
|
||||
|
||||
If you want to start automating the process of onboarding your users and let them do self-registration the following sections give you some guidance.
|
||||
|
||||
### Built-in register form
|
||||
|
||||
#### Prompt registration form
|
||||
|
||||
When users first access your application, they'll typically need to either log in or register.
|
||||
By default, redirecting from your application displays the login page.
|
||||
|
||||
OpenID Connect (OIDC) allows you to control the initial screen by sending a [prompt](/apis/openidoauth/endpoints#additional-parameters) parameter in the authorization request.
|
||||
With the `prompt=create`, the registration form/options will directly be shown to the user.
|
||||
You can test the impact of the different prompts on your login UI in our [OIDC Playground](https://zitadel.com/playgrounds/oidc).
|
||||
|
||||
Per default a user will be registered to the default organization.
|
||||
By sending the scope below in your authorization request you can choose the organization to which the user will be added.
|
||||
|
||||
```
|
||||
urn:zitadel:iam:org:id:{id}
|
||||
```
|
||||
|
||||
Unfortunately, SAML doesn't offer the same level of control over the initial screen.
|
||||
You won't be able to directly influence which page (login or registration) is shown through the SAML flow.
|
||||
|
||||
#### Choose Registration Option
|
||||
|
||||
If an organization allows local user registration as well as registration with a social or enterprise login, the user can choose an option to register.
|
||||
|
||||
As soon as users click the "register" button, they will be presented with a screen showing the different registration options.
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/solution-scenarios/register-options.png"
|
||||
alt="Register Options"
|
||||
/>
|
||||
|
||||
After that, the user can select either local user registration or an external provider.
|
||||
By pressing the button of an external provider, the user will directly be redirected to the provider for consent.
|
||||
|
||||
<Callout>
|
||||
The options are dependent on the settings of the organization.
|
||||
If only one option is possible, the option will directly be selected and shown.
|
||||
</Callout>
|
||||
|
||||
#### Local User Registration
|
||||
|
||||
To allow users to register themselves, you have to enable the "register allowed" in the login behavior settings.
|
||||
You will now see the register button on the login screen.
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/solution-scenarios/register-end-user.png"
|
||||
alt="Register End User"
|
||||
/>
|
||||
|
||||
If nothing else is specified, a user will be registered to the default organization.
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/solution-scenarios/default-organization.png"
|
||||
alt="Default Organization"
|
||||
/>
|
||||
|
||||
You can specify another organization, by sending the organization scope in the authorization requests.
|
||||
By sending the scope below the settings of the specified organization will be triggered and only users of the said organization will be able to authenticate.
|
||||
The users will be registered to the given organization.
|
||||
|
||||
```
|
||||
urn:zitadel:iam:org:id:{id}
|
||||
```
|
||||
|
||||
If the user chooses to register a local account, the register form will be shown.
|
||||
All the mandatory fields like first name, last name, e-mail and password have to be filled.
|
||||
You can only setup authentication with the built-in form.
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/solution-scenarios/register-local-user.png"
|
||||
alt="Register local user"
|
||||
/>
|
||||
|
||||
#### Registration with Social Login
|
||||
|
||||
To allow your users to register with social logins you have to configure the external identity providers.
|
||||
If you only need the social logins for your end users and you want to have them all in the organization, we recommend using the default organization for those users.
|
||||
In that case you can configure the identity providers on the default organization.
|
||||
If you want to have the social logins on different organizations you can configure the default on the instance, and enable it on the needed organizations.
|
||||
|
||||
Please follow the configuration guides for the needed providers: [Let Users Login with Preferred Identity Provider in ZITADEL](/guides/integrate/identity-providers/introduction)
|
||||
|
||||
The configured providers will be shown on the first login screen or when the users click on the registration button, they will be able to choose between local account or the social login.
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/solution-scenarios/register-end-user.png"
|
||||
alt="Register End User"
|
||||
/>
|
||||
|
||||
#### Registration with Organization External Identity Provider
|
||||
|
||||
If your business customer already have an identity provider, and you want to allow SSO for them, you can configure their providers directly for their organization.
|
||||
Configure the needed provider such as Entra ID or OKTA.
|
||||
|
||||
Please follow the configuration guides for the needed providers: [Let Users Login with Preferred Identity Provider in ZITADEL](/guides/integrate/identity-providers/introduction)
|
||||
|
||||
<OrgLoginDescription components={props.components} name="OrgLoginDescription" />
|
||||
|
||||
### Build your own registration form
|
||||
|
||||
ZITADEL allows you to build your own registration form and login UI.
|
||||
The registration process highly depends on your needs.
|
||||
|
||||
We do have a guide series on how to build your own login ui, which also includes the registration of different authentication methods, such as:
|
||||
|
||||
- Password authentication
|
||||
- Multi-Factor
|
||||
- Passkeys
|
||||
- External Login Providers
|
||||
|
||||
You can find all the guides here: [Build your own login UI](/guides/integrate/login-ui)
|
||||
|
||||
#### Custom fields
|
||||
|
||||
The [create user request](/reference/api/user/zitadel.user.v2.UserService.AddHumanUser) also allows you to add [metadata](/guides/manage/customize/user-metadata) (key, value) to the user.
|
||||
This gives you the possibility to collect additional data from your users during the registration process and store it directly to the user in ZITADEL.
|
||||
Those metadata can also directly be included in the [token](/guides/manage/customize/user-metadata#use-tokens-to-get-user-metadata) of the user.
|
||||
We recommend storing business relevant data in the database of your application, and only authentication and authorization relevant data in ZITADEL to follow the separation of concern pattern.
|
||||
|
||||
#### Registration with Organization External Identity Provider
|
||||
|
||||
If you want to know more about the multi-tenancy possibilities of ZITADEL, read the following blog post:
|
||||
[Multi-Tenancy and Delegated Access Management with Organizations](https://zitadel.com/blog/multi-tenancy-with-organizations)
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "Onboard Customers and Users"
|
||||
description: "When building your own application, one of the first questions you have to face, is 'How do my customers onboard to my application?'
|
||||
These guides will explain the built-in solution for onboarding new tenants, customers, and users and how you can handle more advanced onboarding use cases. "
|
||||
---
|
||||
|
||||
{/* THIS FILE IS AUTO-GENERATED FROM SIDEBAR-DATA.
|
||||
ANY MANUAL CHANGES WILL BE OVERWRITTEN.
|
||||
*/}
|
||||
|
||||
import { Card, Cards } from 'fumadocs-ui/components/card';
|
||||
import { FileText, Folder, Link as LinkIcon } from 'lucide-react';
|
||||
|
||||
<Cards>
|
||||
<Card title="B2b" href="/guides/integrate/onboarding/b2b" icon={<FileText />} />
|
||||
<Card title="End Users" href="/guides/integrate/onboarding/end-users" icon={<FileText />} />
|
||||
</Cards>
|
||||
Reference in New Issue
Block a user