Merge pull request #818 from JunedKhan101/feature-github-signin

initial-setup for github signin
This commit is contained in:
BlackMagiq
2023-08-03 15:44:15 +07:00
committed by GitHub
13 changed files with 288 additions and 120 deletions
+20
View File
@@ -45,6 +45,7 @@
"node-cache": "^5.1.2", "node-cache": "^5.1.2",
"nodemailer": "^6.8.0", "nodemailer": "^6.8.0",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-github": "^1.1.0",
"passport-google-oauth20": "^2.0.0", "passport-google-oauth20": "^2.0.0",
"posthog-node": "^2.6.0", "posthog-node": "^2.6.0",
"probot": "^12.3.1", "probot": "^12.3.1",
@@ -11385,6 +11386,17 @@
"url": "https://github.com/sponsors/jaredhanson" "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": { "node_modules/passport-google-oauth20": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
@@ -22858,6 +22870,14 @@
"utils-merge": "^1.0.1" "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": { "passport-google-oauth20": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
+1
View File
@@ -36,6 +36,7 @@
"node-cache": "^5.1.2", "node-cache": "^5.1.2",
"nodemailer": "^6.8.0", "nodemailer": "^6.8.0",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-github": "^1.1.0",
"passport-google-oauth20": "^2.0.0", "passport-google-oauth20": "^2.0.0",
"posthog-node": "^2.6.0", "posthog-node": "^2.6.0",
"probot": "^12.3.1", "probot": "^12.3.1",
+6 -2
View File
@@ -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 getClientIdNetlify = async () => (await client.getSecret("CLIENT_ID_NETLIFY")).secretValue;
export const getClientIdGitHub = async () => (await client.getSecret("CLIENT_ID_GITHUB")).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 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 getClientIdBitBucket = async () => (await client.getSecret("CLIENT_ID_BITBUCKET")).secretValue;
export const getClientSecretAzure = async () => (await client.getSecret("CLIENT_SECRET_AZURE")).secretValue; export const getClientSecretAzure = async () => (await client.getSecret("CLIENT_SECRET_AZURE")).secretValue;
export const getClientSecretHeroku = async () => (await client.getSecret("CLIENT_SECRET_HEROKU")).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 getClientSecretNetlify = async () => (await client.getSecret("CLIENT_SECRET_NETLIFY")).secretValue;
export const getClientSecretGitHub = async () => (await client.getSecret("CLIENT_SECRET_GITHUB")).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 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 getClientSecretBitBucket = async () => (await client.getSecret("CLIENT_SECRET_BITBUCKET")).secretValue;
export const getClientSlugVercel = async () => (await client.getSecret("CLIENT_SLUG_VERCEL")).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 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 getPostHogProjectApiKey = async () => (await client.getSecret("POSTHOG_PROJECT_API_KEY")).secretValue || "phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE";
export const getSentryDSN = async () => (await client.getSecret("SENTRY_DSN")).secretValue; export const getSentryDSN = async () => (await client.getSecret("SENTRY_DSN")).secretValue;
@@ -123,9 +123,15 @@ export const updateAuthProvider = async (req: Request, res: Response) => {
authProvider authProvider
} = req.body; } = req.body;
if (req.user?.authProvider === AuthProvider.OKTA_SAML) return res.status(400).send({ if (
message: "Failed to update user authentication method because SAML SSO is enforced" 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( const user = await User.findByIdAndUpdate(
req.user._id.toString(), req.user._id.toString(),
+23
View File
@@ -41,6 +41,29 @@ router.get(
ssoController.redirectSSO 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( router.get(
"/redirect/saml2/:ssoIdentifier", "/redirect/saml2/:ssoIdentifier",
authLimiter, authLimiter,
+1
View File
@@ -3,6 +3,7 @@ import { Document, Schema, Types, model } from "mongoose";
export enum AuthProvider { export enum AuthProvider {
EMAIL = "email", EMAIL = "email",
GOOGLE = "google", GOOGLE = "google",
GITHUB = "github",
OKTA_SAML = "okta-saml", OKTA_SAML = "okta-saml",
AZURE_SAML = "azure-saml", AZURE_SAML = "azure-saml",
JUMPCLOUD_SAML = "jumpcloud-saml", JUMPCLOUD_SAML = "jumpcloud-saml",
+2 -1
View File
@@ -50,7 +50,8 @@ router.patch(
}), }),
body("authProvider").exists().isString().isIn([ body("authProvider").exists().isString().isIn([
AuthProvider.EMAIL, AuthProvider.EMAIL,
AuthProvider.GOOGLE AuthProvider.GOOGLE,
AuthProvider.GITHUB
]), ]),
validateRequest, validateRequest,
usersController.updateAuthProvider usersController.updateAuthProvider
+90 -32
View File
@@ -12,8 +12,10 @@ import {
} from "../models"; } from "../models";
import { createToken } from "../helpers/auth"; import { createToken } from "../helpers/auth";
import { import {
getClientIdGoogle, getClientIdGitHubLogin,
getClientSecretGoogle, getClientIdGoogleLogin,
getClientSecretGitHubLogin,
getClientSecretGoogleLogin,
getJwtProviderAuthLifetime, getJwtProviderAuthLifetime,
getJwtProviderAuthSecret, getJwtProviderAuthSecret,
} from "../config"; } from "../config";
@@ -25,6 +27,8 @@ import { getSiteURL } from "../config";
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const GoogleStrategy = require("passport-google-oauth20").Strategy; 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;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { MultiSamlStrategy } = require("@node-saml/passport-saml"); const { MultiSamlStrategy } = require("@node-saml/passport-saml");
/** /**
@@ -67,42 +71,97 @@ const getAuthDataPayloadUserObj = (authData: AuthData) => {
} }
const initializePassport = async () => { const initializePassport = async () => {
const googleClientSecret = await getClientSecretGoogle(); const clientIdGoogleLogin = await getClientIdGoogleLogin();
const googleClientId = await getClientIdGoogle(); const clientSecretGoogleLogin = await getClientSecretGoogleLogin();
const clientIdGitHubLogin = await getClientIdGitHubLogin();
const clientSecretGitHubLogin = await getClientSecretGitHubLogin();
passport.use(new GoogleStrategy({ if (clientIdGoogleLogin && clientSecretGoogleLogin) {
passReqToCallback: true, passport.use(new GoogleStrategy({
clientID: googleClientId, passReqToCallback: true,
clientSecret: googleClientSecret, clientID: clientIdGoogleLogin,
callbackURL: "/api/v1/sso/google", clientSecret: clientSecretGoogleLogin,
scope: ["profile", " email"], callbackURL: "/api/v1/sso/google",
}, async ( scope: ["profile", " email"],
req: express.Request, }, async (
accessToken: string, req: express.Request,
refreshToken: string, accessToken: string,
profile: any, refreshToken: string,
done: any profile: any,
) => { done: any
try { ) => {
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 email = profile.emails[0].value;
const firstName = profile.name.givenName;
const lastName = profile.name.familyName;
let user = await User.findOne({ let user = await User.findOne({
email email
}).select("+publicKey"); }).select("+publicKey");
if (user && user.authProvider !== AuthProvider.GOOGLE) { if (user && user.authProvider !== AuthProvider.GITHUB) {
done(InternalServerError()); done(InternalServerError());
} }
if (!user) { if (!user) {
user = await new User({ user = await new User({
email, email: email,
authProvider: AuthProvider.GOOGLE, authProvider: AuthProvider.GITHUB,
authId: profile.id, authId: profile.id,
firstName, firstName: profile.displayName,
lastName lastName: ""
}).save(); }).save();
} }
@@ -111,8 +170,8 @@ const initializePassport = async () => {
payload: { payload: {
userId: user._id.toString(), userId: user._id.toString(),
email: user.email, email: user.email,
firstName, firstName: user.firstName,
lastName, lastName: user.lastName,
authProvider: user.authProvider, authProvider: user.authProvider,
isUserCompleted, isUserCompleted,
...(req.query.state ? { ...(req.query.state ? {
@@ -125,11 +184,10 @@ const initializePassport = async () => {
req.isUserCompleted = isUserCompleted; req.isUserCompleted = isUserCompleted;
req.providerAuthToken = providerAuthToken; req.providerAuthToken = providerAuthToken;
done(null, profile); return done(null, profile);
} catch (err) {
done(null, false);
} }
})); ));
}
passport.use("saml", new MultiSamlStrategy( passport.use("saml", new MultiSamlStrategy(
{ {
+1 -8
View File
@@ -24,8 +24,6 @@ import {
reencryptSecretBlindIndexDataSalts reencryptSecretBlindIndexDataSalts
} from "./reencryptData"; } from "./reencryptData";
import { import {
getClientIdGoogle,
getClientSecretGoogle,
getMongoURL, getMongoURL,
getNodeEnv, getNodeEnv,
getSentryDSN getSentryDSN
@@ -55,12 +53,7 @@ export const setup = async () => {
// initializing the database connection // initializing the database connection
await DatabaseService.initDatabase(await getMongoURL()); await DatabaseService.initDatabase(await getMongoURL());
const googleClientSecret: string = await getClientSecretGoogle(); await initializePassport();
const googleClientId: string = await getClientIdGoogle();
if (googleClientId && googleClientSecret) {
await initializePassport();
}
// re-encrypt any data previously encrypted under server hex 128-bit ENCRYPTION_KEY // re-encrypt any data previously encrypted under server hex 128-bit ENCRYPTION_KEY
// to base64 256-bit ROOT_ENCRYPTION_KEY // to base64 256-bit ROOT_ENCRYPTION_KEY
+91 -37
View File
@@ -5,7 +5,7 @@ description: "Configure your environment variables when self-hosting Infisical."
## Backend environment variables ## Backend environment variables
Depending on your choosen self hosted deployment method, you may need to configured at least the required environment variable listed below. Depending on your choosen self hosted deployment method, you may need to configured at least the required environment variable listed below.
Other environment variables are listed below to increase the functionality of your self hosted instance based on your use case. Other environment variables are listed below to increase the functionality of your self hosted instance based on your use case.
<Tabs> <Tabs>
@@ -14,25 +14,40 @@ Other environment variables are listed below to increase the functionality of yo
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16` Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16`
</ParamField> </ParamField>
<ParamField query="JWT_SIGNUP_SECRET" type="string" default="none" required> {" "}
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16`
</ParamField>
<ParamField query="JWT_REFRESH_SECRET" type="string" default="none" required> <ParamField query="JWT_SIGNUP_SECRET" type="string" default="none" required>
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16` Must be a random 16 byte hex string. Can be generated with `openssl rand -hex
</ParamField> 16`
</ParamField>
<ParamField query="JWT_AUTH_SECRET" type="string" default="none" required> {" "}
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16`
</ParamField>
<ParamField query="JWT_MFA_SECRET" type="string" default="none" required> <ParamField query="JWT_REFRESH_SECRET" type="string" default="none" required>
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16` Must be a random 16 byte hex string. Can be generated with `openssl rand -hex
</ParamField> 16`
</ParamField>
<ParamField query="JWT_SERVICE_SECRET" type="string" default="none" required> {" "}
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16`
</ParamField> <ParamField query="JWT_AUTH_SECRET" type="string" default="none" required>
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex
16`
</ParamField>
{" "}
<ParamField query="JWT_MFA_SECRET" type="string" default="none" required>
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex
16`
</ParamField>
{" "}
<ParamField query="JWT_SERVICE_SECRET" type="string" default="none" required>
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex
16`
</ParamField>
<ParamField query="MONGO_URL" type="string" default="none" required> <ParamField query="MONGO_URL" type="string" default="none" required>
*TLS based connection string is not yet supported *TLS based connection string is not yet supported
@@ -58,7 +73,7 @@ Other environment variables are listed below to increase the functionality of yo
</ParamField> </ParamField>
<ParamField query="SMTP_SECURE" type="string" default="none" optional> <ParamField query="SMTP_SECURE" type="string" default="none" optional>
If true, use TLS when connecting to host. If false, TLS will be used if STARTTLS is supported If true, use TLS when connecting to host. If false, TLS will be used if STARTTLS is supported
</ParamField> </ParamField>
<ParamField query="SMTP_FROM_ADDRESS" type="string" default="none" optional> <ParamField query="SMTP_FROM_ADDRESS" type="string" default="none" optional>
@@ -68,9 +83,10 @@ Other environment variables are listed below to increase the functionality of yo
<ParamField query="SMTP_FROM_NAME" type="string" default="none" optional> <ParamField query="SMTP_FROM_NAME" type="string" default="none" optional>
Name label to be used in From field (e.g. Team) Name label to be used in From field (e.g. Team)
</ParamField> </ParamField>
</Tab> </Tab>
<Tab title="Secret Integrations"> <Tab title="Secret Integrations">
To sync secret to third party services, provide value for the related services To sync secret to third party services, provide value for the related services
<ParamField query="CLIENT_ID_HEROKU" type="string" default="none" optional> <ParamField query="CLIENT_ID_HEROKU" type="string" default="none" optional>
OAuth2 client ID for Heroku integration OAuth2 client ID for Heroku integration
@@ -81,7 +97,7 @@ Other environment variables are listed below to increase the functionality of yo
</ParamField> </ParamField>
<ParamField query="CLIENT_ID_VERCEL" type="string" default="none" optional> <ParamField query="CLIENT_ID_VERCEL" type="string" default="none" optional>
OAuth2 client ID for Vercel integration OAuth2 client ID for Vercel integration
</ParamField> </ParamField>
<ParamField query="CLIENT_SECRET_VERCEL" type="string" default="none" optional> <ParamField query="CLIENT_SECRET_VERCEL" type="string" default="none" optional>
@@ -89,7 +105,7 @@ Other environment variables are listed below to increase the functionality of yo
</ParamField> </ParamField>
<ParamField query="CLIENT_ID_NETLIFY" type="string" default="none" optional> <ParamField query="CLIENT_ID_NETLIFY" type="string" default="none" optional>
OAuth2 client ID for Netlify integration OAuth2 client ID for Netlify integration
</ParamField> </ParamField>
<ParamField query="CLIENT_SECRET_NETLIFY" type="string" default="none" optional> <ParamField query="CLIENT_SECRET_NETLIFY" type="string" default="none" optional>
@@ -97,7 +113,7 @@ Other environment variables are listed below to increase the functionality of yo
</ParamField> </ParamField>
<ParamField query="CLIENT_ID_GITHUB" type="string" default="none" optional> <ParamField query="CLIENT_ID_GITHUB" type="string" default="none" optional>
OAuth2 client ID for GitHub integration OAuth2 client ID for GitHub integration
</ParamField> </ParamField>
<ParamField query="CLIENT_SECRET_GITHUB" type="string" default="none" optional> <ParamField query="CLIENT_SECRET_GITHUB" type="string" default="none" optional>
@@ -109,23 +125,30 @@ Other environment variables are listed below to increase the functionality of yo
</ParamField> </ParamField>
<ParamField query="CLIENT_ID_BITBUCKET" type="string" default="none" optional> <ParamField query="CLIENT_ID_BITBUCKET" type="string" default="none" optional>
OAuth2 client ID for BitBucket integration OAuth2 client ID for BitBucket integration
</ParamField> </ParamField>
<ParamField query="CLIENT_SECRET_BITBUCKET" type="string" default="none" optional> <ParamField query="CLIENT_SECRET_BITBUCKET" type="string" default="none" optional>
OAuth2 client secret for BitBucket integration OAuth2 client secret for BitBucket integration
</ParamField> </ParamField>
</Tab> </Tab>
<Tab title="Auth Integrations"> <Tab title="Auth Integrations">
To integrate with external auth providers, provide value for the related keys To integrate with external auth providers, provide value for the related keys
<ParamField query="JWT_PROVIDER_AUTH_SECRET" type="string" required> <ParamField query="JWT_PROVIDER_AUTH_SECRET" type="string" required>
Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16` Must be a random 16 byte hex string. Can be generated with `openssl rand -hex 16`
</ParamField> </ParamField>
<ParamField query="CLIENT_ID_GOOGLE" type="string" default="none" optional> <ParamField query="CLIENT_ID_GOOGLE_LOGIN" type="string" default="none" optional>
OAuth2 client ID for Google auth integration OAuth2 client ID for Google login
</ParamField> </ParamField>
<ParamField query="CLIENT_SECRET_GOOGLE" type="string" default="none" optional> <ParamField query="CLIENT_SECRET_GOOGLE_LOGIN" type="string" default="none" optional>
OAuth2 client secret for Google auth integration OAuth2 client secret for Google login
</ParamField>
<ParamField query="CLIENT_ID_GITHUB_LOGIN" type="string" default="none" optional>
OAuth2 client ID for GitHub login
</ParamField>
<ParamField query="CLIENT_SECRET_GITHUB_LOGIN" type="string" default="none" optional>
OAuth2 client secret for GitHub login
</ParamField> </ParamField>
</Tab> </Tab>
<Tab title="Others"> <Tab title="Others">
@@ -150,18 +173,44 @@ Other environment variables are listed below to increase the functionality of yo
JWT token lifetime expressed in seconds or a string describing a time span JWT token lifetime expressed in seconds or a string describing a time span
</ParamField> </ParamField>
<ParamField query="MONGO_USERNAME" type="string" default="none" optional></ParamField> {" "}
<ParamField query="MONGO_PASSWORD" type="string" default="none" optional></ParamField> <ParamField
query="MONGO_USERNAME"
type="string"
default="none"
optional
></ParamField>
#### Error logging {" "}
Infisical uses Sentry to report error logs
<ParamField query="SENTRY_DSN" type="string" default="none" optional></ParamField>
#### Settings <ParamField
<ParamField query="INVITE_ONLY_SIGNUP" type="string" default="false" optional> query="MONGO_PASSWORD"
Only allow users who are invited to sign up type="string"
</ParamField> default="none"
optional
></ParamField>
#### Error logging
Infisical uses Sentry to report error logs
{" "}
<ParamField
query="SENTRY_DSN"
type="string"
default="none"
optional
></ParamField>
#### Settings
{" "}
<ParamField query="INVITE_ONLY_SIGNUP" type="string" default="false" optional>
Only allow users who are invited to sign up
</ParamField>
<ParamField query="SITE_URL" type="string" default="none" optional> <ParamField query="SITE_URL" type="string" default="none" optional>
Site URL - should be an absolute URL including the protocol (e.g. https://app.infisical.com) Site URL - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
@@ -170,6 +219,11 @@ Other environment variables are listed below to increase the functionality of yo
</Tab> </Tab>
</Tabs> </Tabs>
## Frontend environment variables ## Frontend environment variables
<ParamField query="TELEMETRY_ENABLED" type="string" default="true" optional></ParamField>
<ParamField
query="TELEMETRY_ENABLED"
type="string"
default="true"
optional
></ParamField>
-2
View File
@@ -293,12 +293,10 @@ export const useRevokeMySessions = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async () => { mutationFn: async () => {
console.log("useRevokeAllSessions 1");
const { data } = await apiRequest.delete( const { data } = await apiRequest.delete(
"/api/v2/users/me/sessions" "/api/v2/users/me/sessions"
); );
console.log("useRevokeAllSessions 2: ", data);
return data; return data;
}, },
onSuccess() { onSuccess() {
@@ -2,7 +2,7 @@ import { FormEvent, useState } from "react";
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 { faGoogle } from "@fortawesome/free-brands-svg-icons"; import { faGithub,faGoogle } from "@fortawesome/free-brands-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import axios from "axios" import axios from "axios"
@@ -34,7 +34,6 @@ export const InitialStep = ({
const { t } = useTranslation(); const { t } = useTranslation();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [loginError, setLoginError] = useState(false); const [loginError, setLoginError] = useState(false);
const [loginEmailChosen, setLoginEmailChosen] = useState(false);
const { data: serverDetails } = useFetchServerStatus(); const { data: serverDetails } = useFetchServerStatus();
const queryParams = new URLSearchParams(window.location.search); const queryParams = new URLSearchParams(window.location.search);
@@ -68,8 +67,7 @@ export const InitialStep = ({
// send request to server endpoint // send request to server endpoint
const instance = axios.create() const instance = axios.create()
const cliResp = await instance.post(cliUrl, { ...isCliLoginSuccessful.loginResponse }) await instance.post(cliUrl, { ...isCliLoginSuccessful.loginResponse })
console.log(cliResp)
// cli page // cli page
router.push("/cli-redirect"); router.push("/cli-redirect");
@@ -118,23 +116,6 @@ export const InitialStep = ({
return ( return (
<form onSubmit={handleLogin} className='flex flex-col mx-auto w-full justify-center items-center'> <form onSubmit={handleLogin} className='flex flex-col mx-auto w-full justify-center items-center'>
<h1 className='text-xl font-medium text-transparent bg-clip-text bg-gradient-to-b from-white to-bunker-200 text-center mb-8' >Login to Infisical</h1> <h1 className='text-xl font-medium text-transparent bg-clip-text bg-gradient-to-b from-white to-bunker-200 text-center mb-8' >Login to Infisical</h1>
<div className='lg:w-1/6 w-1/4 min-w-[21.2rem] md:min-w-[20.1rem] text-center rounded-md mt-4'>
<Button
colorSchema="primary"
variant={loginEmailChosen ? "outline_bg" : "solid"}
onClick={() => {
const callbackPort = queryParams.get("callback_port");
window.open(`/api/v1/sso/redirect/google${callbackPort ? `?callback_port=${callbackPort}` : ""}`);
window.close();
}}
leftIcon={<FontAwesomeIcon icon={faGoogle} className="mr-1" />}
className="h-12 w-full mx-0"
>
{t("login.continue-with-google")}
</Button>
</div>
{loginEmailChosen && <>
<div className='lg:w-1/6 w-1/4 min-w-[20rem] flex flex-row items-center my-4 py-2'> <div className='lg:w-1/6 w-1/4 min-w-[20rem] flex flex-row items-center my-4 py-2'>
<div className='w-full border-t border-mineshaft-500' /> <div className='w-full border-t border-mineshaft-500' />
</div> </div>
@@ -175,19 +156,40 @@ export const InitialStep = ({
{!isLoading && loginError && <Error text={t("login.error-login") ?? ""} />} {!isLoading && loginError && <Error text={t("login.error-login") ?? ""} />}
<div className='lg:w-1/6 w-1/4 min-w-[20rem] flex flex-row items-center mt-4 py-2'> <div className='lg:w-1/6 w-1/4 min-w-[20rem] flex flex-row items-center mt-4 py-2'>
<div className='w-full border-t border-mineshaft-500' /> <div className='w-full border-t border-mineshaft-500' />
</div></>} </div>
{!loginEmailChosen && <div className='lg:w-1/6 w-1/4 min-w-[21.2rem] md:min-w-[20.1rem] text-center rounded-md mt-4'> <div className='lg:w-1/6 w-1/4 min-w-[21.2rem] md:min-w-[20.1rem] text-center rounded-md mt-4'>
<Button <Button
onClick={() => { colorSchema="primary"
setLoginEmailChosen(true);
}}
size="sm"
isFullWidth
className='h-12'
colorSchema="primary"
variant="outline_bg" variant="outline_bg"
> Continue with Email </Button> onClick={() => {
</div>} const callbackPort = queryParams.get("callback_port");
window.open(`/api/v1/sso/redirect/google${callbackPort ? `?callback_port=${callbackPort}` : ""}`);
window.close();
}}
leftIcon={<FontAwesomeIcon icon={faGoogle} className="mr-2" />}
className="h-12 w-full mx-0"
>
{t("login.continue-with-google")}
</Button>
</div>
<div className='lg:w-1/6 w-1/4 min-w-[21.2rem] md:min-w-[20.1rem] text-center rounded-md mt-4'>
<Button
colorSchema="primary"
variant="outline_bg"
onClick={() => {
const callbackPort = queryParams.get("callback_port");
window.open(`/api/v1/sso/redirect/github${callbackPort ? `?callback_port=${callbackPort}` : ""}`);
window.close();
}}
leftIcon={<FontAwesomeIcon icon={faGithub} className="mr-2" />}
className="h-12 w-full mx-0"
>
Continue with GitHub
</Button>
</div>
<div className='lg:w-1/6 w-1/4 min-w-[21.2rem] md:min-w-[20.1rem] text-center rounded-md mt-4'> <div className='lg:w-1/6 w-1/4 min-w-[21.2rem] md:min-w-[20.1rem] text-center rounded-md mt-4'>
<Button <Button
colorSchema="primary" colorSchema="primary"
@@ -17,7 +17,10 @@ import {
const authMethods = [ const authMethods = [
{ label: "Email", value: "email" }, { label: "Email", value: "email" },
{ label: "Google SSO", value: "google" }, { label: "Google SSO", value: "google" },
{ label: "Okta SAML 2.0", value: "okta-saml" }, { label: "GitHub SSO", value: "github" },
{ label: "Okta SAML", value: "okta-saml" },
{ label: "Azure SAML", value: "azure-saml" },
{ label: "JumpCloud SAML", value: "jumpcloud-saml" }
]; ];
const schema = yup.object({ const schema = yup.object({
@@ -54,9 +57,13 @@ export const AuthMethodSection = () => {
authMethod authMethod
}: FormData) => { }: FormData) => {
try { try {
if (authMethod === "okta-saml") { if (
authMethod === "okta-saml"
|| authMethod === "azure-saml"
|| authMethod === "jumpcloud-saml"
) {
createNotification({ createNotification({
text: "Okta SAML 2.0 can only be configured in your organization settings", text: "SAML authentication can only be configured in your organization settings",
type: "error" type: "error"
}); });