mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-12 17:15:15 +00:00
Merge commit from fork
* fix: Improve host header handling and deployment mode detection * ZITADEL_CLOUD env * refactor service config * service config * cleanup * cleanup * util for original and public host * instanceHost, publicHost * cleanup constructUrl * cleanup middleware * add x-zitadel-forward-host as fallback for current cloud setup * fix build * fix: lint * fix: update test mocks * fix: provide basepath to unit tests * host handling * unit tests * imports * fix: getPublicHost instead of getInstanceHost * unit tests * update nextjs, implement jwt verify for logout_token * pass logout information in jwt to login v2 * handle hosts in jwks url * point idp callbacks to the api and not the login UI * logout_hint out of logout token, typecheck * rm unused imports * fix oidc integration test --------- Co-authored-by: Livio Spring <[email protected]>
This commit is contained in:
co-authored by
Livio Spring
parent
f9e3871bb3
commit
df75be96ff
@@ -9,7 +9,7 @@ import { idpTypeToIdentityProviderType, idpTypeToSlug } from "../idp";
|
||||
|
||||
import { PasskeysType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
|
||||
import { UserState } from "@zitadel/proto/zitadel/user/v2/user_pb";
|
||||
import { getServiceUrlFromHeaders } from "../service-url";
|
||||
import { getServiceConfig } from "../service-url";
|
||||
import {
|
||||
getActiveIdentityProviders,
|
||||
getIDPByID,
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
startIdentityProviderFlow,
|
||||
} from "../zitadel";
|
||||
import { createSessionAndUpdateCookie } from "./cookie";
|
||||
import { getOriginalHost } from "./host";
|
||||
import { getPublicHost } from "./host";
|
||||
import { IDPLink } from "@zitadel/proto/zitadel/user/v2/idp_pb";
|
||||
|
||||
export type SendLoginnameCommand = {
|
||||
@@ -36,21 +36,18 @@ const ORG_SUFFIX_REGEX = /(?<=@)(.+)/;
|
||||
|
||||
export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
const _headers = await headers();
|
||||
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
|
||||
const { serviceConfig } = getServiceConfig(_headers);
|
||||
|
||||
const t = await getTranslations("loginname");
|
||||
|
||||
const loginSettingsByContext = await getLoginSettings({
|
||||
serviceUrl,
|
||||
organization: command.organization,
|
||||
});
|
||||
const loginSettingsByContext = await getLoginSettings({ serviceConfig, organization: command.organization });
|
||||
|
||||
if (!loginSettingsByContext) {
|
||||
return { error: t("errors.couldNotGetLoginSettings") };
|
||||
}
|
||||
|
||||
let searchUsersRequest: SearchUsersCommand = {
|
||||
serviceUrl,
|
||||
serviceConfig,
|
||||
searchValue: command.loginName,
|
||||
organizationId: command.organization,
|
||||
loginSettings: loginSettingsByContext,
|
||||
@@ -88,28 +85,22 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
// If userId is provided, check for user-specific IDP links first
|
||||
let identityProviders: IDPLink[] = [];
|
||||
if (userId) {
|
||||
identityProviders = await listIDPLinks({
|
||||
serviceUrl,
|
||||
userId,
|
||||
}).then((resp) => {
|
||||
identityProviders = await listIDPLinks({ serviceConfig, userId }).then((resp) => {
|
||||
return resp.result;
|
||||
});
|
||||
}
|
||||
|
||||
// If no IDP links exist for the user (or no userId provided), try to get active IDPs from the organization
|
||||
if (identityProviders.length === 0) {
|
||||
const activeIdps = await getActiveIdentityProviders({
|
||||
serviceUrl,
|
||||
orgId: organization,
|
||||
}).then((resp) => {
|
||||
const activeIdps = await getActiveIdentityProviders({ serviceConfig, orgId: organization }).then((resp) => {
|
||||
return resp.identityProviders;
|
||||
});
|
||||
|
||||
// If exactly one active IDP exists in the organization, redirect to it
|
||||
if (activeIdps.length === 1) {
|
||||
const _headers = await headers();
|
||||
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
|
||||
const host = await getOriginalHost();
|
||||
const { serviceConfig } = getServiceConfig(_headers);
|
||||
const host = getPublicHost(_headers);
|
||||
|
||||
const identityProviderType = activeIdps[0].type;
|
||||
const provider = idpTypeToSlug(identityProviderType);
|
||||
@@ -131,7 +122,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? "";
|
||||
|
||||
const url = await startIdentityProviderFlow({
|
||||
serviceUrl,
|
||||
serviceConfig,
|
||||
idpId: activeIdps[0].id,
|
||||
urls: {
|
||||
successUrl:
|
||||
@@ -153,15 +144,12 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
|
||||
if (identityProviders.length === 1) {
|
||||
const _headers = await headers();
|
||||
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
|
||||
const host = await getOriginalHost();
|
||||
const { serviceConfig } = getServiceConfig(_headers);
|
||||
const host = getPublicHost(_headers);
|
||||
|
||||
const identityProviderId = identityProviders[0].idpId;
|
||||
|
||||
const idp = await getIDPByID({
|
||||
serviceUrl,
|
||||
id: identityProviderId,
|
||||
});
|
||||
const idp = await getIDPByID({ serviceConfig, id: identityProviderId });
|
||||
|
||||
const idpType = idp?.type;
|
||||
|
||||
@@ -189,7 +177,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? "";
|
||||
|
||||
const url = await startIdentityProviderFlow({
|
||||
serviceUrl,
|
||||
serviceConfig,
|
||||
idpId: idp.id,
|
||||
urls: {
|
||||
successUrl:
|
||||
@@ -216,10 +204,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
const user = users[0];
|
||||
const userId = users[0].userId;
|
||||
|
||||
const userLoginSettings = await getLoginSettings({
|
||||
serviceUrl,
|
||||
organization: user.details?.resourceOwner,
|
||||
});
|
||||
const userLoginSettings = await getLoginSettings({ serviceConfig, organization: user.details?.resourceOwner });
|
||||
|
||||
// compare with the concatenated suffix when set
|
||||
const concatLoginname = command.suffix ? `${command.loginName}@${command.suffix}` : command.loginName;
|
||||
@@ -273,10 +258,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
// Resolve organization from command or session
|
||||
const organization = command.organization ?? session.factors?.user?.organizationId;
|
||||
|
||||
const methods = await listAuthenticationMethodTypes({
|
||||
serviceUrl,
|
||||
userId: session.factors?.user?.id,
|
||||
});
|
||||
const methods = await listAuthenticationMethodTypes({ serviceConfig, userId: session.factors?.user?.id });
|
||||
|
||||
// always resend invite if user has no auth method set
|
||||
if (!methods.authMethodTypes || !methods.authMethodTypes.length) {
|
||||
@@ -418,18 +400,12 @@ export async function sendLoginname(command: SendLoginnameCommand) {
|
||||
const suffix = matched?.[1] ?? "";
|
||||
|
||||
// this just returns orgs where the suffix is set as primary domain
|
||||
const orgs = await getOrgsByDomain({
|
||||
serviceUrl,
|
||||
domain: suffix,
|
||||
});
|
||||
const orgs = await getOrgsByDomain({ serviceConfig, domain: suffix });
|
||||
|
||||
const orgToCheckForDiscovery = orgs.result && orgs.result.length === 1 ? orgs.result[0].id : undefined;
|
||||
|
||||
if (orgToCheckForDiscovery) {
|
||||
const orgLoginSettings = await getLoginSettings({
|
||||
serviceUrl,
|
||||
organization: orgToCheckForDiscovery,
|
||||
});
|
||||
const orgLoginSettings = await getLoginSettings({ serviceConfig, organization: orgToCheckForDiscovery });
|
||||
|
||||
if (orgLoginSettings?.allowDomainDiscovery) {
|
||||
console.log("org discovery successful, using org:", orgToCheckForDiscovery);
|
||||
|
||||
Reference in New Issue
Block a user