-
{t("activity:event." + currentEvent)}
-
toggleSidebar([])}>
-
+ useEffect(() => {
+ const getLogData = async () => {
+ setIsLoading(true);
+ const tempActionData = await getActionData({ actionId: currentAction });
+ const latestKey = await getLatestFileKey({ workspaceId: String(router.query.id) })
+ const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY');
+
+ // #TODO: make this a separate function and reuse across the app
+ let decryptedLatestKey: string;
+ if (latestKey) {
+ // assymmetrically decrypt symmetric key with local private key
+ decryptedLatestKey = decryptAssymmetric({
+ ciphertext: latestKey.latestKey.encryptedKey,
+ nonce: latestKey.latestKey.nonce,
+ publicKey: latestKey.latestKey.sender.publicKey,
+ privateKey: String(PRIVATE_KEY)
+ });
+ }
+
+ const decryptedSecretVersions = tempActionData.payload.secretVersions.map((encryptedSecretVersion: {
+ newSecretVersion?: SecretProps;
+ oldSecretVersion?: SecretProps;
+ }) => {
+ return {
+ newSecretVersion: {
+ key: decryptSymmetric({
+ ciphertext: encryptedSecretVersion.newSecretVersion!.secretKeyCiphertext,
+ iv: encryptedSecretVersion.newSecretVersion!.secretKeyIV,
+ tag: encryptedSecretVersion.newSecretVersion!.secretKeyTag,
+ key: decryptedLatestKey
+ }),
+ value: decryptSymmetric({
+ ciphertext: encryptedSecretVersion.newSecretVersion!.secretValueCiphertext,
+ iv: encryptedSecretVersion.newSecretVersion!.secretValueIV,
+ tag: encryptedSecretVersion.newSecretVersion!.secretValueTag,
+ key: decryptedLatestKey
+ })
+ },
+ oldSecretVersion: {
+ key: encryptedSecretVersion.oldSecretVersion?.secretKeyCiphertext
+ ? decryptSymmetric({
+ ciphertext: encryptedSecretVersion.oldSecretVersion?.secretKeyCiphertext,
+ iv: encryptedSecretVersion.oldSecretVersion?.secretKeyIV,
+ tag: encryptedSecretVersion.oldSecretVersion?.secretKeyTag,
+ key: decryptedLatestKey
+ }): undefined,
+ value: encryptedSecretVersion.oldSecretVersion?.secretValueCiphertext
+ ? decryptSymmetric({
+ ciphertext: encryptedSecretVersion.oldSecretVersion?.secretValueCiphertext,
+ iv: encryptedSecretVersion.oldSecretVersion?.secretValueIV,
+ tag: encryptedSecretVersion.oldSecretVersion?.secretValueTag,
+ key: decryptedLatestKey
+ }): undefined
+ }
+ }
+ })
+
+ setActionData(decryptedSecretVersions);
+ setActionMetaData({name: tempActionData.name});
+ setIsLoading(false);
+ }
+ getLogData();
+ }, [currentAction]);
+
+ return
+ {isLoading ? (
+
+
+
+ ) : (
+
+
+
{t("activity:event." + actionMetaData?.name)}
+
toggleSidebar("")}>
+
+
+
+
+ {(actionMetaData?.name == 'readSecrets'
+ || actionMetaData?.name == 'addSecrets'
+ || actionMetaData?.name == 'deleteSecrets') && actionData?.map((item, id) =>
+
+
{item.newSecretVersion.key}
+
{}}
+ type="value"
+ position={1}
+ value={item.newSecretVersion.value}
+ isDuplicate={false}
+ blurred={false}
+ />
+
+ )}
+ {actionMetaData?.name == 'updateSecrets' && actionData?.map((item, id) =>
+ <>
+
{item.newSecretVersion.key}
+
+
- {patienceDiff(item.oldSecretVersion.value.split(''), item.newSecretVersion.value.split(''), false).lines.map((character, id) => character.bIndex != -1 && {character.line})}
+
+ {patienceDiff(item.oldSecretVersion.value.split(''), item.newSecretVersion.value.split(''), false).lines.map((character, id) => character.aIndex != -1 && {character.line})}
+
+ >
+ )}
-
- {currentEvent == 'readSecrets' && sidebarData.map((item, id) =>
- <>
-
Key {id}
-
{}}
- type="varName"
- position={1}
- value={"a" + item}
- isDuplicate={false}
- blurred={false}
- />
- >
- )}
- {currentEvent == 'updateSecrets' && sidebarData.map((item, id) =>
- secretChanges.map(secretChange =>
- <>
- Secret Name {id}
-
-
- {patienceDiff(secretChange.oldSecret.split(''), secretChange.newSecret.split(''), false).lines.map((character, id) => character.aIndex != -1 && {character.line})}
-
+ {patienceDiff(secretChange.oldSecret.split(''), secretChange.newSecret.split('')).lines.map((character, id) => character.bIndex != -1 && {character.line})}
-
- >
- ))}
-
-
-
+ )}
};
diff --git a/frontend/ee/components/ActivityTable.tsx b/frontend/ee/components/ActivityTable.tsx
index a25920202..607b25c5d 100644
--- a/frontend/ee/components/ActivityTable.tsx
+++ b/frontend/ee/components/ActivityTable.tsx
@@ -4,8 +4,7 @@ import { useTranslation } from "next-i18next";
import {
faAngleDown,
faAngleRight,
- faUpRightFromSquare,
- faX
+ faUpRightFromSquare
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import timeSince from 'ee/utilities/timeSince';
@@ -14,6 +13,7 @@ import guidGenerator from '../../components/utilities/randomId';
interface PayloadProps {
+ _id: string;
name: string;
secretVersions: string[];
}
@@ -29,25 +29,26 @@ interface logData {
/**
- *
+ * This is a single row of the activity table
* @param obj
- * @param {function} obj.setCurrentEvent - specify the name of the event for which the sidebar is being opened
+ * @param {logData} obj.row - data for a certain event
+ * @param {function} obj.toggleSidebar - open and close sidebar that displays data for a specific event
* @returns
*/
-const ActivityLogsRow = ({ row, toggleSidebar, setCurrentEvent }: { row: logData, toggleSidebar: (value: string[]) => void; setCurrentEvent: (value: string) => void; }) => {
+const ActivityLogsRow = ({ row, toggleSidebar }: { row: logData, toggleSidebar: (value: string) => void; }) => {
const [payloadOpened, setPayloadOpened] = useState(false);
const { t } = useTranslation();
return (
<>
-
+
| setPayloadOpened(!payloadOpened)}
className="border-mineshaft-700 border-t text-gray-300 flex items-center cursor-pointer"
>
@@ -66,26 +67,23 @@ const ActivityLogsRow = ({ row, toggleSidebar, setCurrentEvent }: { row: logData
|
{payloadOpened &&
-
+
|
Timestamp |
{row.createdAt} |
}
{payloadOpened &&
row.payload?.map((action, index) =>
-
+
|
{t("activity:event." + action.name)} |
- {
- toggleSidebar(action.secretVersions);
- setCurrentEvent(action.name);
- }}>
+ | toggleSidebar(action._id)}>
{action.secretVersions.length + (action.secretVersions.length != 1 ? " secrets" : " secret")}
|
)}
{payloadOpened &&
-
+
|
IP Address |
{row.ipAddress} |
@@ -99,28 +97,27 @@ const ActivityLogsRow = ({ row, toggleSidebar, setCurrentEvent }: { row: logData
* @param {object} obj
* @param {logData} obj.data - data for user activity logs
* @param {function} obj.toggleSidebar - function that opens or closes the sidebar
- * @param {function} obj.setCurrentEvent - specify the name of the event for which the sidebar is being opened
* @returns
*/
-const ActivityTable = ({ data, toggleSidebar, setCurrentEvent }: { data: logData[], toggleSidebar: (value: string[]) => void; setCurrentEvent: (value: string) => void; }) => {
+const ActivityTable = ({ data, toggleSidebar }: { data: logData[], toggleSidebar: (value: string) => void; }) => {
return (
-
+
-
+
|
- Event |
- User |
- Source |
- Time |
+ EVENT |
+ USER |
+ SOURCE |
+ TIME |
|
{data?.map((row, index) => {
- return ;
+ return ;
})}
diff --git a/frontend/pages/activity/[id].tsx b/frontend/pages/activity/[id].tsx
index f384ae69f..974607d0a 100644
--- a/frontend/pages/activity/[id].tsx
+++ b/frontend/pages/activity/[id].tsx
@@ -21,6 +21,7 @@ interface logData {
email: string;
};
actions: {
+ _id: string;
name: string;
payload: {
secretVersions: string[];
@@ -29,6 +30,7 @@ interface logData {
}
interface PayloadProps {
+ _id: string;
name: string;
secretVersions: string[];
}
@@ -51,13 +53,38 @@ export default function Activity() {
const [logsData, setLogsData] = useState
([]);
const [currentOffset, setCurrentOffset] = useState(0);
const currentLimit = 10;
- const [sidebarData, toggleSidebar] = useState([])
- const [currentEvent, setCurrentEvent] = useState("");
+ const [currentSidebarAction, toggleSidebar] = useState()
const { t } = useTranslation();
+ // this use effect updates the data in case of a new filter being added
+ useEffect(() => {
+ setCurrentOffset(0);
+ const getLogData = async () => {
+ const tempLogsData = await getProjectLogs({ workspaceId: String(router.query.id), offset: 0, limit: currentLimit, userId: "", actionNames: eventChosen })
+ setLogsData(tempLogsData.map((log: logData) => {
+ return {
+ _id: log._id,
+ channel: log.channel,
+ createdAt: log.createdAt,
+ ipAddress: log.ipAddress,
+ user: log.user.email,
+ payload: log.actions.map(action => {
+ return {
+ _id: action._id,
+ name: action.name,
+ secretVersions: action.payload.secretVersions
+ }
+ })
+ }
+ }))
+ }
+ getLogData();
+ }, [eventChosen]);
+
+ // this use effect adds more data in case 'View More' button is clicked
useEffect(() => {
const getLogData = async () => {
- const tempLogsData = await getProjectLogs({ workspaceId: String(router.query.id), offset: currentOffset, limit: currentLimit, filters: {} })
+ const tempLogsData = await getProjectLogs({ workspaceId: String(router.query.id), offset: currentOffset, limit: currentLimit, userId: "", actionNames: eventChosen })
setLogsData(logsData.concat(tempLogsData.map((log: logData) => {
return {
_id: log._id,
@@ -67,6 +94,7 @@ export default function Activity() {
user: log.user.email,
payload: log.actions.map(action => {
return {
+ _id: action._id,
name: action.name,
secretVersions: action.payload.secretVersions
}
@@ -84,31 +112,24 @@ export default function Activity() {
return (
- {sidebarData.length > 0 &&
}
+ {currentSidebarAction &&
}
- Event history limited to the last 12 months.
+ Event history for this Infisical project.
b.createdAt.localeCompare(a.createdAt))
- .filter((log) =>
- eventChosen != '' ? log.payload?.map(action => t("activity:event." + action.name)).includes(eventChosen) : true
- )
- }
+ data={logsData}
toggleSidebar={toggleSidebar}
- setCurrentEvent={setCurrentEvent}
/>