2024-09-30 17:11:01 +00:00
|
|
|
import {BasicRole, NonGuestRole} from 'app/common/roles';
|
|
|
|
import {StringUnion} from 'app/common/StringUnion';
|
|
|
|
|
2024-09-09 20:04:21 +00:00
|
|
|
export interface AuditEvent<Name extends AuditEventName> {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
|
|
|
* The event.
|
|
|
|
*/
|
2024-09-09 20:04:21 +00:00
|
|
|
event: {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
|
|
|
* The name of the event.
|
|
|
|
*/
|
2024-09-09 20:04:21 +00:00
|
|
|
name: Name;
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
|
|
|
* The user that triggered the event.
|
|
|
|
*/
|
|
|
|
user: AuditEventUser;
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* Event-specific details (e.g. IDs of affected resources).
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
|
|
|
details: AuditEventDetails[Name] | {};
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The context that the event occurred in (e.g. workspace, document).
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
|
|
|
context: AuditEventContext;
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* Information about the source of the event (e.g. IP address).
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
|
|
|
source: AuditEventSource;
|
2024-09-09 20:04:21 +00:00
|
|
|
};
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* ISO 8601 timestamp (e.g. `2024-09-04T14:54:50Z`) of when the event occurred.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-09 20:04:21 +00:00
|
|
|
timestamp: string;
|
|
|
|
}
|
|
|
|
|
2024-09-30 17:11:01 +00:00
|
|
|
export const SiteAuditEventName = StringUnion(
|
|
|
|
'createDocument',
|
|
|
|
'sendToGoogleDrive',
|
|
|
|
'renameDocument',
|
|
|
|
'pinDocument',
|
|
|
|
'unpinDocument',
|
|
|
|
'moveDocument',
|
|
|
|
'removeDocument',
|
|
|
|
'deleteDocument',
|
|
|
|
'restoreDocumentFromTrash',
|
|
|
|
'changeDocumentAccess',
|
|
|
|
'openDocument',
|
|
|
|
'duplicateDocument',
|
|
|
|
'forkDocument',
|
|
|
|
'replaceDocument',
|
|
|
|
'reloadDocument',
|
|
|
|
'truncateDocumentHistory',
|
|
|
|
'deliverWebhookEvents',
|
|
|
|
'clearWebhookQueue',
|
|
|
|
'clearAllWebhookQueues',
|
|
|
|
'runSQLQuery',
|
|
|
|
'createWorkspace',
|
|
|
|
'renameWorkspace',
|
|
|
|
'removeWorkspace',
|
|
|
|
'deleteWorkspace',
|
|
|
|
'restoreWorkspaceFromTrash',
|
|
|
|
'changeWorkspaceAccess',
|
|
|
|
'renameSite',
|
|
|
|
'changeSiteAccess',
|
|
|
|
);
|
|
|
|
|
|
|
|
export type SiteAuditEventName = typeof SiteAuditEventName.type;
|
|
|
|
|
|
|
|
export const AuditEventName = StringUnion(
|
|
|
|
...SiteAuditEventName.values,
|
|
|
|
'createSite',
|
|
|
|
'deleteSite',
|
|
|
|
'changeUserName',
|
|
|
|
'createUserAPIKey',
|
|
|
|
'deleteUserAPIKey',
|
|
|
|
'deleteUser',
|
|
|
|
);
|
|
|
|
|
|
|
|
export type AuditEventName = typeof AuditEventName.type;
|
2024-09-23 15:04:22 +00:00
|
|
|
|
|
|
|
export type AuditEventUser =
|
|
|
|
| User
|
|
|
|
| Anonymous
|
2024-09-30 17:11:01 +00:00
|
|
|
| System
|
2024-09-23 15:04:22 +00:00
|
|
|
| Unknown;
|
|
|
|
|
|
|
|
interface User {
|
|
|
|
type: 'user';
|
|
|
|
id: number;
|
|
|
|
email: string;
|
|
|
|
name: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Anonymous {
|
|
|
|
type: 'anonymous';
|
|
|
|
}
|
|
|
|
|
2024-09-30 17:11:01 +00:00
|
|
|
interface System {
|
|
|
|
type: 'system';
|
|
|
|
}
|
|
|
|
|
2024-09-23 15:04:22 +00:00
|
|
|
interface Unknown {
|
|
|
|
type: 'unknown';
|
2024-09-09 20:04:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface AuditEventDetails {
|
|
|
|
createDocument: {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name?: string;
|
|
|
|
};
|
2024-09-30 17:11:01 +00:00
|
|
|
sendToGoogleDrive: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
};
|
|
|
|
renameDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The previous name of the document.
|
|
|
|
*/
|
|
|
|
previousName: string;
|
|
|
|
/**
|
|
|
|
* The current name of the document.
|
|
|
|
*/
|
|
|
|
currentName: string;
|
|
|
|
};
|
|
|
|
pinDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
unpinDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
2024-09-23 15:04:22 +00:00
|
|
|
moveDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The workspace the document was moved from.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
previousWorkspace: {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The ID of the workspace.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
2024-09-23 15:04:22 +00:00
|
|
|
};
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The workspace the document was moved to.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
newWorkspace: {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The ID of the workspace.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
2024-09-23 15:04:22 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
removeDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
deleteDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
2024-09-09 20:04:21 +00:00
|
|
|
id: string;
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
restoreDocumentFromTrash: {
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
/**
|
|
|
|
* The workspace of the document.
|
|
|
|
*/
|
|
|
|
workspace: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
changeDocumentAccess: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The access level of the document.
|
|
|
|
*/
|
|
|
|
access: {
|
|
|
|
/**
|
|
|
|
* The max inherited role.
|
|
|
|
*/
|
|
|
|
maxInheritedRole?: BasicRole | null;
|
|
|
|
/**
|
|
|
|
* The access level by user ID.
|
|
|
|
*/
|
|
|
|
users?: Record<string, NonGuestRole | null>;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
openDocument: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
/**
|
|
|
|
* The URL ID of the document.
|
|
|
|
*/
|
|
|
|
urlId: string;
|
|
|
|
/**
|
|
|
|
* The ID of the fork, if the document is a fork.
|
|
|
|
*/
|
|
|
|
forkId?: string;
|
|
|
|
/**
|
|
|
|
* The ID of the snapshot, if the document is a snapshot.
|
|
|
|
*/
|
|
|
|
snapshotId?: string;
|
|
|
|
};
|
|
|
|
duplicateDocument: {
|
|
|
|
/**
|
|
|
|
* The document that was duplicated.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
original: {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
2024-09-30 17:11:01 +00:00
|
|
|
/**
|
|
|
|
* The workspace of the document.
|
|
|
|
*/
|
|
|
|
workspace: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
2024-09-23 15:04:22 +00:00
|
|
|
};
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The newly-duplicated document.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
duplicate: {
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The ID of the document.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
id: string;
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The name of the document.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
2024-09-30 17:11:01 +00:00
|
|
|
/**
|
|
|
|
* If the document was duplicated without any data from the original document.
|
|
|
|
*/
|
|
|
|
asTemplate: boolean;
|
2024-09-23 15:04:22 +00:00
|
|
|
};
|
2024-09-30 17:11:01 +00:00
|
|
|
forkDocument: {
|
|
|
|
/**
|
|
|
|
* The document that was forked.
|
|
|
|
*/
|
|
|
|
original: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The name of the document.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* The newly-forked document.
|
|
|
|
*/
|
|
|
|
fork: {
|
|
|
|
/**
|
|
|
|
* The ID of the fork.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The ID of the fork with the trunk ID.
|
|
|
|
*/
|
|
|
|
documentId: string;
|
|
|
|
/**
|
|
|
|
* The ID of the fork with the trunk URL ID.
|
|
|
|
*/
|
|
|
|
urlId: string;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
replaceDocument: {
|
|
|
|
/**
|
|
|
|
* The document that was replaced.
|
|
|
|
*/
|
|
|
|
previous: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* The newly-replaced document.
|
|
|
|
*/
|
|
|
|
current: {
|
|
|
|
/**
|
|
|
|
* The ID of the document.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The ID of the snapshot, if the document was replaced with one.
|
|
|
|
*/
|
|
|
|
snapshotId?: string;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
reloadDocument: {},
|
|
|
|
truncateDocumentHistory: {
|
|
|
|
/**
|
|
|
|
* The number of history items kept.
|
|
|
|
*/
|
|
|
|
keep: number;
|
|
|
|
},
|
|
|
|
deliverWebhookEvents: {
|
|
|
|
/**
|
|
|
|
* The ID of the webhook.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
/**
|
|
|
|
* The host the webhook events were delivered to.
|
|
|
|
*/
|
|
|
|
host: string;
|
|
|
|
/**
|
|
|
|
* The number of webhook events delivered.
|
|
|
|
*/
|
|
|
|
quantity: number;
|
|
|
|
},
|
|
|
|
clearWebhookQueue: {
|
|
|
|
/**
|
|
|
|
* The ID of the webhook.
|
|
|
|
*/
|
|
|
|
id: string;
|
|
|
|
},
|
|
|
|
clearAllWebhookQueues: {},
|
2024-09-23 15:04:22 +00:00
|
|
|
runSQLQuery: {
|
|
|
|
/**
|
|
|
|
* The SQL query.
|
|
|
|
*/
|
|
|
|
query: string;
|
|
|
|
/**
|
|
|
|
* The arguments used for query parameters, if any.
|
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
arguments?: Array<string | number>;
|
|
|
|
/**
|
|
|
|
* The query execution timeout duration in milliseconds.
|
|
|
|
*/
|
|
|
|
timeoutMs?: number;
|
|
|
|
};
|
|
|
|
createWorkspace: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
renameWorkspace: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The previous name of the workspace.
|
|
|
|
*/
|
|
|
|
previousName: string;
|
|
|
|
/**
|
|
|
|
* The current name of the workspace.
|
|
|
|
*/
|
|
|
|
currentName: string;
|
|
|
|
};
|
|
|
|
removeWorkspace: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
deleteWorkspace: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
restoreWorkspaceFromTrash: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the workspace.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
changeWorkspaceAccess: {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The access level of the workspace.
|
|
|
|
*/
|
|
|
|
access: {
|
|
|
|
/**
|
|
|
|
* The max inherited role.
|
|
|
|
*/
|
|
|
|
maxInheritedRole?: BasicRole | null;
|
|
|
|
/**
|
|
|
|
* The access level by user ID.
|
|
|
|
*/
|
|
|
|
users?: Record<string, NonGuestRole | null>;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
createSite: {
|
|
|
|
/**
|
|
|
|
* The ID of the site.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the site.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
/**
|
|
|
|
* The domain of the site.
|
|
|
|
*/
|
|
|
|
domain: string;
|
|
|
|
};
|
|
|
|
renameSite: {
|
|
|
|
/**
|
|
|
|
* The ID of the site.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The previous name and domain of the site.
|
|
|
|
*/
|
|
|
|
previous: {
|
|
|
|
/**
|
|
|
|
* The name of the site.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
/**
|
|
|
|
* The domain of the site.
|
|
|
|
*/
|
|
|
|
domain: string;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* The current name and domain of the site.
|
|
|
|
*/
|
|
|
|
current: {
|
|
|
|
/**
|
|
|
|
* The name of the site.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
/**
|
|
|
|
* The domain of the site.
|
|
|
|
*/
|
|
|
|
domain: string;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
deleteSite: {
|
|
|
|
/**
|
|
|
|
* The ID of the site.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The name of the site.
|
|
|
|
*/
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
changeSiteAccess: {
|
|
|
|
/**
|
|
|
|
* The ID of the site.
|
|
|
|
*/
|
|
|
|
id: number;
|
|
|
|
/**
|
|
|
|
* The access level of the site.
|
|
|
|
*/
|
|
|
|
access: {
|
|
|
|
/**
|
|
|
|
* The access level by user ID.
|
|
|
|
*/
|
|
|
|
users?: Record<string, NonGuestRole | null>;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
changeUserName: {
|
|
|
|
/**
|
|
|
|
* The previous name of the user.
|
|
|
|
*/
|
|
|
|
previousName: string;
|
2024-09-23 15:04:22 +00:00
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The current name of the user.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
2024-09-30 17:11:01 +00:00
|
|
|
currentName: string;
|
2024-09-09 20:04:21 +00:00
|
|
|
};
|
2024-09-30 17:11:01 +00:00
|
|
|
createUserAPIKey: {};
|
|
|
|
deleteUserAPIKey: {};
|
|
|
|
deleteUser: {};
|
2024-09-09 20:04:21 +00:00
|
|
|
}
|
2024-09-23 15:04:22 +00:00
|
|
|
|
|
|
|
export interface AuditEventContext {
|
|
|
|
/**
|
|
|
|
* The ID of the workspace the event occurred in.
|
|
|
|
*/
|
|
|
|
workspaceId?: number;
|
|
|
|
/**
|
|
|
|
* The ID of the document the event occurred in.
|
|
|
|
*/
|
|
|
|
documentId?: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface AuditEventSource {
|
|
|
|
/**
|
2024-09-30 17:11:01 +00:00
|
|
|
* The domain of the site tied to the originating request.
|
2024-09-23 15:04:22 +00:00
|
|
|
*/
|
|
|
|
org?: string;
|
|
|
|
/**
|
|
|
|
* The IP address of the originating request.
|
|
|
|
*/
|
|
|
|
ipAddress?: string;
|
|
|
|
/**
|
|
|
|
* The User-Agent HTTP header of the originating request.
|
|
|
|
*/
|
|
|
|
userAgent?: string;
|
|
|
|
/**
|
|
|
|
* The ID of the session tied to the originating request.
|
|
|
|
*/
|
|
|
|
sessionId?: string;
|
|
|
|
}
|