mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-10 07:28:50 +00:00
Merge pull request #1338 from akhilmhdh/feat/blind-index-fix
feat: changed blind index banner for everyone
This commit is contained in:
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas";
|
import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas";
|
||||||
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
}),
|
}),
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
offset: z.coerce.number().default(0),
|
offset: z.coerce.number().default(0),
|
||||||
limit: z.coerce.number().default(20)
|
limit: z.coerce.number().default(20)
|
||||||
}),
|
}),
|
||||||
@@ -46,7 +47,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
}),
|
}),
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/")
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SecretRotationOutputsSchema, SecretRotationsSchema, SecretsSchema } from "@app/db/schemas";
|
import { SecretRotationOutputsSchema, SecretRotationsSchema, SecretsSchema } from "@app/db/schemas";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
|
|||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
secretPath: z.string().trim(),
|
secretPath: z.string().trim().transform(removeTrailingSlash),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
interval: z.number().min(1),
|
interval: z.number().min(1),
|
||||||
provider: z.string().trim(),
|
provider: z.string().trim(),
|
||||||
|
|||||||
@@ -3,3 +3,9 @@ import path from "path";
|
|||||||
// given two paths irrespective of ending with / or not
|
// given two paths irrespective of ending with / or not
|
||||||
// this will return true if its equal
|
// this will return true if its equal
|
||||||
export const isSamePath = async (from: string, to: string) => !path.relative(from, to);
|
export const isSamePath = async (from: string, to: string) => !path.relative(from, to);
|
||||||
|
|
||||||
|
export const removeTrailingSlash = (str: string) => {
|
||||||
|
if (str === "/") return str;
|
||||||
|
|
||||||
|
return str.endsWith("/") ? str.slice(0, -1) : str;
|
||||||
|
};
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider
|
|||||||
req.log.error(error);
|
req.log.error(error);
|
||||||
if (error instanceof BadRequestError) {
|
if (error instanceof BadRequestError) {
|
||||||
res.status(400).send({ statusCode: 400, message: error.message, error: error.name });
|
res.status(400).send({ statusCode: 400, message: error.message, error: error.name });
|
||||||
} else if (error instanceof UnauthorizedError || error instanceof ForbiddenRequestError) {
|
} else if (error instanceof UnauthorizedError) {
|
||||||
res.status(403).send({ statusCode: 403, message: error.message, error: error.name });
|
res.status(403).send({ statusCode: 403, message: error.message, error: error.name });
|
||||||
} else if (error instanceof DatabaseError || error instanceof InternalServerError) {
|
} else if (error instanceof DatabaseError || error instanceof InternalServerError) {
|
||||||
res.status(500).send({ statusCode: 500, message: "Something went wrong", error: error.name });
|
res.status(500).send({ statusCode: 500, message: "Something went wrong", error: error.name });
|
||||||
} else if (error instanceof ZodError) {
|
} else if (error instanceof ZodError) {
|
||||||
res.status(403).send({ statusCode: 403, error: "ValidationFailure", message: error.issues });
|
res.status(403).send({ statusCode: 403, error: "ValidationFailure", message: error.issues });
|
||||||
} else if (error instanceof ForbiddenError) {
|
} else if (error instanceof ForbiddenError) {
|
||||||
res.status(403).send({
|
res.status(401).send({
|
||||||
statusCode: 403,
|
statusCode: 401,
|
||||||
error: "PermissionDenied",
|
error: "PermissionDenied",
|
||||||
message: `You are not allowed to ${error.action} on ${error.subjectType}`
|
message: `You are not allowed to ${error.action} on ${error.subjectType}`
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { IntegrationsSchema } from "@app/db/schemas";
|
import { IntegrationsSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { shake } from "@app/lib/fn";
|
import { removeTrailingSlash, shake } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
|
|||||||
app: z.string().trim().optional(),
|
app: z.string().trim().optional(),
|
||||||
isActive: z.boolean(),
|
isActive: z.boolean(),
|
||||||
appId: z.string().trim().optional(),
|
appId: z.string().trim().optional(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
sourceEnvironment: z.string().trim(),
|
sourceEnvironment: z.string().trim(),
|
||||||
targetEnvironment: z.string().trim().optional(),
|
targetEnvironment: z.string().trim().optional(),
|
||||||
targetEnvironmentId: z.string().trim().optional(),
|
targetEnvironmentId: z.string().trim().optional(),
|
||||||
@@ -89,7 +89,7 @@ export const registerIntegrationRouter = async (server: FastifyZodProvider) => {
|
|||||||
app: z.string().trim(),
|
app: z.string().trim(),
|
||||||
appId: z.string().trim(),
|
appId: z.string().trim(),
|
||||||
isActive: z.boolean(),
|
isActive: z.boolean(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
targetEnvironment: z.string().trim(),
|
targetEnvironment: z.string().trim(),
|
||||||
owner: z.string().trim(),
|
owner: z.string().trim(),
|
||||||
environment: z.string().trim()
|
environment: z.string().trim()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { SecretFoldersSchema } from "@app/db/schemas";
|
import { SecretFoldersSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -14,9 +15,9 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
name: z.string().trim(),
|
name: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
// backward compatiability with cli
|
// backward compatiability with cli
|
||||||
directory: z.string().trim().default("/")
|
directory: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -68,9 +69,9 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
name: z.string().trim(),
|
name: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
// backward compatiability with cli
|
// backward compatiability with cli
|
||||||
directory: z.string().trim().default("/")
|
directory: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -122,9 +123,9 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
// keep this here as cli need directory
|
// keep this here as cli need directory
|
||||||
directory: z.string().trim().default("/")
|
directory: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -172,9 +173,9 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
// backward compatiability with cli
|
// backward compatiability with cli
|
||||||
directory: z.string().trim().default("/")
|
directory: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas";
|
import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -13,10 +14,10 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
import: z.object({
|
import: z.object({
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim()
|
path: z.string().trim().transform(removeTrailingSlash)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -74,10 +75,14 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/"),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
import: z.object({
|
import: z.object({
|
||||||
environment: z.string().trim().optional(),
|
environment: z.string().trim().optional(),
|
||||||
path: z.string().trim().optional(),
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.optional()
|
||||||
|
.transform((val) => (val ? removeTrailingSlash(val) : val)),
|
||||||
position: z.number().optional()
|
position: z.number().optional()
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
@@ -137,7 +142,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/")
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -191,7 +196,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/")
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -243,7 +248,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/")
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { WebhooksSchema } from "@app/db/schemas";
|
import { WebhooksSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
|
|||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
webhookUrl: z.string().url().trim(),
|
webhookUrl: z.string().url().trim(),
|
||||||
webhookSecretKey: z.string().trim().optional(),
|
webhookSecretKey: z.string().trim().optional(),
|
||||||
secretPath: z.string().trim().default("/")
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -182,7 +183,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim().optional(),
|
environment: z.string().trim().optional(),
|
||||||
secretPath: z.string().trim().optional()
|
secretPath: z.string().trim().optional().transform((val)=> val?removeTrailingSlash(val):val)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { ServiceTokensSchema } from "@app/db/schemas";
|
import { ServiceTokensSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) =>
|
|||||||
scopes: z
|
scopes: z
|
||||||
.object({
|
.object({
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim()
|
secretPath: z.string().trim().transform(removeTrailingSlash)
|
||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
.min(1),
|
.min(1),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { CommitType } from "@app/ee/services/secret-approval-request/secret-approval-request-types";
|
import { CommitType } from "@app/ee/services/secret-approval-request/secret-approval-request-types";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
||||||
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
|
||||||
@@ -39,7 +40,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim().optional(),
|
workspaceId: z.string().trim().optional(),
|
||||||
environment: z.string().trim().optional(),
|
environment: z.string().trim().optional(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
include_imports: z
|
include_imports: z
|
||||||
.enum(["true", "false"])
|
.enum(["true", "false"])
|
||||||
.default("false")
|
.default("false")
|
||||||
@@ -129,7 +130,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim().optional(),
|
workspaceId: z.string().trim().optional(),
|
||||||
environment: z.string().trim().optional(),
|
environment: z.string().trim().optional(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
version: z.coerce.number().optional(),
|
version: z.coerce.number().optional(),
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
||||||
include_imports: z
|
include_imports: z
|
||||||
@@ -216,7 +217,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secretValue: z
|
secretValue: z
|
||||||
.string()
|
.string()
|
||||||
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
|
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
|
||||||
@@ -256,7 +257,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
event: {
|
event: {
|
||||||
type: EventType.CREATE_SECRET,
|
type: EventType.CREATE_SECRET,
|
||||||
metadata: {
|
metadata: {
|
||||||
environment: req.body.environment,
|
environment: req.body.environment,
|
||||||
secretPath: req.body.secretPath,
|
secretPath: req.body.secretPath,
|
||||||
secretId: secret.id,
|
secretId: secret.id,
|
||||||
secretKey: req.params.secretName,
|
secretKey: req.params.secretName,
|
||||||
@@ -295,7 +296,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
secretValue: z
|
secretValue: z
|
||||||
.string()
|
.string()
|
||||||
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
|
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
skipMultilineEncoding: z.boolean().optional(),
|
skipMultilineEncoding: z.boolean().optional(),
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared)
|
type: z.nativeEnum(SecretType).default(SecretType.Shared)
|
||||||
}),
|
}),
|
||||||
@@ -365,7 +366,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared)
|
type: z.nativeEnum(SecretType).default(SecretType.Shared)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -430,7 +431,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
include_imports: z
|
include_imports: z
|
||||||
.enum(["true", "false"])
|
.enum(["true", "false"])
|
||||||
.default("false")
|
.default("false")
|
||||||
@@ -518,7 +519,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
||||||
version: z.coerce.number().optional(),
|
version: z.coerce.number().optional(),
|
||||||
include_imports: z
|
include_imports: z
|
||||||
@@ -590,7 +591,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secretKeyCiphertext: z.string().trim(),
|
secretKeyCiphertext: z.string().trim(),
|
||||||
secretKeyIV: z.string().trim(),
|
secretKeyIV: z.string().trim(),
|
||||||
secretKeyTag: z.string().trim(),
|
secretKeyTag: z.string().trim(),
|
||||||
@@ -758,7 +759,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretId: z.string().trim().optional(),
|
secretId: z.string().trim().optional(),
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secretValueCiphertext: z.string().trim(),
|
secretValueCiphertext: z.string().trim(),
|
||||||
secretValueIV: z.string().trim(),
|
secretValueIV: z.string().trim(),
|
||||||
secretValueTag: z.string().trim(),
|
secretValueTag: z.string().trim(),
|
||||||
@@ -935,7 +936,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
type: z.nativeEnum(SecretType).default(SecretType.Shared),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secretId: z.string().trim().optional(),
|
secretId: z.string().trim().optional(),
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim()
|
environment: z.string().trim()
|
||||||
@@ -1050,7 +1051,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secrets: z
|
secrets: z
|
||||||
.object({
|
.object({
|
||||||
secretName: z.string().trim(),
|
secretName: z.string().trim(),
|
||||||
@@ -1176,7 +1177,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secrets: z
|
secrets: z
|
||||||
.object({
|
.object({
|
||||||
secretName: z.string().trim(),
|
secretName: z.string().trim(),
|
||||||
@@ -1301,7 +1302,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim(),
|
workspaceId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().default("/"),
|
secretPath: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
secrets: z
|
secrets: z
|
||||||
.object({
|
.object({
|
||||||
secretName: z.string().trim(),
|
secretName: z.string().trim(),
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ export const secretBlindIndexServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
actorId
|
actorId
|
||||||
}: TGetProjectBlindIndexStatusDTO) => {
|
}: TGetProjectBlindIndexStatusDTO) => {
|
||||||
const { membership } = await permissionService.getProjectPermission(actor, actorId, projectId);
|
await permissionService.getProjectPermission(actor, actorId, projectId);
|
||||||
if (membership?.role !== ProjectMembershipRole.Admin) {
|
|
||||||
throw new UnauthorizedError({ message: "User must be admin" });
|
|
||||||
}
|
|
||||||
|
|
||||||
const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId);
|
const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId);
|
||||||
return Number(secretCount);
|
return Number(secretCount);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
TSecretFoldersUpdate
|
TSecretFoldersUpdate
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
import { BadRequestError, DatabaseError } from "@app/lib/errors";
|
import { BadRequestError, DatabaseError } from "@app/lib/errors";
|
||||||
import { groupBy } from "@app/lib/fn";
|
import { groupBy, removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||||
|
|
||||||
export const validateFolderName = (folderName: string) => {
|
export const validateFolderName = (folderName: string) => {
|
||||||
@@ -238,10 +238,15 @@ export const secretFolderDALFactory = (db: TDbClient) => {
|
|||||||
tx?: Knex
|
tx?: Knex
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const folder = await sqlFindFolderByPathQuery(tx || db, projectId, environment, path)
|
const folder = await sqlFindFolderByPathQuery(
|
||||||
|
tx || db,
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
removeTrailingSlash(path)
|
||||||
|
)
|
||||||
.orderBy("depth", "desc")
|
.orderBy("depth", "desc")
|
||||||
.first();
|
.first();
|
||||||
if (folder && folder.path !== path) {
|
if (folder && folder.path !== removeTrailingSlash(path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!folder) return;
|
if (!folder) return;
|
||||||
@@ -262,7 +267,12 @@ export const secretFolderDALFactory = (db: TDbClient) => {
|
|||||||
tx?: Knex
|
tx?: Knex
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const folder = await sqlFindFolderByPathQuery(tx || db, projectId, environment, path)
|
const folder = await sqlFindFolderByPathQuery(
|
||||||
|
tx || db,
|
||||||
|
projectId,
|
||||||
|
environment,
|
||||||
|
removeTrailingSlash(path)
|
||||||
|
)
|
||||||
.orderBy("depth", "desc")
|
.orderBy("depth", "desc")
|
||||||
.first();
|
.first();
|
||||||
if (!folder) return;
|
if (!folder) return;
|
||||||
@@ -278,8 +288,12 @@ export const secretFolderDALFactory = (db: TDbClient) => {
|
|||||||
tx?: Knex
|
tx?: Knex
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const folders = await sqlFindMultipleFolderByEnvPathQuery(tx || db, query);
|
const formatedQuery = query.map(({ secretPath, envId }) => ({
|
||||||
return query.map(({ envId, secretPath }) =>
|
envId,
|
||||||
|
secretPath: removeTrailingSlash(secretPath)
|
||||||
|
}));
|
||||||
|
const folders = await sqlFindMultipleFolderByEnvPathQuery(tx || db, formatedQuery);
|
||||||
|
return formatedQuery.map(({ envId, secretPath }) =>
|
||||||
folders.find(
|
folders.find(
|
||||||
({ path: targetPath, envId: targetEnvId }) =>
|
({ path: targetPath, envId: targetEnvId }) =>
|
||||||
targetPath === secretPath && targetEnvId === envId
|
targetPath === secretPath && targetEnvId === envId
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const ProjectPermissionCan: FunctionComponent<Props> = ({
|
|||||||
allowedLabel,
|
allowedLabel,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
return (
|
return (
|
||||||
<Can {...props} passThrough={passThrough} ability={props?.ability || permission}>
|
<Can {...props} passThrough={passThrough} ability={props?.ability || permission}>
|
||||||
{(isAllowed, ability) => {
|
{(isAllowed, ability) => {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createContext, ReactNode, useContext } from "react";
|
import { createContext, ReactNode, useContext } from "react";
|
||||||
|
|
||||||
import { useGetUserProjectPermissions } from "@app/hooks/api";
|
import { useGetUserProjectPermissions } from "@app/hooks/api";
|
||||||
|
import { TProjectMembership } from "@app/hooks/api/users/types";
|
||||||
|
|
||||||
import { useWorkspace } from "../WorkspaceContext";
|
import { useWorkspace } from "../WorkspaceContext";
|
||||||
import { TProjectPermission } from "./types";
|
import { TProjectPermission } from "./types";
|
||||||
@@ -9,7 +10,10 @@ type Props = {
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ProjectPermissionContext = createContext<null | TProjectPermission>(null);
|
const ProjectPermissionContext = createContext<null | {
|
||||||
|
permission: TProjectPermission;
|
||||||
|
membership: TProjectMembership;
|
||||||
|
}>(null);
|
||||||
|
|
||||||
export const ProjectPermissionProvider = ({ children }: Props): JSX.Element => {
|
export const ProjectPermissionProvider = ({ children }: Props): JSX.Element => {
|
||||||
const { currentWorkspace, isLoading: isWsLoading } = useWorkspace();
|
const { currentWorkspace, isLoading: isWsLoading } = useWorkspace();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const withProjectPermission = <T extends {}, J extends TProjectPermission
|
|||||||
{ action, subject, className, containerClassName }: Props<Generics<J>["abilities"]>
|
{ action, subject, className, containerClassName }: Props<Generics<J>["abilities"]>
|
||||||
) => {
|
) => {
|
||||||
const HOC = (hocProps: T) => {
|
const HOC = (hocProps: T) => {
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
|
|
||||||
// akhilmhdh: Set as any due to casl/react ts type bug
|
// akhilmhdh: Set as any due to casl/react ts type bug
|
||||||
// REASON: casl due to its type checking can't seem to union even if union intersection is applied
|
// REASON: casl due to its type checking can't seem to union even if union intersection is applied
|
||||||
@@ -29,13 +29,13 @@ export const withProjectPermission = <T extends {}, J extends TProjectPermission
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"container h-full mx-auto flex justify-center items-center",
|
"container mx-auto flex h-full items-center justify-center",
|
||||||
containerClassName
|
containerClassName
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"rounded-md bg-mineshaft-800 text-bunker-300 p-16 flex space-x-12 items-end",
|
"flex items-end space-x-12 rounded-md bg-mineshaft-800 p-16 text-bunker-300",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -43,7 +43,7 @@ export const withProjectPermission = <T extends {}, J extends TProjectPermission
|
|||||||
<FontAwesomeIcon icon={faLock} size="6x" />
|
<FontAwesomeIcon icon={faLock} size="6x" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="text-4xl font-medium mb-2">Permission Denied</div>
|
<div className="mb-2 text-4xl font-medium">Permission Denied</div>
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
You do not have permission to this page. <br /> Kindly contact your organization
|
You do not have permission to this page. <br /> Kindly contact your organization
|
||||||
administrator
|
administrator
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { apiRequest } from "@app/config/request";
|
|||||||
import { OrgPermissionSet } from "@app/context/OrgPermissionContext/types";
|
import { OrgPermissionSet } from "@app/context/OrgPermissionContext/types";
|
||||||
import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext/types";
|
import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext/types";
|
||||||
|
|
||||||
import { OrgUser } from "../users/types";
|
import { OrgUser, TProjectMembership } from "../users/types";
|
||||||
import {
|
import {
|
||||||
TGetUserOrgPermissionsDTO,
|
TGetUserOrgPermissionsDTO,
|
||||||
TGetUserProjectPermissionDTO,
|
TGetUserProjectPermissionDTO,
|
||||||
@@ -104,10 +104,13 @@ export const useGetUserOrgPermissions = ({ orgId }: TGetUserOrgPermissionsDTO) =
|
|||||||
|
|
||||||
const getUserProjectPermissions = async ({ workspaceId }: TGetUserProjectPermissionDTO) => {
|
const getUserProjectPermissions = async ({ workspaceId }: TGetUserProjectPermissionDTO) => {
|
||||||
const { data } = await apiRequest.get<{
|
const { data } = await apiRequest.get<{
|
||||||
data: { permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[] };
|
data: {
|
||||||
|
permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[];
|
||||||
|
membership: TProjectMembership;
|
||||||
|
};
|
||||||
}>(`/api/v1/workspace/${workspaceId}/permissions`, {});
|
}>(`/api/v1/workspace/${workspaceId}/permissions`, {});
|
||||||
|
|
||||||
return data.data.permissions;
|
return data.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPermissionDTO) =>
|
export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPermissionDTO) =>
|
||||||
@@ -116,8 +119,8 @@ export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPer
|
|||||||
queryFn: () => getUserProjectPermissions({ workspaceId }),
|
queryFn: () => getUserProjectPermissions({ workspaceId }),
|
||||||
enabled: Boolean(workspaceId),
|
enabled: Boolean(workspaceId),
|
||||||
select: (data) => {
|
select: (data) => {
|
||||||
const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data);
|
const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data.permissions);
|
||||||
const ability = createMongoAbility<ProjectPermissionSet>(rule, { conditionsMatcher });
|
const ability = createMongoAbility<ProjectPermissionSet>(rule, { conditionsMatcher });
|
||||||
return ability;
|
return { permission: ability, membership: data.membership };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,6 +52,15 @@ export type OrgUser = {
|
|||||||
roleId: string;
|
roleId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TProjectMembership = {
|
||||||
|
id: string;
|
||||||
|
role: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
projectId: string;
|
||||||
|
roleId: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type TWorkspaceUser = OrgUser;
|
export type TWorkspaceUser = OrgUser;
|
||||||
|
|
||||||
export type AddUserToWsDTO = {
|
export type AddUserToWsDTO = {
|
||||||
|
|||||||
+2
-2
@@ -30,7 +30,7 @@ export const CloudIntegrationSection = ({
|
|||||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||||
"deleteConfirmation"
|
"deleteConfirmation"
|
||||||
] as const);
|
] as const);
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
const { createNotification } = useNotificationContext();
|
const { createNotification } = useNotificationContext();
|
||||||
|
|
||||||
const isEmpty = !isLoading && !cloudIntegrations?.length;
|
const isEmpty = !isLoading && !cloudIntegrations?.length;
|
||||||
@@ -43,7 +43,7 @@ export const CloudIntegrationSection = ({
|
|||||||
<h1 className="text-3xl font-semibold">{t("integrations.cloud-integrations")}</h1>
|
<h1 className="text-3xl font-semibold">{t("integrations.cloud-integrations")}</h1>
|
||||||
<p className="text-base text-gray-400">{t("integrations.click-to-start")}</p>
|
<p className="text-base text-gray-400">{t("integrations.click-to-start")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-6 grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4">
|
<div className="mx-6 grid grid-cols-2 gap-4 lg:grid-cols-3 2xl:grid-cols-4">
|
||||||
{isLoading &&
|
{isLoading &&
|
||||||
Array.from({ length: 12 }).map((_, index) => (
|
Array.from({ length: 12 }).map((_, index) => (
|
||||||
<Skeleton className="h-32" key={`cloud-integration-skeleton-${index + 1}`} />
|
<Skeleton className="h-32" key={`cloud-integration-skeleton-${index + 1}`} />
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ export const SecretApprovalPolicyList = ({ workspaceId }: Props) => {
|
|||||||
"deletePolicy",
|
"deletePolicy",
|
||||||
"upgradePlan"
|
"upgradePlan"
|
||||||
] as const);
|
] as const);
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
const { createNotification } = useNotificationContext();
|
const { createNotification } = useNotificationContext();
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ export const SecretApprovalPolicyRow = ({
|
|||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [selectedApprovers, setSelectedApprovers] = useState<string[]>([]);
|
const [selectedApprovers, setSelectedApprovers] = useState<string[]>([]);
|
||||||
const { mutate: updateSecretApprovalPolicy, isLoading } = useUpdateSecretApprovalPolicy();
|
const { mutate: updateSecretApprovalPolicy, isLoading } = useUpdateSecretApprovalPolicy();
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tr>
|
<Tr>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const SecretMainPage = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
|
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
const [sortDir, setSortDir] = useState<SortDir>(SortDir.ASC);
|
const [sortDir, setSortDir] = useState<SortDir>(SortDir.ASC);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export const SecretDetailSidebar = ({
|
|||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
values: secret
|
values: secret
|
||||||
});
|
});
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
const cannotEditSecret = permission.cannot(
|
const cannotEditSecret = permission.cannot(
|
||||||
ProjectPermissionActions.Edit,
|
ProjectPermissionActions.Edit,
|
||||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export const SecretItem = memo(
|
|||||||
secretPath
|
secretPath
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
const isReadOnly =
|
const isReadOnly =
|
||||||
permission.can(
|
permission.can(
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionActions.Read,
|
||||||
|
|||||||
+13
-4
@@ -4,9 +4,15 @@ import {
|
|||||||
decryptSymmetric
|
decryptSymmetric
|
||||||
} from "@app/components/utilities/cryptography/crypto";
|
} from "@app/components/utilities/cryptography/crypto";
|
||||||
import { Button, Spinner } from "@app/components/v2";
|
import { Button, Spinner } from "@app/components/v2";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
import {
|
||||||
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionSub,
|
||||||
|
useProjectPermission,
|
||||||
|
useWorkspace
|
||||||
|
} from "@app/context";
|
||||||
import { useToggle } from "@app/hooks";
|
import { useToggle } from "@app/hooks";
|
||||||
import { useGetWorkspaceIndexStatus, useNameWorkspaceSecrets } from "@app/hooks/api";
|
import { useGetWorkspaceIndexStatus, useNameWorkspaceSecrets } from "@app/hooks/api";
|
||||||
|
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||||
import { UserWsKeyPair } from "@app/hooks/api/types";
|
import { UserWsKeyPair } from "@app/hooks/api/types";
|
||||||
import { fetchWorkspaceSecrets } from "@app/hooks/api/workspace/queries";
|
import { fetchWorkspaceSecrets } from "@app/hooks/api/workspace/queries";
|
||||||
|
|
||||||
@@ -18,6 +24,7 @@ type Props = {
|
|||||||
|
|
||||||
export const ProjectIndexSecretsSection = ({ decryptFileKey }: Props) => {
|
export const ProjectIndexSecretsSection = ({ decryptFileKey }: Props) => {
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
|
const { membership } = useProjectPermission();
|
||||||
const { data: isBlindIndexed, isLoading: isBlindIndexedLoading } = useGetWorkspaceIndexStatus(
|
const { data: isBlindIndexed, isLoading: isBlindIndexedLoading } = useGetWorkspaceIndexStatus(
|
||||||
currentWorkspace?.id ?? ""
|
currentWorkspace?.id ?? ""
|
||||||
);
|
);
|
||||||
@@ -74,17 +81,19 @@ export const ProjectIndexSecretsSection = ({ decryptFileKey }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<p className="mb-2 text-lg font-semibold">Enable Blind Indices</p>
|
<p className="mb-2 text-lg font-semibold">Action Required</p>
|
||||||
<p className="mb-4 leading-7 text-gray-400">
|
<p className="mb-4 leading-7 text-gray-400">
|
||||||
Your project was created before the introduction of blind indexing. To continue accessing
|
Your project was created before the introduction of blind indexing. To continue accessing
|
||||||
secrets by name through the SDK, public API and web dashboard, please enable blind indexing.{" "}
|
secrets by name through the SDK, public API and web dashboard, please enable blind indexing.{" "}
|
||||||
<b>This is a one time process.</b>
|
<b>
|
||||||
|
{membership.role !== ProjectMembershipRole.Admin && "This is an admin only operation."}
|
||||||
|
</b>
|
||||||
</p>
|
</p>
|
||||||
<ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}>
|
<ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
onClick={onEnableBlindIndices}
|
onClick={onEnableBlindIndices}
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed || membership.role !== ProjectMembershipRole.Admin}
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
type="submit"
|
type="submit"
|
||||||
isLoading={isIndexing}
|
isLoading={isIndexing}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const SecretRotationPage = withProjectPermission(
|
|||||||
() => {
|
() => {
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
const { createNotification } = useNotificationContext();
|
const { createNotification } = useNotificationContext();
|
||||||
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
|
||||||
"createRotation",
|
"createRotation",
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,7 @@ export const EnvironmentSection = () => {
|
|||||||
const { createNotification } = useNotificationContext();
|
const { createNotification } = useNotificationContext();
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
const permision = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
|
|
||||||
const deleteWsEnvironment = useDeleteWsEnvironment();
|
const deleteWsEnvironment = useDeleteWsEnvironment();
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ export const EnvironmentSection = () => {
|
|||||||
Choose which environments will show up in your dashboard like development, staging,
|
Choose which environments will show up in your dashboard like development, staging,
|
||||||
production
|
production
|
||||||
</p>
|
</p>
|
||||||
{permision.can(ProjectPermissionActions.Read, ProjectPermissionSub.Environments) ? (
|
{permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Environments) ? (
|
||||||
<EnvironmentTable handlePopUpOpen={handlePopUpOpen} />
|
<EnvironmentTable handlePopUpOpen={handlePopUpOpen} />
|
||||||
) : (
|
) : (
|
||||||
<PermissionDeniedBanner />
|
<PermissionDeniedBanner />
|
||||||
|
|||||||
+11
-6
@@ -4,7 +4,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||||
import { PermissionDeniedBanner, ProjectPermissionCan } from "@app/components/permissions";
|
import { PermissionDeniedBanner, ProjectPermissionCan } from "@app/components/permissions";
|
||||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||||
import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission, useWorkspace } from "@app/context";
|
import {
|
||||||
|
ProjectPermissionActions,
|
||||||
|
ProjectPermissionSub,
|
||||||
|
useProjectPermission,
|
||||||
|
useWorkspace
|
||||||
|
} from "@app/context";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useDeleteWsTag } from "@app/hooks/api";
|
import { useDeleteWsTag } from "@app/hooks/api";
|
||||||
|
|
||||||
@@ -20,14 +25,14 @@ export const SecretTagsSection = (): JSX.Element => {
|
|||||||
"deleteTagConfirmation"
|
"deleteTagConfirmation"
|
||||||
] as const);
|
] as const);
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
const permission = useProjectPermission();
|
const { permission } = useProjectPermission();
|
||||||
|
|
||||||
const deleteWsTag = useDeleteWsTag();
|
const deleteWsTag = useDeleteWsTag();
|
||||||
|
|
||||||
const onDeleteApproved = async () => {
|
const onDeleteApproved = async () => {
|
||||||
try {
|
try {
|
||||||
await deleteWsTag.mutateAsync({
|
await deleteWsTag.mutateAsync({
|
||||||
projectId:currentWorkspace?.id || "",
|
projectId: currentWorkspace?.id || "",
|
||||||
tagID: (popUp?.deleteTagConfirmation?.data as DeleteModalData)?.id
|
tagID: (popUp?.deleteTagConfirmation?.data as DeleteModalData)?.id
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -47,8 +52,8 @@ export const SecretTagsSection = (): JSX.Element => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mb-6 p-4 bg-mineshaft-900 rounded-lg border border-mineshaft-600">
|
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
<div className="flex justify-between mb-8">
|
<div className="mb-8 flex justify-between">
|
||||||
<p className="mb-3 text-xl font-semibold">Secret Tags</p>
|
<p className="mb-3 text-xl font-semibold">Secret Tags</p>
|
||||||
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.Tags}>
|
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.Tags}>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
@@ -65,7 +70,7 @@ export const SecretTagsSection = (): JSX.Element => {
|
|||||||
)}
|
)}
|
||||||
</ProjectPermissionCan>
|
</ProjectPermissionCan>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-gray-400 mb-8">
|
<p className="mb-8 text-gray-400">
|
||||||
Every secret can be assigned to one or more tags. Here you can add and remove tags for the
|
Every secret can be assigned to one or more tags. Here you can add and remove tags for the
|
||||||
current project.
|
current project.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user