From 960aceed29953d18563b4790cb05de47b091918a Mon Sep 17 00:00:00 2001 From: Juned Khan Date: Wed, 2 Aug 2023 21:28:35 +0530 Subject: [PATCH] initial-setup for github signin --- backend/package-lock.json | 20 +++++++++++++ backend/package.json | 1 + backend/src/models/user.ts | 1 + backend/src/routes/v1/auth.ts | 56 +++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/backend/package-lock.json b/backend/package-lock.json index 2ac9b89ae..6039205d2 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -45,6 +45,7 @@ "node-cache": "^5.1.2", "nodemailer": "^6.8.0", "passport": "^0.6.0", + "passport-github": "^1.1.0", "passport-google-oauth20": "^2.0.0", "posthog-node": "^2.6.0", "probot": "^12.3.1", @@ -11385,6 +11386,17 @@ "url": "https://github.com/sponsors/jaredhanson" } }, + "node_modules/passport-github": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/passport-github/-/passport-github-1.1.0.tgz", + "integrity": "sha512-XARXJycE6fFh/dxF+Uut8OjlwbFEXgbPVj/+V+K7cvriRK7VcAOm+NgBmbiLM9Qv3SSxEAV+V6fIk89nYHXa8A==", + "dependencies": { + "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/passport-google-oauth20": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", @@ -22858,6 +22870,14 @@ "utils-merge": "^1.0.1" } }, + "passport-github": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/passport-github/-/passport-github-1.1.0.tgz", + "integrity": "sha512-XARXJycE6fFh/dxF+Uut8OjlwbFEXgbPVj/+V+K7cvriRK7VcAOm+NgBmbiLM9Qv3SSxEAV+V6fIk89nYHXa8A==", + "requires": { + "passport-oauth2": "1.x.x" + } + }, "passport-google-oauth20": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", diff --git a/backend/package.json b/backend/package.json index d65f537da..b4251eea0 100644 --- a/backend/package.json +++ b/backend/package.json @@ -36,6 +36,7 @@ "node-cache": "^5.1.2", "nodemailer": "^6.8.0", "passport": "^0.6.0", + "passport-github": "^1.1.0", "passport-google-oauth20": "^2.0.0", "posthog-node": "^2.6.0", "probot": "^12.3.1", diff --git a/backend/src/models/user.ts b/backend/src/models/user.ts index 0332f05ee..fb14e8b8a 100644 --- a/backend/src/models/user.ts +++ b/backend/src/models/user.ts @@ -3,6 +3,7 @@ import { Document, Schema, Types, model } from "mongoose"; export enum AuthProvider { EMAIL = "email", GOOGLE = "google", + GITHUB = "github", OKTA_SAML = "okta-saml", AZURE_SAML = "azure-saml", JUMPCLOUD_SAML = "jumpcloud-saml", diff --git a/backend/src/routes/v1/auth.ts b/backend/src/routes/v1/auth.ts index ae85aa36c..f6d90c804 100644 --- a/backend/src/routes/v1/auth.ts +++ b/backend/src/routes/v1/auth.ts @@ -1,10 +1,66 @@ 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);