fix: enable saml sp

This commit is contained in:
Stefan Benz
2025-03-13 16:31:35 +01:00
parent 15447d66d9
commit 8ae6bc1686
3 changed files with 9 additions and 219 deletions

View File

@@ -4,7 +4,7 @@ import { linkingFailed } from "@/components/idps/pages/linking-failed";
import { linkingSuccess } from "@/components/idps/pages/linking-success";
import { loginFailed } from "@/components/idps/pages/login-failed";
import { loginSuccess } from "@/components/idps/pages/login-success";
import { idpTypeToIdentityProviderType, PROVIDER_MAPPING } from "@/lib/idp";
import { idpTypeToIdentityProviderType } from "@/lib/idp";
import { getServiceUrlFromHeaders } from "@/lib/service";
import {
addHuman,
@@ -57,7 +57,7 @@ export default async function Page(props: {
token,
});
const { idpInformation, userId } = intent;
const { idpInformation, userId, addHumanUser } = intent;
// sign in user. If user should be linked continue
if (userId && !link) {
@@ -124,7 +124,7 @@ export default async function Page(props: {
// search for potential user via username, then link
if (options?.isLinkingAllowed) {
let foundUser;
const email = PROVIDER_MAPPING[providerType](idpInformation).email?.email;
const email = addHumanUser.email?.email;
if (options.autoLinking === AutoLinkingOption.EMAIL && email) {
foundUser = await listUsers({ serviceUrl, email }).then((response) => {
@@ -181,15 +181,12 @@ export default async function Page(props: {
if (options?.isCreationAllowed && options.isAutoCreation) {
let orgToRegisterOn: string | undefined = organization;
let userData: AddHumanUserRequest =
PROVIDER_MAPPING[providerType](idpInformation);
if (
!orgToRegisterOn &&
userData.username && // username or email?
ORG_SUFFIX_REGEX.test(userData.username)
addHumanUser.username && // username or email?
ORG_SUFFIX_REGEX.test(addHumanUser.username)
) {
const matched = ORG_SUFFIX_REGEX.exec(userData.username);
const matched = ORG_SUFFIX_REGEX.exec(addHumanUser.username);
const suffix = matched?.[1] ?? "";
// this just returns orgs where the suffix is set as primary domain
@@ -214,15 +211,15 @@ export default async function Page(props: {
org: { case: "orgId", value: orgToRegisterOn },
});
userData = create(AddHumanUserRequestSchema, {
...userData,
addHumanUser = create(AddHumanUserRequestSchema, {
...addHumanUser,
organization: organizationSchema,
});
}
const newUser = await addHuman({
serviceUrl,
request: userData,
request: addHumanUser,
});
if (newUser) {

View File

@@ -74,189 +74,3 @@ export function idpTypeToIdentityProviderType(
throw new Error("Unknown identity provider type");
}
}
// this maps the IDPInformation to the AddHumanUserRequest which is used when creating a user or linking a user (email)
// TODO: extend this object from a other file which can be overwritten by customers like map = { ...PROVIDER_MAPPING, ...customerMap }
export type OIDC_USER = {
User: {
email: string;
name?: string;
given_name?: string;
family_name?: string;
};
};
const GITLAB_MAPPING = (idp: IDPInformation) => {
const rawInfo = idp.rawInformation as {
name: string;
email: string;
email_verified: boolean;
};
return create(AddHumanUserRequestSchema, {
username: idp.userName,
email: {
email: rawInfo.email,
verification: { case: "isVerified", value: rawInfo.email_verified },
},
profile: {
displayName: rawInfo.name || idp.userName || "",
givenName: "",
familyName: "",
},
idpLinks: [
{
idpId: idp.idpId,
userId: idp.userId,
userName: idp.userName,
},
],
});
};
const OIDC_MAPPING = (idp: IDPInformation) => {
const rawInfo = idp.rawInformation as OIDC_USER;
return create(AddHumanUserRequestSchema, {
username: idp.userName,
email: {
email: rawInfo.User?.email,
verification: { case: "isVerified", value: true },
},
profile: {
displayName: rawInfo.User?.name ?? "",
givenName: rawInfo.User?.given_name ?? "",
familyName: rawInfo.User?.family_name ?? "",
},
idpLinks: [
{
idpId: idp.idpId,
userId: idp.userId,
userName: idp.userName,
},
],
});
};
const GITHUB_MAPPING = (idp: IDPInformation) => {
const rawInfo = idp.rawInformation as {
email: string;
name: string;
};
return create(AddHumanUserRequestSchema, {
username: idp.userName,
email: {
email: rawInfo.email,
verification: { case: "isVerified", value: true },
},
profile: {
displayName: rawInfo.name ?? "",
givenName: rawInfo.name ?? "",
familyName: rawInfo.name ?? "",
},
idpLinks: [
{
idpId: idp.idpId,
userId: idp.userId,
userName: idp.userName,
},
],
});
};
export const PROVIDER_MAPPING: {
[provider: number]: (rI: IDPInformation) => AddHumanUserRequest;
} = {
[IdentityProviderType.GOOGLE]: (idp: IDPInformation) => {
const rawInfo = idp.rawInformation as OIDC_USER;
return create(AddHumanUserRequestSchema, {
username: idp.userName,
email: {
email: rawInfo.User?.email,
verification: { case: "isVerified", value: true },
},
profile: {
displayName: rawInfo.User?.name ?? "",
givenName: rawInfo.User?.given_name ?? "",
familyName: rawInfo.User?.family_name ?? "",
},
idpLinks: [
{
idpId: idp.idpId,
userId: idp.userId,
userName: idp.userName,
},
],
});
},
[IdentityProviderType.GITLAB]: GITLAB_MAPPING,
[IdentityProviderType.GITLAB_SELF_HOSTED]: GITLAB_MAPPING,
[IdentityProviderType.OIDC]: OIDC_MAPPING,
// check
[IdentityProviderType.OAUTH]: OIDC_MAPPING,
[IdentityProviderType.AZURE_AD]: (idp: IDPInformation) => {
const rawInfo = idp.rawInformation as {
jobTitle: string;
mail: string;
mobilePhone: string;
preferredLanguage: string;
id: string;
displayName?: string;
givenName?: string;
surname?: string;
officeLocation?: string;
userPrincipalName: string;
};
return create(AddHumanUserRequestSchema, {
username: idp.userName,
email: {
email: rawInfo.mail || rawInfo.userPrincipalName || "",
verification: { case: "isVerified", value: true },
},
profile: {
displayName: rawInfo.displayName ?? "",
givenName: rawInfo.givenName ?? "",
familyName: rawInfo.surname ?? "",
},
idpLinks: [
{
idpId: idp.idpId,
userId: idp.userId,
userName: idp.userName,
},
],
});
},
[IdentityProviderType.GITHUB]: GITHUB_MAPPING,
[IdentityProviderType.GITHUB_ES]: GITHUB_MAPPING,
[IdentityProviderType.APPLE]: (idp: IDPInformation) => {
const rawInfo = idp.rawInformation as {
name?: string;
firstName?: string;
lastName?: string;
email?: string;
};
return create(AddHumanUserRequestSchema, {
username: idp.userName,
email: {
email: rawInfo.email ?? "",
verification: { case: "isVerified", value: true },
},
profile: {
displayName: rawInfo.name ?? "",
givenName: rawInfo.firstName ?? "",
familyName: rawInfo.lastName ?? "",
},
idpLinks: [
{
idpId: idp.idpId,
userId: idp.userId,
userName: idp.userName,
},
],
});
},
};

View File

@@ -915,27 +915,6 @@ export async function startIdentityProviderFlow({
});
}
export async function retrieveIdentityProviderInformation({
serviceUrl,
idpIntentId,
idpIntentToken,
}: {
serviceUrl: string;
idpIntentId: string;
idpIntentToken: string;
}) {
const userService: Client<typeof UserService> = await createServiceForHost(
UserService,
serviceUrl,
);
return userService.retrieveIdentityProviderIntent({
idpIntentId,
idpIntentToken,
});
}
export async function getAuthRequest({
serviceUrl,
authRequestId,