mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 16:26:16 +00:00
Revise and finish login with GitHub
This commit is contained in:
@@ -36,7 +36,6 @@ export const getClientIdVercel = async () => (await client.getSecret("CLIENT_ID_
|
||||
export const getClientIdNetlify = async () => (await client.getSecret("CLIENT_ID_NETLIFY")).secretValue;
|
||||
export const getClientIdGitHub = async () => (await client.getSecret("CLIENT_ID_GITHUB")).secretValue;
|
||||
export const getClientIdGitLab = async () => (await client.getSecret("CLIENT_ID_GITLAB")).secretValue;
|
||||
export const getClientIdGoogle = async () => (await client.getSecret("CLIENT_ID_GOOGLE")).secretValue;
|
||||
export const getClientIdBitBucket = async () => (await client.getSecret("CLIENT_ID_BITBUCKET")).secretValue;
|
||||
export const getClientSecretAzure = async () => (await client.getSecret("CLIENT_SECRET_AZURE")).secretValue;
|
||||
export const getClientSecretHeroku = async () => (await client.getSecret("CLIENT_SECRET_HEROKU")).secretValue;
|
||||
@@ -44,9 +43,14 @@ export const getClientSecretVercel = async () => (await client.getSecret("CLIENT
|
||||
export const getClientSecretNetlify = async () => (await client.getSecret("CLIENT_SECRET_NETLIFY")).secretValue;
|
||||
export const getClientSecretGitHub = async () => (await client.getSecret("CLIENT_SECRET_GITHUB")).secretValue;
|
||||
export const getClientSecretGitLab = async () => (await client.getSecret("CLIENT_SECRET_GITLAB")).secretValue;
|
||||
export const getClientSecretGoogle = async () => (await client.getSecret("CLIENT_SECRET_GOOGLE")).secretValue;
|
||||
export const getClientSecretBitBucket = async () => (await client.getSecret("CLIENT_SECRET_BITBUCKET")).secretValue;
|
||||
export const getClientSlugVercel = async () => (await client.getSecret("CLIENT_SLUG_VERCEL")).secretValue;
|
||||
|
||||
export const getClientIdGoogleLogin = async () => (await client.getSecret("CLIENT_ID_GOOGLE_LOGIN")).secretValue;
|
||||
export const getClientSecretGoogleLogin = async () => (await client.getSecret("CLIENT_SECRET_GOOGLE_LOGIN")).secretValue;
|
||||
export const getClientIdGitHubLogin = async () => (await client.getSecret("CLIENT_ID_GITHUB_LOGIN")).secretValue;
|
||||
export const getClientSecretGitHubLogin = async () => (await client.getSecret("CLIENT_SECRET_GITHUB_LOGIN")).secretValue;
|
||||
|
||||
export const getPostHogHost = async () => (await client.getSecret("POSTHOG_HOST")).secretValue || "https://app.posthog.com";
|
||||
export const getPostHogProjectApiKey = async () => (await client.getSecret("POSTHOG_PROJECT_API_KEY")).secretValue || "phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE";
|
||||
export const getSentryDSN = async () => (await client.getSecret("SENTRY_DSN")).secretValue;
|
||||
|
||||
@@ -123,9 +123,15 @@ export const updateAuthProvider = async (req: Request, res: Response) => {
|
||||
authProvider
|
||||
} = req.body;
|
||||
|
||||
if (req.user?.authProvider === AuthProvider.OKTA_SAML) return res.status(400).send({
|
||||
message: "Failed to update user authentication method because SAML SSO is enforced"
|
||||
});
|
||||
if (
|
||||
req.user?.authProvider === AuthProvider.OKTA_SAML
|
||||
|| req.user?.authProvider === AuthProvider.AZURE_SAML
|
||||
|| req.user?.authProvider === AuthProvider.JUMPCLOUD_SAML
|
||||
) {
|
||||
return res.status(400).send({
|
||||
message: "Failed to update user authentication method because SAML SSO is enforced"
|
||||
});
|
||||
}
|
||||
|
||||
const user = await User.findByIdAndUpdate(
|
||||
req.user._id.toString(),
|
||||
|
||||
@@ -41,6 +41,29 @@ router.get(
|
||||
ssoController.redirectSSO
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/redirect/github",
|
||||
authLimiter,
|
||||
(req, res, next) => {
|
||||
passport.authenticate("github", {
|
||||
session: false,
|
||||
...(req.query.callback_port ? {
|
||||
state: req.query.callback_port as string
|
||||
} : {})
|
||||
})(req, res, next);
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/github",
|
||||
authLimiter,
|
||||
passport.authenticate("github", {
|
||||
failureRedirect: "/login/provider/error",
|
||||
session: false
|
||||
}),
|
||||
ssoController.redirectSSO
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/redirect/saml2/:ssoIdentifier",
|
||||
authLimiter,
|
||||
|
||||
@@ -1,66 +1,10 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import { body } from "express-validator";
|
||||
import passport from "passport";
|
||||
import { requireAuth, validateRequest } from "../../middleware";
|
||||
import { authController } from "../../controllers/v1";
|
||||
import { authLimiter } from "../../helpers/rateLimiter";
|
||||
import { AUTH_MODE_JWT } from "../../variables";
|
||||
import { User, AuthProvider } from '../../models';
|
||||
import { createToken } from '../../helpers/auth';
|
||||
import { getJwtProviderAuthLifetime, getJwtProviderAuthSecret } from '../../config';
|
||||
import { ssoController } from "../../ee/controllers/v1";
|
||||
|
||||
var GitHubStrategy = require('passport-github').Strategy;
|
||||
passport.use(new GitHubStrategy({
|
||||
passReqToCallback: true,
|
||||
clientID: process.env['CLIENT_ID_GITHUB_LOGIN'],
|
||||
clientSecret: process.env['CLIENT_SECRET_GITHUB'],
|
||||
callbackURL: "/api/v1/auth/github/callback"
|
||||
},
|
||||
async (req : express.Request, accessToken : any, refreshToken : any, profile : any, cb : any) => {
|
||||
const email = profile.emails[0].value;
|
||||
let user = await User.findOne({
|
||||
email
|
||||
});
|
||||
if (!user) {
|
||||
user = await new User({
|
||||
email: email,
|
||||
authProvider: AuthProvider.GITHUB,
|
||||
authId: profile.id,
|
||||
firstName: profile.displayName,
|
||||
}).save();
|
||||
}
|
||||
const isUserCompleted = true;
|
||||
const providerAuthToken = createToken({
|
||||
payload: {
|
||||
userId: profile.id.toString(),
|
||||
email: email,
|
||||
isUserCompleted,
|
||||
...(req.query.state ? {
|
||||
callbackPort: req.query.state as string
|
||||
} : {})
|
||||
},
|
||||
expiresIn: await getJwtProviderAuthLifetime(),
|
||||
secret: await getJwtProviderAuthSecret(),
|
||||
});
|
||||
req.isUserCompleted = isUserCompleted;
|
||||
req.providerAuthToken = providerAuthToken;
|
||||
return cb(null, profile);
|
||||
}
|
||||
));
|
||||
|
||||
router.get('/github', passport.authenticate('github', { failureRedirect: '/login/provider/error', session: false }), ssoController.redirectSSO);
|
||||
|
||||
router.get('/github/callback',
|
||||
passport.authenticate('github', { failureRedirect: '/login/provider/error', session: false }
|
||||
),
|
||||
function(req, res, next) {
|
||||
// Successful authentication, redirect home.
|
||||
console.log("github success");
|
||||
res.redirect(`/login/sso?token=${encodeURIComponent(req.providerAuthToken)}`);
|
||||
next();
|
||||
});
|
||||
|
||||
router.post("/token", validateRequest, authController.getNewToken);
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ router.patch(
|
||||
}),
|
||||
body("authProvider").exists().isString().isIn([
|
||||
AuthProvider.EMAIL,
|
||||
AuthProvider.GOOGLE
|
||||
AuthProvider.GOOGLE,
|
||||
AuthProvider.GITHUB
|
||||
]),
|
||||
validateRequest,
|
||||
usersController.updateAuthProvider
|
||||
|
||||
+90
-32
@@ -12,8 +12,10 @@ import {
|
||||
} from "../models";
|
||||
import { createToken } from "../helpers/auth";
|
||||
import {
|
||||
getClientIdGoogle,
|
||||
getClientSecretGoogle,
|
||||
getClientIdGitHubLogin,
|
||||
getClientIdGoogleLogin,
|
||||
getClientSecretGitHubLogin,
|
||||
getClientSecretGoogleLogin,
|
||||
getJwtProviderAuthLifetime,
|
||||
getJwtProviderAuthSecret,
|
||||
} from "../config";
|
||||
@@ -25,6 +27,8 @@ import { getSiteURL } from "../config";
|
||||
// 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 GitHubStrategy = require("passport-github").Strategy;
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { MultiSamlStrategy } = require("@node-saml/passport-saml");
|
||||
|
||||
/**
|
||||
@@ -67,42 +71,97 @@ const getAuthDataPayloadUserObj = (authData: AuthData) => {
|
||||
}
|
||||
|
||||
const initializePassport = async () => {
|
||||
const googleClientSecret = await getClientSecretGoogle();
|
||||
const googleClientId = await getClientIdGoogle();
|
||||
const clientIdGoogleLogin = await getClientIdGoogleLogin();
|
||||
const clientSecretGoogleLogin = await getClientSecretGoogleLogin();
|
||||
const clientIdGitHubLogin = await getClientIdGitHubLogin();
|
||||
const clientSecretGitHubLogin = await getClientSecretGitHubLogin();
|
||||
|
||||
passport.use(new GoogleStrategy({
|
||||
passReqToCallback: true,
|
||||
clientID: googleClientId,
|
||||
clientSecret: googleClientSecret,
|
||||
callbackURL: "/api/v1/sso/google",
|
||||
scope: ["profile", " email"],
|
||||
}, async (
|
||||
req: express.Request,
|
||||
accessToken: string,
|
||||
refreshToken: string,
|
||||
profile: any,
|
||||
done: any
|
||||
) => {
|
||||
try {
|
||||
if (clientIdGoogleLogin && clientSecretGoogleLogin) {
|
||||
passport.use(new GoogleStrategy({
|
||||
passReqToCallback: true,
|
||||
clientID: clientIdGoogleLogin,
|
||||
clientSecret: clientSecretGoogleLogin,
|
||||
callbackURL: "/api/v1/sso/google",
|
||||
scope: ["profile", " email"],
|
||||
}, async (
|
||||
req: express.Request,
|
||||
accessToken: string,
|
||||
refreshToken: string,
|
||||
profile: any,
|
||||
done: any
|
||||
) => {
|
||||
try {
|
||||
const email = profile.emails[0].value;
|
||||
|
||||
let user = await User.findOne({
|
||||
email
|
||||
}).select("+publicKey");
|
||||
|
||||
if (user && user.authProvider !== AuthProvider.GOOGLE) {
|
||||
done(InternalServerError());
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
user = await new User({
|
||||
email,
|
||||
authProvider: AuthProvider.GOOGLE,
|
||||
authId: profile.id,
|
||||
firstName: profile.name.givenName,
|
||||
lastName: profile.name.familyName
|
||||
}).save();
|
||||
}
|
||||
|
||||
const isUserCompleted = !!user.publicKey;
|
||||
const providerAuthToken = createToken({
|
||||
payload: {
|
||||
userId: user._id.toString(),
|
||||
email: user.email,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
authProvider: user.authProvider,
|
||||
isUserCompleted,
|
||||
...(req.query.state ? {
|
||||
callbackPort: req.query.state as string
|
||||
} : {})
|
||||
},
|
||||
expiresIn: await getJwtProviderAuthLifetime(),
|
||||
secret: await getJwtProviderAuthSecret(),
|
||||
});
|
||||
|
||||
req.isUserCompleted = isUserCompleted;
|
||||
req.providerAuthToken = providerAuthToken;
|
||||
done(null, profile);
|
||||
} catch (err) {
|
||||
done(null, false);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (clientIdGitHubLogin && clientSecretGitHubLogin) {
|
||||
passport.use(new GitHubStrategy({
|
||||
passReqToCallback: true,
|
||||
clientID: clientIdGitHubLogin,
|
||||
clientSecret: clientSecretGitHubLogin,
|
||||
callbackURL: "/api/v1/sso/github"
|
||||
},
|
||||
async (req : express.Request, accessToken : any, refreshToken : any, profile : any, done : any) => {
|
||||
const email = profile.emails[0].value;
|
||||
const firstName = profile.name.givenName;
|
||||
const lastName = profile.name.familyName;
|
||||
|
||||
let user = await User.findOne({
|
||||
email
|
||||
}).select("+publicKey");
|
||||
|
||||
if (user && user.authProvider !== AuthProvider.GOOGLE) {
|
||||
if (user && user.authProvider !== AuthProvider.GITHUB) {
|
||||
done(InternalServerError());
|
||||
}
|
||||
|
||||
|
||||
if (!user) {
|
||||
user = await new User({
|
||||
email,
|
||||
authProvider: AuthProvider.GOOGLE,
|
||||
email: email,
|
||||
authProvider: AuthProvider.GITHUB,
|
||||
authId: profile.id,
|
||||
firstName,
|
||||
lastName
|
||||
firstName: profile.displayName,
|
||||
lastName: ""
|
||||
}).save();
|
||||
}
|
||||
|
||||
@@ -111,8 +170,8 @@ const initializePassport = async () => {
|
||||
payload: {
|
||||
userId: user._id.toString(),
|
||||
email: user.email,
|
||||
firstName,
|
||||
lastName,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
authProvider: user.authProvider,
|
||||
isUserCompleted,
|
||||
...(req.query.state ? {
|
||||
@@ -125,11 +184,10 @@ const initializePassport = async () => {
|
||||
|
||||
req.isUserCompleted = isUserCompleted;
|
||||
req.providerAuthToken = providerAuthToken;
|
||||
done(null, profile);
|
||||
} catch (err) {
|
||||
done(null, false);
|
||||
return done(null, profile);
|
||||
}
|
||||
}));
|
||||
));
|
||||
}
|
||||
|
||||
passport.use("saml", new MultiSamlStrategy(
|
||||
{
|
||||
|
||||
@@ -24,8 +24,6 @@ import {
|
||||
reencryptSecretBlindIndexDataSalts
|
||||
} from "./reencryptData";
|
||||
import {
|
||||
getClientIdGoogle,
|
||||
getClientSecretGoogle,
|
||||
getMongoURL,
|
||||
getNodeEnv,
|
||||
getSentryDSN
|
||||
@@ -55,12 +53,7 @@ export const setup = async () => {
|
||||
// initializing the database connection
|
||||
await DatabaseService.initDatabase(await getMongoURL());
|
||||
|
||||
const googleClientSecret: string = await getClientSecretGoogle();
|
||||
const googleClientId: string = await getClientIdGoogle();
|
||||
|
||||
if (googleClientId && googleClientSecret) {
|
||||
await initializePassport();
|
||||
}
|
||||
await initializePassport();
|
||||
|
||||
// re-encrypt any data previously encrypted under server hex 128-bit ENCRYPTION_KEY
|
||||
// to base64 256-bit ROOT_ENCRYPTION_KEY
|
||||
|
||||
Reference in New Issue
Block a user