@@ -52,6 +52,7 @@ import { dub } from "./dub";
5252import { validateSamlAccountConversion } from "./samlAccountLinking" ;
5353import CalComAdapter from "./next-auth-custom-adapter" ;
5454import { verifyPassword } from "./verifyPassword" ;
55+ import { UserProfile } from "@calcom/types/UserProfile" ;
5556
5657type UserWithProfiles = NonNullable <
5758 Awaited < ReturnType < UserRepository [ "findByEmailAndIncludeProfilesAndPassword" ] > >
@@ -274,6 +275,16 @@ export const CalComCredentialsProvider = CredentialsProvider({
274275} ) ;
275276
276277const providers : Provider [ ] = [ CalComCredentialsProvider , ImpersonationProvider ] ;
278+ type SamlIdpUser = {
279+ id : number ;
280+ userId : number ;
281+ firstName : string ;
282+ lastName : string ;
283+ email : string ;
284+ name : string ;
285+ email_verified : boolean ;
286+ profile : UserProfile ;
287+ } ;
277288
278289if ( IS_GOOGLE_LOGIN_ENABLED ) {
279290 providers . push (
@@ -356,7 +367,7 @@ if (isSAMLLoginEnabled) {
356367 credentials : {
357368 code : { } ,
358369 } ,
359- async authorize ( credentials ) {
370+ async authorize ( credentials ) : Promise < SamlIdpUser | null > {
360371 log . debug ( "CredentialsProvider:saml-idp:authorize" , safeStringify ( { credentials } ) ) ;
361372 if ( ! credentials ) {
362373 return null ;
@@ -418,7 +429,11 @@ if (isSAMLLoginEnabled) {
418429 }
419430 const [ userProfile ] = user ?. allProfiles ?? [ ] ;
420431 return {
432+ // This `id` is actually email as sent by the saml configuration of NameId=email
433+ // Instead of changing it, we introduce a new userId field to the object
434+ // Also, another reason to not touch it is that setting to to user.id starts breaking the saml-idp flow with an uncaught error something related to that it is expected to be a string
421435 id : id as unknown as number ,
436+ userId : user . id ,
422437 firstName,
423438 lastName,
424439 email,
@@ -622,7 +637,14 @@ export const getOptions = ({
622637 log . debug ( "callbacks:jwt:accountType:credentials" , safeStringify ( { account } ) ) ;
623638 // return token if credentials,saml-idp
624639 if ( account . provider === "saml-idp" ) {
625- return { ...token , upId : user . profile ?. upId ?? token . upId ?? null } as JWT ;
640+ const samlIdpUser = user as SamlIdpUser ;
641+ const updatedToken = {
642+ ...token ,
643+ // Server Session explicitly requires sub to be userId. So, override what is set by BoxyHQ
644+ sub : samlIdpUser . userId . toString ( ) ,
645+ upId : samlIdpUser . profile ?. upId ?? token . upId ?? null ,
646+ } as JWT ;
647+ return updatedToken ;
626648 }
627649 // any other credentials, add user info
628650 return {
0 commit comments