mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 02:51:51 +00:00
initial setup for google signin signup integration
This commit is contained in:
@@ -12,6 +12,8 @@ export const getJwtRefreshSecret = () => infisical.get('JWT_REFRESH_SECRET')!;
|
||||
export const getJwtServiceSecret = () => infisical.get('JWT_SERVICE_SECRET')!;
|
||||
export const getJwtSignupLifetime = () => infisical.get('JWT_SIGNUP_LIFETIME')! || '15m';
|
||||
export const getJwtSignupSecret = () => infisical.get('JWT_SIGNUP_SECRET')!;
|
||||
export const getJwtProviderAuthSecret = () => infisical.get('JWT_PROVIDER_AUTH_SECRET')!;
|
||||
export const getJwtProviderAuthLifetime = () => infisical.get('JWT_PROVIDER_AUTH_LIFETIME')! || '15m';
|
||||
export const getMongoURL = () => infisical.get('MONGO_URL')!;
|
||||
export const getNodeEnv = () => infisical.get('NODE_ENV')! || 'production';
|
||||
export const getVerboseErrorOutput = () => infisical.get('VERBOSE_ERROR_OUTPUT')! === 'true' && true;
|
||||
@@ -32,6 +34,7 @@ export const getClientSlugVercel = () => infisical.get('CLIENT_SLUG_VERCEL')!;
|
||||
export const getPostHogHost = () => infisical.get('POSTHOG_HOST')! || 'https://app.posthog.com';
|
||||
export const getPostHogProjectApiKey = () => infisical.get('POSTHOG_PROJECT_API_KEY')! || 'phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE';
|
||||
export const getSentryDSN = () => infisical.get('SENTRY_DSN')!;
|
||||
export const getSessionSecret = () => infisical.get('SESSION_SECRET')!;
|
||||
export const getSiteURL = () => infisical.get('SITE_URL')!;
|
||||
export const getSmtpHost = () => infisical.get('SMTP_HOST')!;
|
||||
export const getSmtpSecure = () => infisical.get('SMTP_SECURE')! === 'true' || false;
|
||||
|
||||
@@ -267,3 +267,7 @@ export const getNewToken = async (req: Request, res: Response) => {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const handleGoogleCallback = (req: Request, res: Response) => {
|
||||
res.redirect(`/login/provider/success?token=${encodeURIComponent(req.providerAuthToken)}`);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import infisical from 'infisical-node';
|
||||
import express from 'express';
|
||||
import helmet from 'helmet';
|
||||
import cors from 'cors';
|
||||
import session from 'express-session';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { DatabaseService } from './services';
|
||||
import { setUpHealthEndpoint } from './services/health';
|
||||
@@ -75,7 +76,7 @@ import {
|
||||
getPort,
|
||||
getSentryDSN,
|
||||
getSiteURL,
|
||||
getSmtpHost
|
||||
getSessionSecret,
|
||||
} from './config';
|
||||
|
||||
const main = async () => {
|
||||
@@ -111,6 +112,11 @@ const main = async () => {
|
||||
);
|
||||
|
||||
app.use(requestIp.mw());
|
||||
app.use(session({
|
||||
secret: getSessionSecret(),
|
||||
resave: false, // don't save session if unmodified
|
||||
saveUninitialized: false, // don't create session until something stored
|
||||
}));
|
||||
|
||||
if (getNodeEnv() === 'production') {
|
||||
// enable app-wide rate-limiting + helmet security
|
||||
|
||||
@@ -21,7 +21,7 @@ export const requestErrorHandler: ErrorRequestHandler = (error: RequestError | E
|
||||
|
||||
//* Set Sentry user identification if req.user is populated
|
||||
if (req.user !== undefined && req.user !== null) {
|
||||
Sentry.setUser({ email: req.user.email })
|
||||
Sentry.setUser({ email: (req.user as any).email })
|
||||
}
|
||||
//* Only sent error to Sentry if LogLevel is one of the following level 'ERROR', 'EMERGENCY' or 'CRITICAL'
|
||||
//* with this we will eliminate false-positive errors like 'BadRequestError', 'UnauthorizedRequestError' and so on
|
||||
|
||||
@@ -2,6 +2,8 @@ import { Schema, model, Types, Document } from 'mongoose';
|
||||
|
||||
export interface IUser extends Document {
|
||||
_id: Types.ObjectId;
|
||||
authId?: string;
|
||||
authProvider?: string;
|
||||
email: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
@@ -26,9 +28,15 @@ export interface IUser extends Document {
|
||||
|
||||
const userSchema = new Schema<IUser>(
|
||||
{
|
||||
authId: {
|
||||
type: String,
|
||||
},
|
||||
authProvider: {
|
||||
type: String,
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
firstName: {
|
||||
type: String
|
||||
|
||||
@@ -1,10 +1,50 @@
|
||||
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 } from '../../models';
|
||||
import { createToken } from '../../helpers/auth';
|
||||
import { getJwtProviderAuthLifetime, getJwtProviderAuthSecret } from '../../config';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const GoogleStrategy = require('passport-google-oidc');
|
||||
|
||||
passport.use(new GoogleStrategy({
|
||||
passReqToCallback: true,
|
||||
clientID: process.env['GOOGLE_CLIENT_ID'],
|
||||
clientSecret: process.env['GOOGLE_CLIENT_SECRET'],
|
||||
callbackURL: '/api/v1/auth/google/callback',
|
||||
}, async (req: express.Request, issuer: any, profile: any, cb: any) => {
|
||||
const email = profile.emails[0].value;
|
||||
let user = await User.findOne({
|
||||
authProvider: issuer,
|
||||
authId: profile.id,
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
user = await new User({
|
||||
email,
|
||||
authProvider: issuer,
|
||||
authId: profile.id,
|
||||
}).save();
|
||||
}
|
||||
|
||||
const providerAuthToken = createToken({
|
||||
payload: {
|
||||
userId: user._id.toString(),
|
||||
email: user.email,
|
||||
},
|
||||
expiresIn: getJwtProviderAuthLifetime(),
|
||||
secret: getJwtProviderAuthSecret(),
|
||||
});
|
||||
|
||||
req.providerAuthToken = providerAuthToken;
|
||||
cb(null, profile);
|
||||
}));
|
||||
|
||||
router.post('/token', validateRequest, authController.getNewToken);
|
||||
|
||||
@@ -27,20 +67,34 @@ router.post( // deprecated (moved to api/v2/auth/login2)
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/logout',
|
||||
'/logout',
|
||||
authLimiter,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
}),
|
||||
}),
|
||||
authController.logout
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/checkAuth',
|
||||
'/checkAuth',
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
}),
|
||||
}),
|
||||
authController.checkAuth
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/login/federated/google',
|
||||
authLimiter,
|
||||
passport.authenticate('google', {
|
||||
scope: ['profile', 'email'],
|
||||
}),
|
||||
)
|
||||
|
||||
router.get(
|
||||
'/google/callback',
|
||||
passport.authenticate('google', { failureRedirect: '/error', session: false }),
|
||||
authController.handleGoogleCallback,
|
||||
)
|
||||
|
||||
export default router;
|
||||
|
||||
Vendored
+7
@@ -9,6 +9,12 @@ import {
|
||||
AuthData
|
||||
} from '../../interfaces/middleware';
|
||||
|
||||
declare module 'express' {
|
||||
interface Request {
|
||||
user?: any;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix (any) types
|
||||
declare global {
|
||||
namespace Express {
|
||||
@@ -18,6 +24,7 @@ declare global {
|
||||
workspace: any;
|
||||
membership: any;
|
||||
targetMembership: any;
|
||||
providerAuthToken: any;
|
||||
organization: any;
|
||||
membershipOrg: any;
|
||||
integration: any;
|
||||
|
||||
Reference in New Issue
Block a user