mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-17 02:47:35 +00:00
Add more audit log events
This commit is contained in:
@@ -3,7 +3,9 @@ import { Types } from "mongoose";
|
||||
import { standardRequest } from "../../config/request";
|
||||
import { getApps, getTeams, revokeAccess } from "../../integrations";
|
||||
import { Bot, IntegrationAuth } from "../../models";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { IntegrationService } from "../../services";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import {
|
||||
ALGORITHM_AES_256_GCM,
|
||||
ENCODING_SCHEME_UTF8,
|
||||
@@ -62,6 +64,19 @@ export const oAuthExchange = async (req: Request, res: Response) => {
|
||||
environment: environments[0].slug
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.AUTHORIZE_INTEGRATION,
|
||||
metadata: {
|
||||
integration: integrationAuth.integration
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integrationAuth.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integrationAuth
|
||||
});
|
||||
@@ -129,6 +144,19 @@ export const saveIntegrationAccessToken = async (req: Request, res: Response) =>
|
||||
});
|
||||
|
||||
if (!integrationAuth) throw new Error("Failed to save integration access token");
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.AUTHORIZE_INTEGRATION,
|
||||
metadata: {
|
||||
integration: integrationAuth.integration
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integrationAuth.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integrationAuth
|
||||
@@ -530,6 +558,23 @@ export const deleteIntegrationAuth = async (req: Request, res: Response) => {
|
||||
integrationAuth: req.integrationAuth,
|
||||
accessToken: req.accessToken
|
||||
});
|
||||
|
||||
if (!integrationAuth) return res.status(400).send({
|
||||
message: "Failed to find integration authorization"
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UNAUTHORIZE_INTEGRATION,
|
||||
metadata: {
|
||||
integration: integrationAuth.integration
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integrationAuth.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integrationAuth
|
||||
|
||||
@@ -6,6 +6,8 @@ import { eventStartIntegration } from "../../events";
|
||||
import Folder from "../../models/folder";
|
||||
import { getFolderByPath } from "../../services/FolderService";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import { EventType } from "../../ee/models";
|
||||
|
||||
/**
|
||||
* Create/initialize an (empty) integration for integration authorization
|
||||
@@ -74,6 +76,25 @@ export const createIntegration = async (req: Request, res: Response) => {
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_INTEGRATION,
|
||||
metadata: {
|
||||
integrationId: integration._id.toString(),
|
||||
integration: integration.integration,
|
||||
environment: integration.environment,
|
||||
secretPath,
|
||||
app: integration.app,
|
||||
targetEnvironment: integration.targetEnvironment,
|
||||
targetEnvironmentId: integration.targetEnvironmentId
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integration.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integration
|
||||
@@ -148,8 +169,7 @@ export const updateIntegration = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete integration with id [integrationId] and deactivate bot if there are
|
||||
* no integrations left
|
||||
* Delete integration with id [integrationId]
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
@@ -163,6 +183,25 @@ export const deleteIntegration = async (req: Request, res: Response) => {
|
||||
|
||||
if (!integration) throw new Error("Failed to find integration");
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_INTEGRATION,
|
||||
metadata: {
|
||||
integrationId: integration._id.toString(),
|
||||
integration: integration.integration,
|
||||
environment: integration.environment,
|
||||
secretPath: integration.secretPath,
|
||||
app: integration.app,
|
||||
targetEnvironment: integration.targetEnvironment,
|
||||
targetEnvironmentId: integration.targetEnvironmentId
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integration.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integration
|
||||
});
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Key, Membership, MembershipOrg, User } from "../../models";
|
||||
import { Types } from "mongoose";
|
||||
import { Key, Membership, MembershipOrg, User, IUser } from "../../models";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { deleteMembership as deleteMember, findMembership } from "../../helpers/membership";
|
||||
import { sendMail } from "../../helpers/nodemailer";
|
||||
import { ACCEPTED, ADMIN, MEMBER } from "../../variables";
|
||||
import { getSiteURL } from "../../config";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
|
||||
/**
|
||||
* Check that user is a member of workspace with id [workspaceId]
|
||||
@@ -36,11 +39,11 @@ export const validateMembership = async (req: Request, res: Response) => {
|
||||
*/
|
||||
export const deleteMembership = async (req: Request, res: Response) => {
|
||||
const { membershipId } = req.params;
|
||||
|
||||
|
||||
// check if membership to delete exists
|
||||
const membershipToDelete = await Membership.findOne({
|
||||
_id: membershipId
|
||||
}).populate("user");
|
||||
}).populate<{ user: IUser }>("user");
|
||||
|
||||
if (!membershipToDelete) {
|
||||
throw new Error("Failed to delete workspace membership that doesn't exist");
|
||||
@@ -66,6 +69,20 @@ export const deleteMembership = async (req: Request, res: Response) => {
|
||||
const deletedMembership = await deleteMember({
|
||||
membershipId: membershipToDelete._id.toString()
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.REMOVE_WORKSPACE_MEMBER,
|
||||
metadata: {
|
||||
userId: membershipToDelete.user._id.toString(),
|
||||
email: membershipToDelete.user.email
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: membership.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
deletedMembership
|
||||
@@ -140,7 +157,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
|
||||
const inviteeMembership = await Membership.findOne({
|
||||
user: invitee._id,
|
||||
workspace: workspaceId
|
||||
});
|
||||
}).populate<{ user: IUser }>("user");
|
||||
|
||||
if (inviteeMembership) throw new Error("Failed to add existing member of workspace");
|
||||
|
||||
@@ -181,6 +198,20 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
|
||||
}
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.ADD_WORKSPACE_MEMBER,
|
||||
metadata: {
|
||||
userId: invitee._id.toString(),
|
||||
email: invitee.email
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
invitee,
|
||||
latestKey
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Secret } from "../../models";
|
||||
import { Types } from "mongoose";
|
||||
import Folder from "../../models/folder";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import {
|
||||
@@ -8,6 +9,7 @@ import {
|
||||
generateFolderId,
|
||||
getAllFolderIds,
|
||||
getFolderByPath,
|
||||
getFolderPath,
|
||||
getParentFromFolderId,
|
||||
searchByFolderId,
|
||||
searchByFolderIdWithDir,
|
||||
@@ -15,10 +17,9 @@ import {
|
||||
} from "../../services/FolderService";
|
||||
import { ADMIN, MEMBER } from "../../variables";
|
||||
import { validateMembership } from "../../helpers/membership";
|
||||
import { FolderVersion } from "../../ee/models";
|
||||
import { EESecretService } from "../../ee/services";
|
||||
import { FolderVersion, EventType } from "../../ee/models";
|
||||
import { EESecretService, EEAuditLogService } from "../../ee/services";
|
||||
|
||||
// TODO
|
||||
// verify workspace id/environment
|
||||
export const createFolder = async (req: Request, res: Response) => {
|
||||
const { workspaceId, environment, folderName, parentFolderId } = req.body;
|
||||
@@ -33,6 +34,7 @@ export const createFolder = async (req: Request, res: Response) => {
|
||||
environment,
|
||||
}).lean();
|
||||
// space has no folders initialized
|
||||
|
||||
if (!folders) {
|
||||
const id = generateFolderId();
|
||||
const folder = new Folder({
|
||||
@@ -56,13 +58,32 @@ export const createFolder = async (req: Request, res: Response) => {
|
||||
workspaceId,
|
||||
environment,
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_FOLDER,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId: id,
|
||||
folderName,
|
||||
folderPath: `root/${folderName}`
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.json({ folder: { id, name: folderName } });
|
||||
}
|
||||
|
||||
const folder = appendFolder(folders.nodes, { folderName, parentFolderId });
|
||||
|
||||
await Folder.findByIdAndUpdate(folders._id, folders);
|
||||
|
||||
const parentFolder = searchByFolderId(folders.nodes, parentFolderId);
|
||||
|
||||
const folderVersion = new FolderVersion({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
@@ -75,6 +96,24 @@ export const createFolder = async (req: Request, res: Response) => {
|
||||
environment,
|
||||
folderId: parentFolderId,
|
||||
});
|
||||
|
||||
const folderPath = await getFolderPath(folders, folder.id);
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_FOLDER,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId: folder.id,
|
||||
folderName,
|
||||
folderPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.json({ folder });
|
||||
};
|
||||
@@ -87,7 +126,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
||||
if (!folders) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
|
||||
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
@@ -100,10 +139,12 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
const folder = parentFolder.children.find(({ id }) => id === folderId);
|
||||
|
||||
if (!folder) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
|
||||
const oldFolderName = folder.name;
|
||||
parentFolder.version += 1;
|
||||
folder.name = name;
|
||||
|
||||
@@ -121,6 +162,25 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
||||
folderId: parentFolder.id,
|
||||
});
|
||||
|
||||
const folderPath = await getFolderPath(folders, folder.id);
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_FOLDER,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId: folder.id,
|
||||
oldFolderName,
|
||||
newFolderName: name,
|
||||
folderPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.json({
|
||||
message: "Successfully updated folder",
|
||||
folder: { name: folder.name, id: folder.id },
|
||||
@@ -143,6 +203,8 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
});
|
||||
|
||||
const folderPath = await getFolderPath(folders, folderId);
|
||||
|
||||
const delOp = deleteFolderById(folders.nodes, folderId);
|
||||
if (!delOp) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
@@ -173,6 +235,22 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
||||
folderId: parentFolder.id,
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_FOLDER ,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId,
|
||||
folderName: delFolder.name,
|
||||
folderPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
res.send({ message: "successfully deleted folders", folders: delFolderIds });
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import { client, getRootEncryptionKey } from "../../config";
|
||||
import { validateMembership } from "../../helpers";
|
||||
import Webhook from "../../models/webhooks";
|
||||
import { getWebhookPayload, triggerWebhookRequest } from "../../services/WebhookService";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import { BadRequestError, ResourceNotFoundError } from "../../utils/errors";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { ADMIN, ALGORITHM_AES_256_GCM, ENCODING_SCHEME_BASE64, MEMBER } from "../../variables";
|
||||
|
||||
export const createWebhook = async (req: Request, res: Response) => {
|
||||
@@ -27,6 +29,23 @@ export const createWebhook = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
await webhook.save();
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_WEBHOOK,
|
||||
metadata: {
|
||||
webhookId: webhook._id.toString(),
|
||||
environment,
|
||||
secretPath,
|
||||
webhookUrl,
|
||||
isDisabled: false
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
webhook,
|
||||
@@ -54,6 +73,23 @@ export const updateWebhook = async (req: Request, res: Response) => {
|
||||
}
|
||||
await webhook.save();
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_WEBHOOK_STATUS,
|
||||
metadata: {
|
||||
webhookId: webhook._id.toString(),
|
||||
environment: webhook.environment,
|
||||
secretPath: webhook.secretPath,
|
||||
webhookUrl: webhook.url,
|
||||
isDisabled
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: webhook.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
webhook,
|
||||
message: "successfully updated webhook"
|
||||
@@ -62,9 +98,10 @@ export const updateWebhook = async (req: Request, res: Response) => {
|
||||
|
||||
export const deleteWebhook = async (req: Request, res: Response) => {
|
||||
const { webhookId } = req.params;
|
||||
const webhook = await Webhook.findById(webhookId);
|
||||
let webhook = await Webhook.findById(webhookId);
|
||||
|
||||
if (!webhook) {
|
||||
throw BadRequestError({ message: "Webhook not found!!" });
|
||||
throw ResourceNotFoundError({ message: "Webhook not found!!" });
|
||||
}
|
||||
|
||||
await validateMembership({
|
||||
@@ -72,8 +109,29 @@ export const deleteWebhook = async (req: Request, res: Response) => {
|
||||
workspaceId: webhook.workspace,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
|
||||
webhook = await Webhook.findByIdAndDelete(webhookId);
|
||||
|
||||
await webhook.deleteOne();
|
||||
if (!webhook) {
|
||||
throw ResourceNotFoundError({ message: "Webhook not found!!" });
|
||||
}
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_WEBHOOK,
|
||||
metadata: {
|
||||
webhookId: webhook._id.toString(),
|
||||
environment: webhook.environment,
|
||||
secretPath: webhook.secretPath,
|
||||
webhookUrl: webhook.url,
|
||||
isDisabled: webhook.isDisabled
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: webhook.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
message: "successfully removed webhook"
|
||||
|
||||
Reference in New Issue
Block a user