mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 11:27:32 +00:00
fix: dashboard not showing when root accessn not provided
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SecretFoldersSchema, SecretImportsSchema, SecretTagsSchema } from "@app/db/schemas";
|
import { SecretFoldersSchema, SecretImportsSchema, SecretTagsSchema } from "@app/db/schemas";
|
||||||
@@ -173,60 +174,49 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeDynamicSecrets) {
|
try {
|
||||||
// this is the unique count, ie duplicate secrets across envs only count as 1
|
if (includeDynamicSecrets) {
|
||||||
totalDynamicSecretCount = await server.services.dynamicSecret.getCountMultiEnv({
|
// this is the unique count, ie duplicate secrets across envs only count as 1
|
||||||
actor: req.permission.type,
|
totalDynamicSecretCount = await server.services.dynamicSecret.getCountMultiEnv({
|
||||||
actorId: req.permission.id,
|
|
||||||
actorAuthMethod: req.permission.authMethod,
|
|
||||||
actorOrgId: req.permission.orgId,
|
|
||||||
projectId,
|
|
||||||
search,
|
|
||||||
environmentSlugs: environments,
|
|
||||||
path: secretPath
|
|
||||||
});
|
|
||||||
|
|
||||||
if (remainingLimit > 0 && totalDynamicSecretCount > adjustedOffset) {
|
|
||||||
dynamicSecrets = await server.services.dynamicSecret.listDynamicSecretsByFolderIds({
|
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId,
|
projectId,
|
||||||
search,
|
search,
|
||||||
orderBy,
|
|
||||||
orderDirection,
|
|
||||||
environmentSlugs: environments,
|
environmentSlugs: environments,
|
||||||
path: secretPath,
|
path: secretPath
|
||||||
limit: remainingLimit,
|
|
||||||
offset: adjustedOffset
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// get the count of unique dynamic secret names to properly adjust remaining limit
|
if (remainingLimit > 0 && totalDynamicSecretCount > adjustedOffset) {
|
||||||
const uniqueDynamicSecretsCount = new Set(dynamicSecrets.map((dynamicSecret) => dynamicSecret.name)).size;
|
dynamicSecrets = await server.services.dynamicSecret.listDynamicSecretsByFolderIds({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
projectId,
|
||||||
|
search,
|
||||||
|
orderBy,
|
||||||
|
orderDirection,
|
||||||
|
environmentSlugs: environments,
|
||||||
|
path: secretPath,
|
||||||
|
limit: remainingLimit,
|
||||||
|
offset: adjustedOffset
|
||||||
|
});
|
||||||
|
|
||||||
remainingLimit -= uniqueDynamicSecretsCount;
|
// get the count of unique dynamic secret names to properly adjust remaining limit
|
||||||
adjustedOffset = 0;
|
const uniqueDynamicSecretsCount = new Set(dynamicSecrets.map((dynamicSecret) => dynamicSecret.name)).size;
|
||||||
} else {
|
|
||||||
adjustedOffset = Math.max(0, adjustedOffset - totalDynamicSecretCount);
|
remainingLimit -= uniqueDynamicSecretsCount;
|
||||||
|
adjustedOffset = 0;
|
||||||
|
} else {
|
||||||
|
adjustedOffset = Math.max(0, adjustedOffset - totalDynamicSecretCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (includeSecrets) {
|
if (includeSecrets) {
|
||||||
// this is the unique count, ie duplicate secrets across envs only count as 1
|
// this is the unique count, ie duplicate secrets across envs only count as 1
|
||||||
totalSecretCount = await server.services.secret.getSecretsCountMultiEnv({
|
totalSecretCount = await server.services.secret.getSecretsCountMultiEnv({
|
||||||
actorId: req.permission.id,
|
|
||||||
actor: req.permission.type,
|
|
||||||
actorOrgId: req.permission.orgId,
|
|
||||||
environments,
|
|
||||||
actorAuthMethod: req.permission.authMethod,
|
|
||||||
projectId,
|
|
||||||
path: secretPath,
|
|
||||||
search
|
|
||||||
});
|
|
||||||
|
|
||||||
if (remainingLimit > 0 && totalSecretCount > adjustedOffset) {
|
|
||||||
secrets = await server.services.secret.getSecretsRawMultiEnv({
|
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
@@ -234,47 +224,64 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
projectId,
|
projectId,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
orderBy,
|
search
|
||||||
orderDirection,
|
|
||||||
search,
|
|
||||||
limit: remainingLimit,
|
|
||||||
offset: adjustedOffset
|
|
||||||
});
|
});
|
||||||
|
|
||||||
for await (const environment of environments) {
|
if (remainingLimit > 0 && totalSecretCount > adjustedOffset) {
|
||||||
const secretCountFromEnv = secrets.filter((secret) => secret.environment === environment).length;
|
secrets = await server.services.secret.getSecretsRawMultiEnv({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
environments,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
projectId,
|
||||||
|
path: secretPath,
|
||||||
|
orderBy,
|
||||||
|
orderDirection,
|
||||||
|
search,
|
||||||
|
limit: remainingLimit,
|
||||||
|
offset: adjustedOffset
|
||||||
|
});
|
||||||
|
|
||||||
if (secretCountFromEnv) {
|
for await (const environment of environments) {
|
||||||
await server.services.auditLog.createAuditLog({
|
const secretCountFromEnv = secrets.filter((secret) => secret.environment === environment).length;
|
||||||
projectId,
|
|
||||||
...req.auditLogInfo,
|
|
||||||
event: {
|
|
||||||
type: EventType.GET_SECRETS,
|
|
||||||
metadata: {
|
|
||||||
environment,
|
|
||||||
secretPath,
|
|
||||||
numberOfSecrets: secretCountFromEnv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (getUserAgentType(req.headers["user-agent"]) !== UserAgentType.K8_OPERATOR) {
|
if (secretCountFromEnv) {
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
await server.services.auditLog.createAuditLog({
|
||||||
event: PostHogEventTypes.SecretPulled,
|
projectId,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
...req.auditLogInfo,
|
||||||
properties: {
|
event: {
|
||||||
numberOfSecrets: secretCountFromEnv,
|
type: EventType.GET_SECRETS,
|
||||||
workspaceId: projectId,
|
metadata: {
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
channel: getUserAgentType(req.headers["user-agent"]),
|
numberOfSecrets: secretCountFromEnv
|
||||||
...req.auditLogInfo
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (getUserAgentType(req.headers["user-agent"]) !== UserAgentType.K8_OPERATOR) {
|
||||||
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
|
event: PostHogEventTypes.SecretPulled,
|
||||||
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
properties: {
|
||||||
|
numberOfSecrets: secretCountFromEnv,
|
||||||
|
workspaceId: projectId,
|
||||||
|
environment,
|
||||||
|
secretPath,
|
||||||
|
channel: getUserAgentType(req.headers["user-agent"]),
|
||||||
|
...req.auditLogInfo
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof ForbiddenError)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -498,56 +505,44 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeDynamicSecrets) {
|
try {
|
||||||
totalDynamicSecretCount = await server.services.dynamicSecret.getDynamicSecretCount({
|
if (includeDynamicSecrets) {
|
||||||
actor: req.permission.type,
|
totalDynamicSecretCount = await server.services.dynamicSecret.getDynamicSecretCount({
|
||||||
actorId: req.permission.id,
|
|
||||||
actorAuthMethod: req.permission.authMethod,
|
|
||||||
actorOrgId: req.permission.orgId,
|
|
||||||
projectId,
|
|
||||||
search,
|
|
||||||
environmentSlug: environment,
|
|
||||||
path: secretPath
|
|
||||||
});
|
|
||||||
|
|
||||||
if (remainingLimit > 0 && totalDynamicSecretCount > adjustedOffset) {
|
|
||||||
dynamicSecrets = await server.services.dynamicSecret.listDynamicSecretsByEnv({
|
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId,
|
projectId,
|
||||||
search,
|
search,
|
||||||
orderBy,
|
|
||||||
orderDirection,
|
|
||||||
environmentSlug: environment,
|
environmentSlug: environment,
|
||||||
path: secretPath,
|
path: secretPath
|
||||||
limit: remainingLimit,
|
|
||||||
offset: adjustedOffset
|
|
||||||
});
|
});
|
||||||
|
|
||||||
remainingLimit -= dynamicSecrets.length;
|
if (remainingLimit > 0 && totalDynamicSecretCount > adjustedOffset) {
|
||||||
adjustedOffset = 0;
|
dynamicSecrets = await server.services.dynamicSecret.listDynamicSecretsByEnv({
|
||||||
} else {
|
actor: req.permission.type,
|
||||||
adjustedOffset = Math.max(0, adjustedOffset - totalDynamicSecretCount);
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
projectId,
|
||||||
|
search,
|
||||||
|
orderBy,
|
||||||
|
orderDirection,
|
||||||
|
environmentSlug: environment,
|
||||||
|
path: secretPath,
|
||||||
|
limit: remainingLimit,
|
||||||
|
offset: adjustedOffset
|
||||||
|
});
|
||||||
|
|
||||||
|
remainingLimit -= dynamicSecrets.length;
|
||||||
|
adjustedOffset = 0;
|
||||||
|
} else {
|
||||||
|
adjustedOffset = Math.max(0, adjustedOffset - totalDynamicSecretCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (includeSecrets) {
|
if (includeSecrets) {
|
||||||
totalSecretCount = await server.services.secret.getSecretsCount({
|
totalSecretCount = await server.services.secret.getSecretsCount({
|
||||||
actorId: req.permission.id,
|
|
||||||
actor: req.permission.type,
|
|
||||||
actorOrgId: req.permission.orgId,
|
|
||||||
environment,
|
|
||||||
actorAuthMethod: req.permission.authMethod,
|
|
||||||
projectId,
|
|
||||||
path: secretPath,
|
|
||||||
search,
|
|
||||||
tagSlugs: tags
|
|
||||||
});
|
|
||||||
|
|
||||||
if (remainingLimit > 0 && totalSecretCount > adjustedOffset) {
|
|
||||||
const secretsRaw = await server.services.secret.getSecretsRaw({
|
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
@@ -555,44 +550,62 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
|||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
projectId,
|
projectId,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
orderBy,
|
|
||||||
orderDirection,
|
|
||||||
search,
|
search,
|
||||||
limit: remainingLimit,
|
|
||||||
offset: adjustedOffset,
|
|
||||||
tagSlugs: tags
|
tagSlugs: tags
|
||||||
});
|
});
|
||||||
|
|
||||||
secrets = secretsRaw.secrets;
|
if (remainingLimit > 0 && totalSecretCount > adjustedOffset) {
|
||||||
|
const secretsRaw = await server.services.secret.getSecretsRaw({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
environment,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
projectId,
|
||||||
|
path: secretPath,
|
||||||
|
orderBy,
|
||||||
|
orderDirection,
|
||||||
|
search,
|
||||||
|
limit: remainingLimit,
|
||||||
|
offset: adjustedOffset,
|
||||||
|
tagSlugs: tags
|
||||||
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
secrets = secretsRaw.secrets;
|
||||||
projectId,
|
|
||||||
...req.auditLogInfo,
|
|
||||||
event: {
|
|
||||||
type: EventType.GET_SECRETS,
|
|
||||||
metadata: {
|
|
||||||
environment,
|
|
||||||
secretPath,
|
|
||||||
numberOfSecrets: secrets.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (getUserAgentType(req.headers["user-agent"]) !== UserAgentType.K8_OPERATOR) {
|
await server.services.auditLog.createAuditLog({
|
||||||
await server.services.telemetry.sendPostHogEvents({
|
projectId,
|
||||||
event: PostHogEventTypes.SecretPulled,
|
...req.auditLogInfo,
|
||||||
distinctId: getTelemetryDistinctId(req),
|
event: {
|
||||||
properties: {
|
type: EventType.GET_SECRETS,
|
||||||
numberOfSecrets: secrets.length,
|
metadata: {
|
||||||
workspaceId: projectId,
|
environment,
|
||||||
environment,
|
secretPath,
|
||||||
secretPath,
|
numberOfSecrets: secrets.length
|
||||||
channel: getUserAgentType(req.headers["user-agent"]),
|
}
|
||||||
...req.auditLogInfo
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (getUserAgentType(req.headers["user-agent"]) !== UserAgentType.K8_OPERATOR) {
|
||||||
|
await server.services.telemetry.sendPostHogEvents({
|
||||||
|
event: PostHogEventTypes.SecretPulled,
|
||||||
|
distinctId: getTelemetryDistinctId(req),
|
||||||
|
properties: {
|
||||||
|
numberOfSecrets: secrets.length,
|
||||||
|
workspaceId: projectId,
|
||||||
|
environment,
|
||||||
|
secretPath,
|
||||||
|
channel: getUserAgentType(req.headers["user-agent"]),
|
||||||
|
...req.auditLogInfo
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof ForbiddenError)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -191,20 +191,10 @@ export const SecretOverviewPage = () => {
|
|||||||
|
|
||||||
const userAvailableEnvs = currentWorkspace?.environments || [];
|
const userAvailableEnvs = currentWorkspace?.environments || [];
|
||||||
|
|
||||||
const readableEnvs = userAvailableEnvs?.filter(({ slug }) =>
|
const [visibleEnvs, setVisibleEnvs] = useState(userAvailableEnvs);
|
||||||
permission.can(
|
|
||||||
ProjectPermissionActions.Read,
|
|
||||||
subject(ProjectPermissionSub.Secrets, {
|
|
||||||
environment: slug,
|
|
||||||
secretPath
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const [visibleEnvs, setVisibleEnvs] = useState(readableEnvs);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setVisibleEnvs(readableEnvs);
|
setVisibleEnvs(userAvailableEnvs);
|
||||||
}, [userAvailableEnvs, secretPath]);
|
}, [userAvailableEnvs, secretPath]);
|
||||||
|
|
||||||
const { isImportedSecretPresentInEnv, getImportedSecretByKey } = useGetImportedSecretsAllEnvs({
|
const { isImportedSecretPresentInEnv, getImportedSecretByKey } = useGetImportedSecretsAllEnvs({
|
||||||
@@ -529,9 +519,7 @@ export const SecretOverviewPage = () => {
|
|||||||
|
|
||||||
const isTableEmpty = totalCount === 0;
|
const isTableEmpty = totalCount === 0;
|
||||||
|
|
||||||
const isTableFiltered =
|
const isTableFiltered = Boolean(Object.values(filter).filter((enabled) => !enabled).length);
|
||||||
Boolean(Object.values(filter).filter((enabled) => !enabled).length) ||
|
|
||||||
visibleEnvs.length !== readableEnvs?.length;
|
|
||||||
|
|
||||||
if (!isProjectV3)
|
if (!isProjectV3)
|
||||||
return (
|
return (
|
||||||
@@ -611,7 +599,7 @@ export const SecretOverviewPage = () => {
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
<DropdownMenuLabel>Choose visible environments</DropdownMenuLabel>
|
<DropdownMenuLabel>Choose visible environments</DropdownMenuLabel>
|
||||||
{readableEnvs.map((availableEnv) => {
|
{userAvailableEnvs.map((availableEnv) => {
|
||||||
const { id: envId, name } = availableEnv;
|
const { id: envId, name } = availableEnv;
|
||||||
|
|
||||||
const isEnvSelected = visibleEnvs.map((env) => env.id).includes(envId);
|
const isEnvSelected = visibleEnvs.map((env) => env.id).includes(envId);
|
||||||
|
|||||||
Reference in New Issue
Block a user