This commit is contained in:
Tuan Dang
2023-07-19 22:23:48 +07:00
parent dfcd6b1efd
commit 846e2e037f
88 changed files with 4557 additions and 2320 deletions
+87 -2
View File
@@ -1,11 +1,14 @@
import express from "express";
import passport from "passport";
import { Types } from "mongoose";
import { AuthData } from "../interfaces/middleware";
import {
AuthProvider,
ServiceAccount,
ServiceTokenData,
User,
Organization,
MembershipOrg
} from "../models";
import { createToken } from "../helpers/auth";
import {
@@ -14,9 +17,14 @@ import {
getJwtProviderAuthLifetime,
getJwtProviderAuthSecret,
} from "../config";
import { getSSOConfigHelper } from "../ee/helpers/organizations";
import { OrganizationNotFoundError } from "./errors";
import { MEMBER, INVITED } from "../variables";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const GoogleStrategy = require("passport-google-oauth20").Strategy;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { MultiSamlStrategy } = require("@node-saml/passport-saml");
// TODO: find a more optimal folder structure to store these types of functions
@@ -39,7 +47,6 @@ const getAuthDataPayloadIdObj = (authData: AuthData) => {
}
};
/**
* Returns an object containing the user associated with the authentication data payload
* @param {AuthData} authData - authentication data object
@@ -56,7 +63,7 @@ const getAuthDataPayloadUserObj = (authData: AuthData) => {
}
if (authData.authPayload instanceof ServiceTokenData) {
return { user: authData.authPayload.user };
return { user: authData.authPayload.user };0
}
}
@@ -109,6 +116,84 @@ const initializePassport = async () => {
cb(null, false);
}
}));
passport.use("saml", new MultiSamlStrategy(
{
passReqToCallback: true,
getSamlOptions: async (req: any, done: any) => {
const { ssoIdentifier } = req.params;
const ssoConfig = await getSSOConfigHelper({
ssoConfigId: new Types.ObjectId(ssoIdentifier)
});
const samlConfig = ({
path: "/api/v1/auth/callback/saml",
callbackURL: "http://localhost:8080/api/v1/auth/callback/saml", // TODO: get rid of localhost:8080 here
entryPoint: ssoConfig.entryPoint,
issuer: ssoConfig.issuer,
cert: ssoConfig.cert,
audience: ssoConfig.audience
});
req.ssoConfig = ssoConfig;
done(null, samlConfig);
},
},
async (req: any, profile: any, done: any) => {
const organization = await Organization.findById(req.ssoConfig.organization);
if (!organization) done(OrganizationNotFoundError());
const email = profile.email;
const firstName = profile.firstName;
const lastName = profile.lastName;
let user = await User.findOne({
authProvider: AuthProvider.OKTA_SAML,
email
}).select("+publicKey");
if (!user) {
user = await new User({
email,
authProvider: AuthProvider.OKTA_SAML,
firstName,
lastName
}).save();
await new MembershipOrg({
inviteEmail: email,
user: user._id,
organization: organization?._id,
role: MEMBER,
status: INVITED
}).save();
}
const isUserCompleted = !!user.publicKey;
const providerAuthToken = createToken({
payload: {
userId: user._id.toString(),
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
organizationName: organization?.name,
authProvider: user.authProvider,
isUserCompleted
},
expiresIn: await getJwtProviderAuthLifetime(),
secret: await getJwtProviderAuthSecret(),
});
req.isUserCompleted = isUserCompleted;
req.providerAuthToken = providerAuthToken;
done(null, profile);
}
));
}
export {