mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-11 21:02:21 +00:00
describe discovery
This commit is contained in:
@@ -58,6 +58,7 @@ Requests to the APIs made:
|
||||
- `startIdentityProviderFlow`
|
||||
- `listUsers(org?)`
|
||||
- `listAuthenticationMethodTypes`
|
||||
- `getOrgsByDomain`
|
||||
|
||||
After a loginname is entered, a `listUsers` request is made using the loginName query to identify already registered users.
|
||||
|
||||
@@ -70,7 +71,8 @@ If password is the next step, we check `loginSettings.passkeysType` for Passkeys
|
||||
If no user is found, we check whether registering is allowed using `loginSettings.allowRegister`.
|
||||
If `loginSettings?.allowUsernamePassword` is not allowed we continue to check for available IDPs. If a single IDP is available, we directly redirect the user to signup.
|
||||
|
||||
If no single IDP is set, we check for `loginSettings.allowUsernamePassword` and redirect the user to /register page.
|
||||
If no single IDP is set, we check for `loginSettings.allowUsernamePassword` and if no organization is set as context, we check whether we can discover a organization from the loginname of the user (using: `getOrgsByDomain`). Then if an organization is found, we check whether domainDiscovery is allowed on it and redirect the user to /register page including the discovered domain or without.
|
||||
|
||||
If no previous condition is met we throw an error stating the user was not found.
|
||||
|
||||
If the outcome after this order produces a no authentication methods found, or user not found, we check whether `loginSettings?.ignoreUnknownUsernames` is set to `true` as in this case we redirect to the /password page regardless (to not leak information about a registered user).
|
||||
|
||||
@@ -9,6 +9,7 @@ import { idpTypeToSlug } from "../idp";
|
||||
import {
|
||||
getActiveIdentityProviders,
|
||||
getLoginSettings,
|
||||
getOrgsByDomain,
|
||||
listAuthenticationMethodTypes,
|
||||
listUsers,
|
||||
startIdentityProviderFlow,
|
||||
@@ -20,6 +21,8 @@ export type SendLoginnameCommand = {
|
||||
organization?: string;
|
||||
};
|
||||
|
||||
const ORG_SUFFIX_REGEX = /(?<=@)(.+)/;
|
||||
|
||||
export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
const users = await listUsers({
|
||||
loginName: command.loginName,
|
||||
@@ -181,9 +184,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check if allowDomainDiscovery has to be allowed too, to redirect to the register page
|
||||
// user not found, check if register is enabled on organization
|
||||
|
||||
if (loginSettings?.allowRegister && !loginSettings?.allowUsernamePassword) {
|
||||
// TODO: do we need to handle login hints for IDPs here?
|
||||
await redirectUserToSingleIDPIfAvailable();
|
||||
@@ -193,10 +194,31 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
loginSettings?.allowRegister &&
|
||||
loginSettings?.allowUsernamePassword
|
||||
) {
|
||||
let orgToRegisterOn: string | undefined = command.organization;
|
||||
|
||||
if (
|
||||
!orgToRegisterOn &&
|
||||
command.loginName &&
|
||||
ORG_SUFFIX_REGEX.test(command.loginName)
|
||||
) {
|
||||
const matched = ORG_SUFFIX_REGEX.exec(command.loginName);
|
||||
const suffix = matched?.[1] ?? "";
|
||||
|
||||
// this just returns orgs where the suffix is set as primary domain
|
||||
const orgs = await getOrgsByDomain(suffix);
|
||||
const orgToCheckForDiscovery =
|
||||
orgs.result && orgs.result.length === 1 ? orgs.result[0].id : undefined;
|
||||
|
||||
const orgLoginSettings = await getLoginSettings(orgToCheckForDiscovery);
|
||||
if (orgLoginSettings?.allowDomainDiscovery) {
|
||||
orgToRegisterOn = orgToCheckForDiscovery;
|
||||
}
|
||||
}
|
||||
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (command.organization) {
|
||||
params.set("organization", command.organization);
|
||||
if (orgToRegisterOn) {
|
||||
params.set("organization", orgToRegisterOn);
|
||||
}
|
||||
if (command.authRequestId) {
|
||||
params.set("authRequestId", command.authRequestId);
|
||||
|
||||
Reference in New Issue
Block a user