mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Refactor approval URL construction in access and secret approval request services
- Updated the construction of approval URLs to use a consistent project path format. - Modified notification payloads to include the new approval URL structure. - Enhanced Slack message formatting to include buttons for viewing requests directly.
This commit is contained in:
@@ -399,7 +399,8 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
|
||||
const requesterFullName = `${requestedByUser.firstName} ${requestedByUser.lastName}`;
|
||||
const editorFullName = `${editedByUser.firstName} ${editedByUser.lastName}`;
|
||||
const approvalPath = `/projects/secret-management/${project.id}/approval`;
|
||||
const projectPath = `/projects/secret-management/${project.id}`;
|
||||
const approvalPath = `${projectPath}/approval`;
|
||||
const approvalUrl = `${cfg.SITE_URL}${approvalPath}`;
|
||||
|
||||
await triggerWorkflowIntegrationNotification({
|
||||
@@ -417,7 +418,8 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
approvalUrl,
|
||||
editNote,
|
||||
editorEmail: editedByUser.email as string,
|
||||
editorFullName
|
||||
editorFullName,
|
||||
projectPath
|
||||
}
|
||||
},
|
||||
projectId: project.id
|
||||
|
||||
@@ -37,7 +37,7 @@ export const sendApprovalEmailsFn = async ({
|
||||
type: NotificationType.SECRET_CHANGE_REQUEST,
|
||||
title: "Secret Change Request",
|
||||
body: `You have a new secret change request pending your review for the project **${project.name}** in the organization **${project.organization.name}**.`,
|
||||
link: `/projects/secret-management/${project.id}/approval?requestId=${secretApprovalRequest.id}`
|
||||
link: `/projects/secret-management/${project.id}/approval`
|
||||
}))
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@ export const sendApprovalEmailsFn = async ({
|
||||
firstName: reviewerUser.firstName,
|
||||
projectName: project.name,
|
||||
organizationName: project.organization.name,
|
||||
approvalUrl: `${cfg.SITE_URL}/projects/secret-management/${project.id}/approval?requestId=${secretApprovalRequest.id}`
|
||||
approvalUrl: `${cfg.SITE_URL}/projects/secret-management/${project.id}/approval}`
|
||||
},
|
||||
template: SmtpTemplates.SecretApprovalRequestNeedsReview
|
||||
});
|
||||
|
||||
@@ -1416,6 +1416,11 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
const env = await projectEnvDAL.findOne({ id: policy.envId });
|
||||
const user = await userDAL.findById(actorId);
|
||||
|
||||
const projectPath = `/projects/secret-management/${projectId}`;
|
||||
const approvalPath = `${projectPath}/approval`;
|
||||
const cfg = getConfig();
|
||||
const approvalUrl = `${cfg.SITE_URL}${approvalPath}`;
|
||||
|
||||
await triggerWorkflowIntegrationNotification({
|
||||
input: {
|
||||
projectId,
|
||||
@@ -1427,7 +1432,8 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
secretPath,
|
||||
projectId,
|
||||
requestId: secretApprovalRequest.id,
|
||||
secretKeys: [...new Set(Object.values(data).flatMap((arr) => arr?.map((item) => item.secretName) ?? []))]
|
||||
secretKeys: [...new Set(Object.values(data).flatMap((arr) => arr?.map((item) => item.secretName) ?? []))],
|
||||
approvalUrl
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1786,6 +1792,11 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
const user = await userDAL.findById(actorId);
|
||||
const env = await projectEnvDAL.findOne({ id: policy.envId });
|
||||
|
||||
const projectPath = `/projects/secret-management/${project.id}`;
|
||||
const approvalPath = `${projectPath}/approval`;
|
||||
const cfg = getConfig();
|
||||
const approvalUrl = `${cfg.SITE_URL}${approvalPath}`;
|
||||
|
||||
await triggerWorkflowIntegrationNotification({
|
||||
input: {
|
||||
projectId,
|
||||
@@ -1797,7 +1808,8 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
secretPath,
|
||||
projectId,
|
||||
requestId: secretApprovalRequest.id,
|
||||
secretKeys: [...new Set(Object.values(data).flatMap((arr) => arr?.map((item) => item.secretKey) ?? []))]
|
||||
secretKeys: [...new Set(Object.values(data).flatMap((arr) => arr?.map((item) => item.secretKey) ?? []))],
|
||||
approvalUrl
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -21,6 +21,7 @@ export type TNotification =
|
||||
requestId: string;
|
||||
projectId: string;
|
||||
secretKeys: string[];
|
||||
approvalUrl: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
@@ -52,6 +53,7 @@ export type TNotification =
|
||||
editNote?: string;
|
||||
editorFullName?: string;
|
||||
editorEmail?: string;
|
||||
projectPath: string;
|
||||
};
|
||||
}
|
||||
| {
|
||||
|
||||
@@ -51,13 +51,9 @@ const buildSlackPayload = (notification: TNotification) => {
|
||||
const messageBody = `A secret approval request has been opened by ${payload.userEmail}.
|
||||
*Environment*: ${payload.environment}
|
||||
*Secret path*: ${payload.secretPath || "/"}
|
||||
*Secret Key${payload.secretKeys.length > 1 ? "s" : ""}*: ${payload.secretKeys.join(", ")}
|
||||
*Secret Key${payload.secretKeys.length > 1 ? "s" : ""}*: ${payload.secretKeys.join(", ")}`;
|
||||
|
||||
View the complete details <${appCfg.SITE_URL}/projects/secret-management/${payload.projectId}/approval?requestId=${
|
||||
payload.requestId
|
||||
}|here>.`;
|
||||
|
||||
const payloadBlocks = [
|
||||
const headerBlocks = [
|
||||
{
|
||||
type: "header",
|
||||
text: {
|
||||
@@ -65,18 +61,36 @@ View the complete details <${appCfg.SITE_URL}/projects/secret-management/${paylo
|
||||
text: "Secret approval request",
|
||||
emoji: true
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
const payloadBlocks = [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: messageBody
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "actions",
|
||||
elements: [
|
||||
{
|
||||
type: "button",
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "View request",
|
||||
emoji: true
|
||||
},
|
||||
style: "primary",
|
||||
url: payload.approvalUrl
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
headerBlocks: [],
|
||||
headerBlocks,
|
||||
payloadMessage: messageBody,
|
||||
payloadBlocks,
|
||||
color: COMPANY_BRAND_COLOR
|
||||
@@ -84,12 +98,12 @@ View the complete details <${appCfg.SITE_URL}/projects/secret-management/${paylo
|
||||
}
|
||||
case TriggerFeature.ACCESS_REQUEST: {
|
||||
const { payload } = notification;
|
||||
const projectUrl = `${appCfg.SITE_URL}${payload.projectPath}`;
|
||||
const projectUrl = `${appCfg.SITE_URL}${payload.projectPath}/overview`;
|
||||
const accessType = payload.isTemporary ? "temporary" : "permanent";
|
||||
const permissionsFormatted = payload.permissions.map((p) => `*${p}*`).join(", ");
|
||||
|
||||
const messageBody = `${payload.requesterFullName} (${payload.requesterEmail}) has requested ${accessType} access to ${payload.secretPath} in the ${payload.environment} environment of ${payload.projectName}.\n\nThe following permissions are requested: ${payload.permissions.join(", ")}${
|
||||
payload.note ? `\n\nUser note\n${payload.note}` : ""
|
||||
payload.note ? `\n\nUser note: ${payload.note}` : ""
|
||||
}`;
|
||||
|
||||
const headerBlocks = [
|
||||
@@ -109,7 +123,7 @@ View the complete details <${appCfg.SITE_URL}/projects/secret-management/${paylo
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `*${payload.requesterFullName}* (${payload.requesterEmail}) has requested *${accessType}* access to *${payload.secretPath}* in the *${payload.environment}* environment of *<${projectUrl}|${payload.projectName}>*.\n\nThe following permissions are requested: ${permissionsFormatted}${
|
||||
payload.note ? `\n\n*User note*\n${payload.note}` : ""
|
||||
payload.note ? `\n\n*User note:* ${payload.note}` : ""
|
||||
}`
|
||||
}
|
||||
},
|
||||
@@ -139,20 +153,15 @@ View the complete details <${appCfg.SITE_URL}/projects/secret-management/${paylo
|
||||
}
|
||||
case TriggerFeature.ACCESS_REQUEST_UPDATED: {
|
||||
const { payload } = notification;
|
||||
const messageBody = `${payload.editorFullName} (${payload.editorEmail}) has updated the ${
|
||||
payload.isTemporary ? "temporary" : "permanent"
|
||||
} access request from ${payload.requesterFullName} (${payload.requesterEmail}) to ${payload.secretPath} in the ${payload.environment} environment of ${payload.projectName}.
|
||||
const projectUrl = `${appCfg.SITE_URL}${payload.projectPath}/overview`;
|
||||
const accessType = payload.isTemporary ? "temporary" : "permanent";
|
||||
const permissionsFormatted = payload.permissions.map((p) => `*${p}*`).join(", ");
|
||||
|
||||
The following permissions are requested: ${payload.permissions.join(", ")}
|
||||
|
||||
View the request and approve or deny it <${payload.approvalUrl}|here>.${
|
||||
payload.editNote
|
||||
? `
|
||||
Editor Note: ${payload.editNote}`
|
||||
: ""
|
||||
const messageBody = `${payload.editorFullName} (${payload.editorEmail}) has updated the ${accessType} access request from ${payload.requesterFullName} (${payload.requesterEmail}) to ${payload.secretPath} in the ${payload.environment} environment of ${payload.projectName}.\n\nThe following permissions are requested: ${payload.permissions.join(", ")}${
|
||||
payload.editNote ? `\n\nEditor Note: ${payload.editNote}` : ""
|
||||
}`;
|
||||
|
||||
const payloadBlocks = [
|
||||
const headerBlocks = [
|
||||
{
|
||||
type: "header",
|
||||
text: {
|
||||
@@ -160,18 +169,38 @@ Editor Note: ${payload.editNote}`
|
||||
text: "Updated access approval request pending for review",
|
||||
emoji: true
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
const payloadBlocks = [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: messageBody
|
||||
text: `*${payload.editorFullName}* (${payload.editorEmail}) has updated the *${accessType}* access request from *${payload.requesterFullName}* (${payload.requesterEmail}) to *${payload.secretPath}* in the *${payload.environment}* environment of *<${projectUrl}|${payload.projectName}>*.\n\nThe following permissions are requested: ${permissionsFormatted}${
|
||||
payload.editNote ? `\n\n*Editor Note:* ${payload.editNote}` : ""
|
||||
}`
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "actions",
|
||||
elements: [
|
||||
{
|
||||
type: "button",
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "View request",
|
||||
emoji: true
|
||||
},
|
||||
style: "primary",
|
||||
url: payload.approvalUrl
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
headerBlocks: [],
|
||||
headerBlocks,
|
||||
payloadMessage: messageBody,
|
||||
payloadBlocks,
|
||||
color: COMPANY_BRAND_COLOR
|
||||
@@ -198,7 +227,7 @@ Editor Note: ${payload.editNote}`
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `*Environment*\n${payload.environment}\n\n\n*Secret Path*\n${payload.secretPath}\n\n\n*Project*\n<${projectUrl}|${payload.projectName}>\n\n\n*Reason*\n${payload.failureMessage}`
|
||||
text: `*Environment:* ${payload.environment}\n\n*Secret Path:* ${payload.secretPath}\n\n*Project:* <${projectUrl}|${payload.projectName}>\n\n*Reason:* ${payload.failureMessage}`
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user