mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 22:27:48 +00:00
Integrated login with Gitlab
This commit is contained in:
@@ -13,8 +13,10 @@ import {
|
|||||||
import { createToken } from "../helpers/auth";
|
import { createToken } from "../helpers/auth";
|
||||||
import {
|
import {
|
||||||
getClientIdGitHubLogin,
|
getClientIdGitHubLogin,
|
||||||
|
getClientIdGitLabLogin,
|
||||||
getClientIdGoogleLogin,
|
getClientIdGoogleLogin,
|
||||||
getClientSecretGitHubLogin,
|
getClientSecretGitHubLogin,
|
||||||
|
getClientSecretGitLabLogin,
|
||||||
getClientSecretGoogleLogin,
|
getClientSecretGoogleLogin,
|
||||||
getJwtProviderAuthLifetime,
|
getJwtProviderAuthLifetime,
|
||||||
getJwtProviderAuthSecret,
|
getJwtProviderAuthSecret,
|
||||||
@@ -29,6 +31,8 @@ const GoogleStrategy = require("passport-google-oauth20").Strategy;
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const GitHubStrategy = require("passport-github").Strategy;
|
const GitHubStrategy = require("passport-github").Strategy;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const GitLabStrategy = require("passport-gitlab2").Strategy;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const { MultiSamlStrategy } = require("@node-saml/passport-saml");
|
const { MultiSamlStrategy } = require("@node-saml/passport-saml");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +79,8 @@ const initializePassport = async () => {
|
|||||||
const clientSecretGoogleLogin = await getClientSecretGoogleLogin();
|
const clientSecretGoogleLogin = await getClientSecretGoogleLogin();
|
||||||
const clientIdGitHubLogin = await getClientIdGitHubLogin();
|
const clientIdGitHubLogin = await getClientIdGitHubLogin();
|
||||||
const clientSecretGitHubLogin = await getClientSecretGitHubLogin();
|
const clientSecretGitHubLogin = await getClientSecretGitHubLogin();
|
||||||
|
const clientIdGitLabLogin = await getClientIdGitLabLogin();
|
||||||
|
const clientSecretGitLabLogin = await getClientSecretGitLabLogin();
|
||||||
|
|
||||||
if (clientIdGoogleLogin && clientSecretGoogleLogin) {
|
if (clientIdGoogleLogin && clientSecretGoogleLogin) {
|
||||||
passport.use(new GoogleStrategy({
|
passport.use(new GoogleStrategy({
|
||||||
@@ -190,6 +196,59 @@ const initializePassport = async () => {
|
|||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientIdGitLabLogin && clientSecretGitLabLogin) {
|
||||||
|
passport.use(new GitLabStrategy({
|
||||||
|
passReqToCallback: true,
|
||||||
|
clientID: clientIdGitLabLogin,
|
||||||
|
clientSecret: clientSecretGitLabLogin,
|
||||||
|
callbackURL: "/api/v1/sso/gitlab"
|
||||||
|
},
|
||||||
|
async (req : express.Request, accessToken : any, refreshToken : any, profile : any, done : any) => {
|
||||||
|
const email = profile.emails[0].value;
|
||||||
|
|
||||||
|
let user = await User.findOne({
|
||||||
|
email
|
||||||
|
}).select("+publicKey");
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
user = await new User({
|
||||||
|
email: email,
|
||||||
|
authMethods: [AuthMethod.GITLAB],
|
||||||
|
firstName: profile.displayName,
|
||||||
|
lastName: ""
|
||||||
|
}).save();
|
||||||
|
}
|
||||||
|
|
||||||
|
let isLinkingRequired = false;
|
||||||
|
if (!user.authMethods.includes(AuthMethod.GITLAB)) {
|
||||||
|
isLinkingRequired = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isUserCompleted = !!user.publicKey;
|
||||||
|
const providerAuthToken = createToken({
|
||||||
|
payload: {
|
||||||
|
userId: user._id.toString(),
|
||||||
|
email: user.email,
|
||||||
|
firstName: user.firstName,
|
||||||
|
lastName: user.lastName,
|
||||||
|
authMethod: AuthMethod.GITLAB,
|
||||||
|
isUserCompleted,
|
||||||
|
isLinkingRequired,
|
||||||
|
...(req.query.state ? {
|
||||||
|
callbackPort: req.query.state as string
|
||||||
|
} : {})
|
||||||
|
},
|
||||||
|
expiresIn: await getJwtProviderAuthLifetime(),
|
||||||
|
secret: await getJwtProviderAuthSecret(),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.isUserCompleted = isUserCompleted;
|
||||||
|
req.providerAuthToken = providerAuthToken;
|
||||||
|
return done(null, profile);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
passport.use("saml", new MultiSamlStrategy(
|
passport.use("saml", new MultiSamlStrategy(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { faGithub,faGoogle } from "@fortawesome/free-brands-svg-icons";
|
import { faGithub, faGitlab, faGoogle } from "@fortawesome/free-brands-svg-icons";
|
||||||
import { faEnvelope } from "@fortawesome/free-regular-svg-icons";
|
import { faEnvelope } from "@fortawesome/free-regular-svg-icons";
|
||||||
import { faLock } from "@fortawesome/free-solid-svg-icons";
|
import { faLock } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
@@ -9,74 +9,94 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { Button } from "../v2";
|
import { Button } from "../v2";
|
||||||
|
|
||||||
export default function InitialSignupStep({
|
export default function InitialSignupStep({
|
||||||
setIsSignupWithEmail,
|
setIsSignupWithEmail
|
||||||
}: {
|
}: {
|
||||||
setIsSignupWithEmail: (value: boolean) => void
|
setIsSignupWithEmail: (value: boolean) => void;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return <div className='flex flex-col mx-auto w-full justify-center items-center'>
|
return (
|
||||||
<h1 className='text-xl font-medium text-transparent bg-clip-text bg-gradient-to-b from-white to-bunker-200 text-center mb-8' >{t("signup.initial-title")}</h1>
|
<div className="mx-auto flex w-full flex-col items-center justify-center">
|
||||||
<div className='lg:w-1/6 w-1/4 min-w-[20rem] rounded-md'>
|
<h1 className="mb-8 bg-gradient-to-b from-white to-bunker-200 bg-clip-text text-center text-xl font-medium text-transparent">
|
||||||
<Button
|
{t("signup.initial-title")}
|
||||||
colorSchema="primary"
|
</h1>
|
||||||
variant="solid"
|
<div className="w-1/4 min-w-[20rem] rounded-md lg:w-1/6">
|
||||||
onClick={() => {
|
<Button
|
||||||
window.open("/api/v1/sso/redirect/google");
|
colorSchema="primary"
|
||||||
window.close();
|
variant="solid"
|
||||||
}}
|
onClick={() => {
|
||||||
leftIcon={<FontAwesomeIcon icon={faGoogle} className="mr-2" />}
|
window.open("/api/v1/sso/redirect/google");
|
||||||
className="h-12 w-full mx-0"
|
window.close();
|
||||||
>
|
}}
|
||||||
{t("signup.continue-with-google")}
|
leftIcon={<FontAwesomeIcon icon={faGoogle} className="mr-2" />}
|
||||||
</Button>
|
className="mx-0 h-12 w-full"
|
||||||
</div>
|
>
|
||||||
<div className='lg:w-1/6 w-1/4 min-w-[20rem] rounded-md mt-4'>
|
{t("signup.continue-with-google")}
|
||||||
<Button
|
</Button>
|
||||||
colorSchema="primary"
|
</div>
|
||||||
variant="outline_bg"
|
<div className="mt-4 w-1/4 min-w-[20rem] rounded-md lg:w-1/6">
|
||||||
onClick={() => {
|
<Button
|
||||||
window.open("/api/v1/sso/redirect/github");
|
colorSchema="primary"
|
||||||
window.close();
|
variant="outline_bg"
|
||||||
}}
|
onClick={() => {
|
||||||
leftIcon={<FontAwesomeIcon icon={faGithub} className="mr-2" />}
|
window.open("/api/v1/sso/redirect/github");
|
||||||
className="h-12 w-full mx-0"
|
window.close();
|
||||||
>
|
}}
|
||||||
Continue with GitHub
|
leftIcon={<FontAwesomeIcon icon={faGithub} className="mr-2" />}
|
||||||
</Button>
|
className="mx-0 h-12 w-full"
|
||||||
</div>
|
>
|
||||||
<div className='lg:w-1/6 w-1/4 min-w-[20rem] text-center rounded-md mt-4'>
|
Continue with GitHub
|
||||||
<Button
|
</Button>
|
||||||
colorSchema="primary"
|
</div>
|
||||||
variant="outline_bg"
|
<div className="mt-4 w-1/4 min-w-[20rem] rounded-md lg:w-1/6">
|
||||||
onClick={() => {
|
<Button
|
||||||
setIsSignupWithEmail(true);
|
colorSchema="primary"
|
||||||
}}
|
variant="outline_bg"
|
||||||
leftIcon={<FontAwesomeIcon icon={faEnvelope} className="mr-2" />}
|
onClick={() => {
|
||||||
className="h-12 w-full mx-0"
|
window.open("/api/v1/sso/redirect/gitlab");
|
||||||
>
|
window.close();
|
||||||
Continue with Email
|
}}
|
||||||
</Button>
|
leftIcon={<FontAwesomeIcon icon={faGitlab} className="mr-2" />}
|
||||||
</div>
|
className="mx-0 h-12 w-full"
|
||||||
<div className='lg:w-1/6 w-1/4 min-w-[20rem] text-center rounded-md mt-4'>
|
>
|
||||||
<Button
|
Continue with GitLab
|
||||||
colorSchema="primary"
|
</Button>
|
||||||
variant="outline_bg"
|
</div>
|
||||||
onClick={() => router.push("/saml-sso")}
|
<div className="mt-4 w-1/4 min-w-[20rem] rounded-md text-center lg:w-1/6">
|
||||||
leftIcon={<FontAwesomeIcon icon={faLock} className="mr-2" />}
|
<Button
|
||||||
className="h-12 w-full mx-0"
|
colorSchema="primary"
|
||||||
>
|
variant="outline_bg"
|
||||||
Continue with SSO
|
onClick={() => {
|
||||||
</Button>
|
setIsSignupWithEmail(true);
|
||||||
</div>
|
}}
|
||||||
<div className='lg:w-1/6 w-1/4 min-w-[20rem] px-8 text-center mt-6 text-xs text-bunker-400'>
|
leftIcon={<FontAwesomeIcon icon={faEnvelope} className="mr-2" />}
|
||||||
{t("signup.create-policy")}
|
className="mx-0 h-12 w-full"
|
||||||
</div>
|
>
|
||||||
<div className="mt-2 text-bunker-400 text-xs flex flex-row">
|
Continue with Email
|
||||||
<Link href="/login">
|
</Button>
|
||||||
<span className='hover:underline hover:underline-offset-4 hover:decoration-primary-700 hover:text-bunker-200 duration-200 cursor-pointer'>{t("signup.already-have-account")}</span>
|
</div>
|
||||||
</Link>
|
<div className="mt-4 w-1/4 min-w-[20rem] rounded-md text-center lg:w-1/6">
|
||||||
</div>
|
<Button
|
||||||
|
colorSchema="primary"
|
||||||
|
variant="outline_bg"
|
||||||
|
onClick={() => router.push("/saml-sso")}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faLock} className="mr-2" />}
|
||||||
|
className="mx-0 h-12 w-full"
|
||||||
|
>
|
||||||
|
Continue with SSO
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mt-6 w-1/4 min-w-[20rem] px-8 text-center text-xs text-bunker-400 lg:w-1/6">
|
||||||
|
{t("signup.create-policy")}
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex flex-row text-xs text-bunker-400">
|
||||||
|
<Link href="/login">
|
||||||
|
<span className="cursor-pointer duration-200 hover:text-bunker-200 hover:underline hover:decoration-primary-700 hover:underline-offset-4">
|
||||||
|
{t("signup.already-have-account")}
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user