mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-25 14:05:03 +00:00
Compare commits
5 Commits
snyk-fix-f
...
infisical-
Author | SHA1 | Date | |
---|---|---|---|
27030138ec | |||
c37ce4eaea | |||
17647587f9 | |||
f3dc7fcf7b | |||
e65c6568e1 |
.github/workflows
backend/src
cli/packages
frontend
23
.github/workflows/check-be-pull-request.yml
vendored
23
.github/workflows/check-be-pull-request.yml
vendored
@ -13,6 +13,7 @@ jobs:
|
||||
check-be-pr:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: ☁️ Checkout source
|
||||
@ -26,17 +27,17 @@ jobs:
|
||||
- name: 📦 Install dependencies
|
||||
run: npm ci --only-production
|
||||
working-directory: backend
|
||||
- name: 🧪 Run tests
|
||||
run: npm run test:ci
|
||||
working-directory: backend
|
||||
- name: 📁 Upload test results
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: be-test-results
|
||||
path: |
|
||||
./backend/reports
|
||||
./backend/coverage
|
||||
# - name: 🧪 Run tests
|
||||
# run: npm run test:ci
|
||||
# working-directory: backend
|
||||
# - name: 📁 Upload test results
|
||||
# uses: actions/upload-artifact@v3
|
||||
# if: always()
|
||||
# with:
|
||||
# name: be-test-results
|
||||
# path: |
|
||||
# ./backend/reports
|
||||
# ./backend/coverage
|
||||
- name: 🏗️ Run build
|
||||
run: npm run build
|
||||
working-directory: backend
|
||||
|
29
.github/workflows/check-fe-pull-request.yml
vendored
29
.github/workflows/check-fe-pull-request.yml
vendored
@ -2,40 +2,35 @@ name: Check Frontend Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ opened, synchronize ]
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- 'frontend/**'
|
||||
- '!frontend/README.md'
|
||||
- '!frontend/.*'
|
||||
- 'frontend/.eslintrc.js'
|
||||
|
||||
- "frontend/**"
|
||||
- "!frontend/README.md"
|
||||
- "!frontend/.*"
|
||||
- "frontend/.eslintrc.js"
|
||||
|
||||
jobs:
|
||||
|
||||
check-fe-pr:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
-
|
||||
name: ☁️ Checkout source
|
||||
- name: ☁️ Checkout source
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: 🔧 Setup Node 16
|
||||
- name: 🔧 Setup Node 16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16'
|
||||
cache: 'npm'
|
||||
node-version: "16"
|
||||
cache: "npm"
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
-
|
||||
name: 📦 Install dependencies
|
||||
- name: 📦 Install dependencies
|
||||
run: npm ci --only-production --ignore-scripts
|
||||
working-directory: frontend
|
||||
# -
|
||||
# name: 🧪 Run tests
|
||||
# run: npm run test:ci
|
||||
# working-directory: frontend
|
||||
-
|
||||
name: 🏗️ Run build
|
||||
- name: 🏗️ Run build
|
||||
run: npm run build
|
||||
working-directory: frontend
|
||||
|
@ -1,17 +1,15 @@
|
||||
import to from 'await-to-js';
|
||||
import { Types } from 'mongoose';
|
||||
import { Request, Response } from 'express';
|
||||
import { ISecret, Secret, Workspace } from '../../models';
|
||||
import { IAction, SecretVersion } from '../../ee/models';
|
||||
import {
|
||||
SECRET_PERSONAL,
|
||||
SECRET_SHARED,
|
||||
ACTION_ADD_SECRETS,
|
||||
ACTION_READ_SECRETS,
|
||||
ACTION_UPDATE_SECRETS,
|
||||
ACTION_DELETE_SECRETS
|
||||
} from '../../variables';
|
||||
import { UnauthorizedRequestError, ValidationError } from '../../utils/errors';
|
||||
import { UnauthorizedRequestError, WorkspaceNotFoundError } from '../../utils/errors';
|
||||
import { EventService } from '../../services';
|
||||
import { eventPushSecrets } from '../../events';
|
||||
import { EESecretService, EELogService, EELicenseService } from '../../ee/services';
|
||||
@ -20,7 +18,7 @@ import { getChannelFromUserAgent } from '../../utils/posthog';
|
||||
import { PERMISSION_WRITE_SECRETS } from '../../variables';
|
||||
import { userHasNoAbility, userHasWorkspaceAccess, userHasWriteOnlyAbility } from '../../ee/helpers/checkMembershipPermissions';
|
||||
import Tag from '../../models/tag';
|
||||
import _, { eq } from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
BatchSecretRequest,
|
||||
BatchSecret
|
||||
@ -49,13 +47,11 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
requests: BatchSecretRequest[];
|
||||
} = req.body;
|
||||
|
||||
const organizationId = (
|
||||
await Workspace.findOne({
|
||||
_id: workspaceId
|
||||
})
|
||||
)?.organization?.toString();
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(organizationId || '');
|
||||
const isPaid = orgPlan.slug != 'starter';
|
||||
const workspace = await Workspace.findById(workspaceId);
|
||||
if (!workspace) throw WorkspaceNotFoundError();
|
||||
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(workspace.organization.toString());
|
||||
const isPaid = orgPlan.tier < 1;
|
||||
|
||||
const createSecrets: BatchSecret[] = [];
|
||||
const updateSecrets: BatchSecret[] = [];
|
||||
@ -387,13 +383,11 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
}
|
||||
|
||||
const organizationId = (
|
||||
await Workspace.findOne({
|
||||
_id: workspaceId
|
||||
})
|
||||
)?.organization?.toString();
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(organizationId || '');
|
||||
const isPaid = orgPlan.slug != 'starter';
|
||||
const workspace = await Workspace.findById(workspaceId);
|
||||
if (!workspace) throw WorkspaceNotFoundError();
|
||||
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(workspace.organization.toString());
|
||||
const isPaid = orgPlan.tier < 1;
|
||||
|
||||
let listOfSecretsToCreate;
|
||||
if (Array.isArray(req.body.secrets)) {
|
||||
@ -615,13 +609,11 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
const normalizedPath = normalizePath(secretsPath as string)
|
||||
const folders = await getFoldersInDirectory(workspaceId as string, environment as string, normalizedPath)
|
||||
|
||||
const organizationId = (
|
||||
await Workspace.findOne({
|
||||
_id: workspaceId
|
||||
})
|
||||
)?.organization?.toString();
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(organizationId || '');
|
||||
const isPaid = orgPlan.slug != 'starter';
|
||||
const workspace = await Workspace.findById(workspaceId);
|
||||
if (!workspace) throw WorkspaceNotFoundError();
|
||||
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(workspace.organization.toString());
|
||||
const isPaid = orgPlan.tier < 1;
|
||||
|
||||
// secrets to return
|
||||
let secrets: ISecret[] = [];
|
||||
@ -967,13 +959,11 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
||||
workspaceId: new Types.ObjectId(key)
|
||||
})
|
||||
|
||||
const organizationId = (
|
||||
await Workspace.findOne({
|
||||
_id: key
|
||||
})
|
||||
)?.organization?.toString();
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(organizationId || '');
|
||||
const isPaid = orgPlan.slug != 'starter';
|
||||
const workspace = await Workspace.findById(key);
|
||||
if (!workspace) throw WorkspaceNotFoundError();
|
||||
|
||||
const orgPlan = await EELicenseService.getOrganizationPlan(workspace.organization.toString());
|
||||
const isPaid = orgPlan.tier < 1;
|
||||
|
||||
const postHogClient = await TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
|
@ -43,7 +43,7 @@ class EELicenseService {
|
||||
public globalFeatureSet: FeatureSet = {
|
||||
_id: null,
|
||||
slug: null,
|
||||
tier: null,
|
||||
tier: -1,
|
||||
projectLimit: null,
|
||||
memberLimit: null,
|
||||
secretVersioning: true,
|
||||
|
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/config"
|
||||
"github.com/go-resty/resty/v2"
|
||||
@ -179,6 +180,19 @@ func CallLogin2V2(httpClient *resty.Client, request GetLoginTwoV2Request) (GetLo
|
||||
SetBody(request).
|
||||
Post(fmt.Sprintf("%v/v2/auth/login2", config.INFISICAL_URL))
|
||||
|
||||
cookies := response.Cookies()
|
||||
// Find a cookie by name
|
||||
cookieName := "jid"
|
||||
var refreshToken *http.Cookie
|
||||
for _, cookie := range cookies {
|
||||
if cookie.Name == cookieName {
|
||||
refreshToken = cookie
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
loginTwoV2Response.RefreshToken = refreshToken.Value
|
||||
|
||||
if err != nil {
|
||||
return GetLoginTwoV2Response{}, fmt.Errorf("CallLogin2V2: Unable to complete api request [err=%s]", err)
|
||||
}
|
||||
@ -247,3 +261,26 @@ func CallGetAccessibleEnvironments(httpClient *resty.Client, request GetAccessib
|
||||
|
||||
return accessibleEnvironmentsResponse, nil
|
||||
}
|
||||
|
||||
func CallGetNewAccessTokenWithRefreshToken(httpClient *resty.Client, refreshToken string) (GetNewAccessTokenWithRefreshTokenResponse, error) {
|
||||
var newAccessToken GetNewAccessTokenWithRefreshTokenResponse
|
||||
response, err := httpClient.
|
||||
R().
|
||||
SetResult(&newAccessToken).
|
||||
SetHeader("User-Agent", USER_AGENT).
|
||||
SetCookie(&http.Cookie{
|
||||
Name: "jid",
|
||||
Value: refreshToken,
|
||||
}).
|
||||
Post(fmt.Sprintf("%v/v1/auth/token", config.INFISICAL_URL))
|
||||
|
||||
if err != nil {
|
||||
return GetNewAccessTokenWithRefreshTokenResponse{}, err
|
||||
}
|
||||
|
||||
if response.IsError() {
|
||||
return GetNewAccessTokenWithRefreshTokenResponse{}, fmt.Errorf("CallGetNewAccessTokenWithRefreshToken: Unsuccessful response: [response=%v]", response)
|
||||
}
|
||||
|
||||
return newAccessToken, nil
|
||||
}
|
||||
|
@ -281,6 +281,7 @@ type GetLoginTwoV2Response struct {
|
||||
ProtectedKey string `json:"protectedKey"`
|
||||
ProtectedKeyIV string `json:"protectedKeyIV"`
|
||||
ProtectedKeyTag string `json:"protectedKeyTag"`
|
||||
RefreshToken string `json:"RefreshToken"`
|
||||
}
|
||||
|
||||
type VerifyMfaTokenRequest struct {
|
||||
@ -314,3 +315,7 @@ type VerifyMfaTokenErrorResponse struct {
|
||||
Application string `json:"application"`
|
||||
Extra []interface{} `json:"extra"`
|
||||
}
|
||||
|
||||
type GetNewAccessTokenWithRefreshTokenResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ var loginCmd = &cobra.Command{
|
||||
|
||||
loginOneResponse, loginTwoResponse, err := getFreshUserCredentials(email, password)
|
||||
if err != nil {
|
||||
fmt.Println("Unable to authenticate with the provided credentials, please try again")
|
||||
log.Warn().Msg("Unable to authenticate with the provided credentials, please ensure your email and password are correct")
|
||||
log.Debug().Err(err)
|
||||
return
|
||||
}
|
||||
@ -244,9 +244,10 @@ var loginCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
userCredentialsToBeStored := &models.UserCredentials{
|
||||
Email: email,
|
||||
PrivateKey: string(decryptedPrivateKey),
|
||||
JTWToken: loginTwoResponse.Token,
|
||||
Email: email,
|
||||
PrivateKey: string(decryptedPrivateKey),
|
||||
JTWToken: loginTwoResponse.Token,
|
||||
RefreshToken: loginTwoResponse.RefreshToken,
|
||||
}
|
||||
|
||||
err = util.StoreUserCredsInKeyRing(userCredentialsToBeStored)
|
||||
@ -414,7 +415,7 @@ func getFreshUserCredentials(email string, password string) (*api.GetLoginOneV2R
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
util.HandleError(err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// **** Login 2
|
||||
|
@ -5,9 +5,10 @@ import (
|
||||
)
|
||||
|
||||
type UserCredentials struct {
|
||||
Email string `json:"email"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
JTWToken string `json:"JTWToken"`
|
||||
Email string `json:"email"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
JTWToken string `json:"JTWToken"`
|
||||
RefreshToken string `json:"RefreshToken"`
|
||||
}
|
||||
|
||||
// The file struct for Infisical config file
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/Infisical/infisical-merge/packages/config"
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type LoggedInUserDetails struct {
|
||||
@ -96,6 +97,20 @@ func GetCurrentLoggedInUserDetails() (LoggedInUserDetails, error) {
|
||||
}
|
||||
|
||||
isAuthenticated := api.CallIsAuthenticated(httpClient)
|
||||
|
||||
if !isAuthenticated {
|
||||
accessTokenResponse, _ := api.CallGetNewAccessTokenWithRefreshToken(httpClient, userCreds.RefreshToken)
|
||||
if accessTokenResponse.Token != "" {
|
||||
isAuthenticated = true
|
||||
userCreds.JTWToken = accessTokenResponse.Token
|
||||
}
|
||||
}
|
||||
|
||||
err = StoreUserCredsInKeyRing(&userCreds)
|
||||
if err != nil {
|
||||
log.Debug().Msg("unable to store your user credentials with new access token")
|
||||
}
|
||||
|
||||
if !isAuthenticated {
|
||||
return LoggedInUserDetails{
|
||||
IsUserLoggedIn: true, // was logged in
|
||||
|
@ -74,23 +74,12 @@ func ConfigContainsEmail(users []models.LoggedInUser, email string) bool {
|
||||
}
|
||||
|
||||
func RequireLogin() {
|
||||
currentUserDetails, err := GetCurrentLoggedInUserDetails()
|
||||
// get the config file that stores the current logged in user email
|
||||
configFile, _ := GetConfigFile()
|
||||
|
||||
if err != nil {
|
||||
HandleError(err, "unable to retrieve your login details")
|
||||
}
|
||||
|
||||
if !currentUserDetails.IsUserLoggedIn {
|
||||
if configFile.LoggedInUserEmail == "" {
|
||||
PrintErrorMessageAndExit("You must be logged in to run this command. To login, run [infisical login]")
|
||||
}
|
||||
|
||||
if currentUserDetails.LoginExpired {
|
||||
PrintErrorMessageAndExit("Your login expired, please login in again. To login, run [infisical login]")
|
||||
}
|
||||
|
||||
if currentUserDetails.UserCredentials.Email == "" && currentUserDetails.UserCredentials.JTWToken == "" && currentUserDetails.UserCredentials.PrivateKey == "" {
|
||||
PrintErrorMessageAndExit("One or more of your login details is empty. Please try logging in again via by running [infisical login]")
|
||||
}
|
||||
}
|
||||
|
||||
func RequireServiceToken() {
|
||||
|
16
frontend/package-lock.json
generated
16
frontend/package-lock.json
generated
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "npm-proj-1684890464416-0.6926505276366393M9OjQI",
|
||||
"name": "npm-proj-1684411062139-0.5362546945149991xa7WAK",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
@ -57,7 +57,7 @@
|
||||
"lottie-react": "^2.4.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"next": "^12.3.4",
|
||||
"posthog-js": "^1.57.2",
|
||||
"posthog-js": "^1.54.0",
|
||||
"query-string": "^7.1.3",
|
||||
"react": "^17.0.2",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
@ -17460,9 +17460,9 @@
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"node_modules/posthog-js": {
|
||||
"version": "1.57.2",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.57.2.tgz",
|
||||
"integrity": "sha512-ER4gkYZasrd2Zwmt/yLeZ5G/nZJ6tpaYBCpx3CvocDx+3F16WdawJlYMT0IyLKHXDniC5+AsjzFd6fi8uyYlJA==",
|
||||
"version": "1.54.0",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.54.0.tgz",
|
||||
"integrity": "sha512-5kT9zvmBrCshFkWqOrYxk13Y/2j7vtV0sF3XmQa5QDD0bVM1KGU4blyZySBt8SAcO1z3WsKvG4bFGxS7TPqjjw==",
|
||||
"dependencies": {
|
||||
"fflate": "^0.4.1",
|
||||
"rrweb-snapshot": "^1.1.14"
|
||||
@ -34822,9 +34822,9 @@
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"posthog-js": {
|
||||
"version": "1.57.2",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.57.2.tgz",
|
||||
"integrity": "sha512-ER4gkYZasrd2Zwmt/yLeZ5G/nZJ6tpaYBCpx3CvocDx+3F16WdawJlYMT0IyLKHXDniC5+AsjzFd6fi8uyYlJA==",
|
||||
"version": "1.54.0",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.54.0.tgz",
|
||||
"integrity": "sha512-5kT9zvmBrCshFkWqOrYxk13Y/2j7vtV0sF3XmQa5QDD0bVM1KGU4blyZySBt8SAcO1z3WsKvG4bFGxS7TPqjjw==",
|
||||
"requires": {
|
||||
"fflate": "^0.4.1",
|
||||
"rrweb-snapshot": "^1.1.14"
|
||||
|
@ -64,7 +64,7 @@
|
||||
"lottie-react": "^2.4.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"next": "^12.3.4",
|
||||
"posthog-js": "^1.57.2",
|
||||
"posthog-js": "^1.54.0",
|
||||
"query-string": "^7.1.3",
|
||||
"react": "^17.0.2",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
|
Reference in New Issue
Block a user