mirror of
https://github.com/Infisical/infisical.git
synced 2025-07-05 04:29:09 +00:00
Compare commits
9 Commits
v0.85.0-po
...
daniel/bet
Author | SHA1 | Date | |
---|---|---|---|
cee982754b | |||
a6497b844a | |||
788dcf2c73 | |||
7f055450df | |||
9234213c62 | |||
e7278c4cd9 | |||
3e79dbb3f5 | |||
9b2565e387 | |||
1c5a8cabe9 |
@ -1,5 +1,6 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import fastifyPlugin from "fastify-plugin";
|
import fastifyPlugin from "fastify-plugin";
|
||||||
|
import { JsonWebTokenError } from "jsonwebtoken";
|
||||||
import { ZodError } from "zod";
|
import { ZodError } from "zod";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -11,6 +12,12 @@ import {
|
|||||||
UnauthorizedError
|
UnauthorizedError
|
||||||
} from "@app/lib/errors";
|
} from "@app/lib/errors";
|
||||||
|
|
||||||
|
enum JWTErrors {
|
||||||
|
JwtExpired = "jwt expired",
|
||||||
|
JwtMalformed = "jwt malformed",
|
||||||
|
InvalidAlgorithm = "invalid algorithm"
|
||||||
|
}
|
||||||
|
|
||||||
export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider) => {
|
export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider) => {
|
||||||
server.setErrorHandler((error, req, res) => {
|
server.setErrorHandler((error, req, res) => {
|
||||||
req.log.error(error);
|
req.log.error(error);
|
||||||
@ -36,6 +43,27 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider
|
|||||||
status: error.status,
|
status: error.status,
|
||||||
detail: error.detail
|
detail: error.detail
|
||||||
});
|
});
|
||||||
|
// Handle JWT errors and make them more human-readable for the end-user.
|
||||||
|
} else if (error instanceof JsonWebTokenError) {
|
||||||
|
const message = (() => {
|
||||||
|
if (error.message === JWTErrors.JwtExpired) {
|
||||||
|
return "Your token has expired. Please re-authenticate.";
|
||||||
|
}
|
||||||
|
if (error.message === JWTErrors.JwtMalformed) {
|
||||||
|
return "The provided access token is malformed. Please use a valid token or generate a new one and try again.";
|
||||||
|
}
|
||||||
|
if (error.message === JWTErrors.InvalidAlgorithm) {
|
||||||
|
return "The access token is signed with an invalid algorithm. Please provide a valid token and try again.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.message;
|
||||||
|
})();
|
||||||
|
|
||||||
|
void res.status(401).send({
|
||||||
|
statusCode: 401,
|
||||||
|
error: "TokenError",
|
||||||
|
message
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
void res.send(error);
|
void res.send(error);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,10 @@ export const getBotKeyFnFactory = (
|
|||||||
) => {
|
) => {
|
||||||
const getBotKeyFn = async (projectId: string) => {
|
const getBotKeyFn = async (projectId: string) => {
|
||||||
const project = await projectDAL.findById(projectId);
|
const project = await projectDAL.findById(projectId);
|
||||||
if (!project) throw new BadRequestError({ message: "Project not found during bot lookup." });
|
if (!project)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project not found during bot lookup. Are you sure you are using the correct project ID?"
|
||||||
|
});
|
||||||
|
|
||||||
if (project.version === 3) {
|
if (project.version === 3) {
|
||||||
return { project, shouldUseSecretV2Bridge: true };
|
return { project, shouldUseSecretV2Bridge: true };
|
||||||
|
@ -512,7 +512,11 @@ export const secretImportServiceFactory = ({
|
|||||||
return importedSecrets;
|
return importedSecrets;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
|
|
||||||
const importedSecrets = await fnSecretsFromImports({ allowedImports, folderDAL, secretDAL, secretImportDAL });
|
const importedSecrets = await fnSecretsFromImports({ allowedImports, folderDAL, secretDAL, secretImportDAL });
|
||||||
return importedSecrets.map((el) => ({
|
return importedSecrets.map((el) => ({
|
||||||
|
@ -832,7 +832,11 @@ export const createManySecretsRawFnFactory = ({
|
|||||||
secretDAL
|
secretDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
const inputSecrets = secrets.map((secret) => {
|
const inputSecrets = secrets.map((secret) => {
|
||||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretName, botKey);
|
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretName, botKey);
|
||||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretValue || "", botKey);
|
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secret.secretValue || "", botKey);
|
||||||
@ -993,7 +997,11 @@ export const updateManySecretsRawFnFactory = ({
|
|||||||
return updatedSecrets;
|
return updatedSecrets;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
|
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
|
||||||
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
|
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
|
||||||
|
|
||||||
|
@ -985,7 +985,11 @@ export const secretServiceFactory = ({
|
|||||||
return { secrets, imports };
|
return { secrets, imports };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
|
|
||||||
const { secrets, imports } = await getSecrets({
|
const { secrets, imports } = await getSecrets({
|
||||||
actorId,
|
actorId,
|
||||||
@ -1146,7 +1150,10 @@ export const secretServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!botKey)
|
if (!botKey)
|
||||||
throw new BadRequestError({ message: "Please upgrade your project first", name: "bot_not_found_error" });
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
const decryptedSecret = decryptSecretRaw(encryptedSecret, botKey);
|
const decryptedSecret = decryptSecretRaw(encryptedSecret, botKey);
|
||||||
|
|
||||||
if (expandSecretReferences) {
|
if (expandSecretReferences) {
|
||||||
@ -1238,7 +1245,11 @@ export const secretServiceFactory = ({
|
|||||||
return { secret, type: SecretProtectionType.Direct as const };
|
return { secret, type: SecretProtectionType.Direct as const };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretName, botKey);
|
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretName, botKey);
|
||||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||||
@ -1376,7 +1387,11 @@ export const secretServiceFactory = ({
|
|||||||
return { type: SecretProtectionType.Direct as const, secret };
|
return { type: SecretProtectionType.Direct as const, secret };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
|
|
||||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||||
@ -1498,7 +1513,11 @@ export const secretServiceFactory = ({
|
|||||||
});
|
});
|
||||||
return { type: SecretProtectionType.Direct as const, secret };
|
return { type: SecretProtectionType.Direct as const, secret };
|
||||||
}
|
}
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
if (policy) {
|
if (policy) {
|
||||||
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
policy,
|
policy,
|
||||||
@ -1598,7 +1617,11 @@ export const secretServiceFactory = ({
|
|||||||
return { secrets, type: SecretProtectionType.Direct as const };
|
return { secrets, type: SecretProtectionType.Direct as const };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
const sanitizedSecrets = inputSecrets.map(
|
const sanitizedSecrets = inputSecrets.map(
|
||||||
({ secretComment, secretKey, metadata, tagIds, secretValue, skipMultilineEncoding }) => {
|
({ secretComment, secretKey, metadata, tagIds, secretValue, skipMultilineEncoding }) => {
|
||||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretKey, botKey);
|
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretKey, botKey);
|
||||||
@ -1720,7 +1743,11 @@ export const secretServiceFactory = ({
|
|||||||
return { type: SecretProtectionType.Direct as const, secrets };
|
return { type: SecretProtectionType.Direct as const, secrets };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
const sanitizedSecrets = inputSecrets.map(
|
const sanitizedSecrets = inputSecrets.map(
|
||||||
({
|
({
|
||||||
secretComment,
|
secretComment,
|
||||||
@ -1848,7 +1875,11 @@ export const secretServiceFactory = ({
|
|||||||
return { type: SecretProtectionType.Direct as const, secrets };
|
return { type: SecretProtectionType.Direct as const, secrets };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
if (!botKey)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
|
|
||||||
if (policy) {
|
if (policy) {
|
||||||
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
const approval = await secretApprovalRequestService.generateSecretApprovalRequest({
|
||||||
@ -2182,7 +2213,10 @@ export const secretServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!botKey)
|
if (!botKey)
|
||||||
throw new BadRequestError({ message: "Please upgrade your project first", name: "bot_not_found_error" });
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
|
|
||||||
await secretDAL.transaction(async (tx) => {
|
await secretDAL.transaction(async (tx) => {
|
||||||
const secrets = await secretDAL.findAllProjectSecretValues(projectId, tx);
|
const secrets = await secretDAL.findAllProjectSecretValues(projectId, tx);
|
||||||
@ -2265,7 +2299,10 @@ export const secretServiceFactory = ({
|
|||||||
|
|
||||||
const { botKey } = await projectBotService.getBotKey(project.id);
|
const { botKey } = await projectBotService.getBotKey(project.id);
|
||||||
if (!botKey) {
|
if (!botKey) {
|
||||||
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
throw new BadRequestError({
|
||||||
|
message: "Project bot not found. Please upgrade your project.",
|
||||||
|
name: "bot_not_found_error"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourceFolder = await folderDAL.findBySecretPath(project.id, sourceEnvironment, sourceSecretPath);
|
const sourceFolder = await folderDAL.findBySecretPath(project.id, sourceEnvironment, sourceSecretPath);
|
||||||
|
@ -4,6 +4,7 @@ Copyright (c) 2023 Infisical Inc.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -43,14 +44,26 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().Bool("silent", false, "Disable output of tip/info messages. Useful when running in scripts or CI/CD pipelines.")
|
rootCmd.PersistentFlags().Bool("silent", false, "Disable output of tip/info messages. Useful when running in scripts or CI/CD pipelines.")
|
||||||
rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
|
rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
|
||||||
silent, err := cmd.Flags().GetBool("silent")
|
silent, err := cmd.Flags().GetBool("silent")
|
||||||
config.INFISICAL_URL = util.AppendAPIEndpoint(config.INFISICAL_URL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.HandleError(err)
|
util.HandleError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.INFISICAL_URL = util.AppendAPIEndpoint(config.INFISICAL_URL)
|
||||||
|
|
||||||
if !util.IsRunningInDocker() && !silent {
|
if !util.IsRunningInDocker() && !silent {
|
||||||
util.CheckForUpdate()
|
util.CheckForUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loggedInDetails, err := util.GetCurrentLoggedInUserDetails()
|
||||||
|
|
||||||
|
if !silent && err == nil && loggedInDetails.IsUserLoggedIn && !loggedInDetails.LoginExpired {
|
||||||
|
token, err := util.GetInfisicalToken(cmd)
|
||||||
|
|
||||||
|
if err == nil && token != nil {
|
||||||
|
util.PrintWarning(fmt.Sprintf("Your logged-in session is being overwritten by the token provided from the %s.", token.Source))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if config.INFISICAL_URL is set to the default value, check if INFISICAL_URL is set in the environment
|
// if config.INFISICAL_URL is set to the default value, check if INFISICAL_URL is set in the environment
|
||||||
|
@ -160,19 +160,19 @@ var secretsSetCmd = &cobra.Command{
|
|||||||
util.HandleError(err, "Unable to parse flag")
|
util.HandleError(err, "Unable to parse flag")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == nil) {
|
if token == nil {
|
||||||
util.RequireLocalWorkspaceFile()
|
util.RequireLocalWorkspaceFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
environmentName, _ := cmd.Flags().GetString("env")
|
environmentName, _ := cmd.Flags().GetString("env")
|
||||||
if !cmd.Flags().Changed("env") {
|
if !cmd.Flags().Changed("env") {
|
||||||
environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
|
environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
|
||||||
if environmentFromWorkspace != "" {
|
if environmentFromWorkspace != "" {
|
||||||
environmentName = environmentFromWorkspace
|
environmentName = environmentFromWorkspace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
projectId, err := cmd.Flags().GetString("projectId")
|
projectId, err := cmd.Flags().GetString("projectId")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.HandleError(err, "Unable to parse flag")
|
util.HandleError(err, "Unable to parse flag")
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,9 @@ type DynamicSecretLease struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TokenDetails struct {
|
type TokenDetails struct {
|
||||||
Type string
|
Type string
|
||||||
Token string
|
Token string
|
||||||
|
Source string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SingleFolder struct {
|
type SingleFolder struct {
|
||||||
|
@ -87,11 +87,15 @@ func GetInfisicalToken(cmd *cobra.Command) (token *models.TokenDetails, err erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var source = "--token flag"
|
||||||
|
|
||||||
if infisicalToken == "" { // If no flag is passed, we first check for the universal auth access token env variable.
|
if infisicalToken == "" { // If no flag is passed, we first check for the universal auth access token env variable.
|
||||||
infisicalToken = os.Getenv(INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN_NAME)
|
infisicalToken = os.Getenv(INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN_NAME)
|
||||||
|
source = fmt.Sprintf("%s environment variable", INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN_NAME)
|
||||||
|
|
||||||
if infisicalToken == "" { // If it's still empty after the first env check, we check for the service token env variable.
|
if infisicalToken == "" { // If it's still empty after the first env check, we check for the service token env variable.
|
||||||
infisicalToken = os.Getenv(INFISICAL_TOKEN_NAME)
|
infisicalToken = os.Getenv(INFISICAL_TOKEN_NAME)
|
||||||
|
source = fmt.Sprintf("%s environment variable", INFISICAL_TOKEN_NAME)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,14 +105,16 @@ func GetInfisicalToken(cmd *cobra.Command) (token *models.TokenDetails, err erro
|
|||||||
|
|
||||||
if strings.HasPrefix(infisicalToken, "st.") {
|
if strings.HasPrefix(infisicalToken, "st.") {
|
||||||
return &models.TokenDetails{
|
return &models.TokenDetails{
|
||||||
Type: SERVICE_TOKEN_IDENTIFIER,
|
Type: SERVICE_TOKEN_IDENTIFIER,
|
||||||
Token: infisicalToken,
|
Token: infisicalToken,
|
||||||
|
Source: source,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &models.TokenDetails{
|
return &models.TokenDetails{
|
||||||
Type: UNIVERSAL_AUTH_TOKEN_IDENTIFIER,
|
Type: UNIVERSAL_AUTH_TOKEN_IDENTIFIER,
|
||||||
Token: infisicalToken,
|
Token: infisicalToken,
|
||||||
|
Source: source,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user