Updating events to include a proper friendly map of audited events.

This commit is contained in:
mike12345567 2023-02-15 19:44:32 +00:00
parent 6d83ea9bec
commit 2afd3e1580
14 changed files with 187 additions and 16 deletions

View File

@ -19,6 +19,7 @@ const created = async (app: App, timestamp?: string | number) => {
const properties: AppCreatedEvent = {
appId: app.appId,
version: app.version,
name: app.name,
}
await publishEvent(Event.APP_CREATED, properties, timestamp)
}
@ -27,6 +28,7 @@ async function updated(app: App) {
const properties: AppUpdatedEvent = {
appId: app.appId,
version: app.version,
name: app.name,
}
await publishEvent(Event.APP_UPDATED, properties)
}
@ -34,6 +36,7 @@ async function updated(app: App) {
async function deleted(app: App) {
const properties: AppDeletedEvent = {
appId: app.appId,
name: app.name,
}
await publishEvent(Event.APP_DELETED, properties)
}
@ -41,6 +44,7 @@ async function deleted(app: App) {
async function published(app: App, timestamp?: string | number) {
const properties: AppPublishedEvent = {
appId: app.appId,
name: app.name,
}
await publishEvent(Event.APP_PUBLISHED, properties, timestamp)
}
@ -48,6 +52,7 @@ async function published(app: App, timestamp?: string | number) {
async function unpublished(app: App) {
const properties: AppUnpublishedEvent = {
appId: app.appId,
name: app.name,
}
await publishEvent(Event.APP_UNPUBLISHED, properties)
}
@ -55,6 +60,7 @@ async function unpublished(app: App) {
async function fileImported(app: App) {
const properties: AppFileImportedEvent = {
appId: app.appId,
name: app.name,
}
await publishEvent(Event.APP_FILE_IMPORTED, properties)
}
@ -63,6 +69,7 @@ async function templateImported(app: App, templateKey: string) {
const properties: AppTemplateImportedEvent = {
appId: app.appId,
templateKey,
name: app.name,
}
await publishEvent(Event.APP_TEMPLATE_IMPORTED, properties)
}
@ -76,6 +83,7 @@ async function versionUpdated(
appId: app.appId,
currentVersion,
updatedToVersion,
name: app.name,
}
await publishEvent(Event.APP_VERSION_UPDATED, properties)
}
@ -89,6 +97,7 @@ async function versionReverted(
appId: app.appId,
currentVersion,
revertedToVersion,
name: app.name,
}
await publishEvent(Event.APP_VERSION_REVERTED, properties)
}
@ -96,6 +105,7 @@ async function versionReverted(
async function reverted(app: App) {
const properties: AppRevertedEvent = {
appId: app.appId,
name: app.name,
}
await publishEvent(Event.APP_REVERTED, properties)
}
@ -103,6 +113,7 @@ async function reverted(app: App) {
async function exported(app: App) {
const properties: AppExportedEvent = {
appId: app.appId,
name: app.name,
}
await publishEvent(Event.APP_EXPORTED, properties)
}

View File

@ -12,19 +12,21 @@ import {
} from "@budibase/types"
import { identification } from ".."
async function login(source: LoginSource) {
async function login(source: LoginSource, email: string) {
const identity = await identification.getCurrentIdentity()
const properties: LoginEvent = {
userId: identity.id,
source,
email,
}
await publishEvent(Event.AUTH_LOGIN, properties)
}
async function logout() {
async function logout(email: string) {
const identity = await identification.getCurrentIdentity()
const properties: LogoutEvent = {
userId: identity.id,
email,
}
await publishEvent(Event.AUTH_LOGOUT, properties)
}

View File

@ -13,6 +13,7 @@ async function appBackupRestored(backup: AppBackup) {
appId: backup.appId,
restoreId: backup._id!,
backupCreatedAt: backup.timestamp,
name: backup.name as string,
}
await publishEvent(Event.APP_BACKUP_RESTORED, properties)
@ -22,13 +23,15 @@ async function appBackupTriggered(
appId: string,
backupId: string,
type: AppBackupType,
trigger: AppBackupTrigger
trigger: AppBackupTrigger,
name: string
) {
const properties: AppBackupTriggeredEvent = {
appId: appId,
backupId,
type,
trigger,
name,
}
await publishEvent(Event.APP_BACKUP_TRIGGERED, properties)
}

View File

@ -8,12 +8,14 @@ import {
GroupUsersAddedEvent,
GroupUsersDeletedEvent,
GroupAddedOnboardingEvent,
GroupPermissionsEditedEvent,
UserGroupRoles,
} from "@budibase/types"
async function created(group: UserGroup, timestamp?: number) {
const properties: GroupCreatedEvent = {
groupId: group._id as string,
name: group.name,
}
await publishEvent(Event.USER_GROUP_CREATED, properties, timestamp)
}
@ -21,6 +23,7 @@ async function created(group: UserGroup, timestamp?: number) {
async function updated(group: UserGroup) {
const properties: GroupUpdatedEvent = {
groupId: group._id as string,
name: group.name,
}
await publishEvent(Event.USER_GROUP_UPDATED, properties)
}
@ -28,6 +31,7 @@ async function updated(group: UserGroup) {
async function deleted(group: UserGroup) {
const properties: GroupDeletedEvent = {
groupId: group._id as string,
name: group.name,
}
await publishEvent(Event.USER_GROUP_DELETED, properties)
}
@ -36,6 +40,7 @@ async function usersAdded(count: number, group: UserGroup) {
const properties: GroupUsersAddedEvent = {
count,
groupId: group._id as string,
name: group.name,
}
await publishEvent(Event.USER_GROUP_USERS_ADDED, properties)
}
@ -44,6 +49,7 @@ async function usersDeleted(count: number, group: UserGroup) {
const properties: GroupUsersDeletedEvent = {
count,
groupId: group._id as string,
name: group.name,
}
await publishEvent(Event.USER_GROUP_USERS_REMOVED, properties)
}
@ -56,9 +62,11 @@ async function createdOnboarding(groupId: string) {
await publishEvent(Event.USER_GROUP_ONBOARDING, properties)
}
async function permissionsEdited(roles: UserGroupRoles) {
const properties: UserGroupRoles = {
...roles,
async function permissionsEdited(group: UserGroup) {
const properties: GroupPermissionsEditedEvent = {
permissions: group.roles!,
name: group.name,
groupId: group._id as string,
}
await publishEvent(Event.USER_GROUP_PERMISSIONS_EDITED, properties)
}

View File

@ -19,6 +19,7 @@ import {
async function created(user: User, timestamp?: number) {
const properties: UserCreatedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_CREATED, properties, timestamp)
}
@ -26,6 +27,7 @@ async function created(user: User, timestamp?: number) {
async function updated(user: User) {
const properties: UserUpdatedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_UPDATED, properties)
}
@ -33,6 +35,7 @@ async function updated(user: User) {
async function deleted(user: User) {
const properties: UserDeletedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_DELETED, properties)
}
@ -40,6 +43,7 @@ async function deleted(user: User) {
export async function onboardingComplete(user: User) {
const properties: UserOnboardingEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_ONBOARDING_COMPLETE, properties)
}
@ -49,6 +53,7 @@ export async function onboardingComplete(user: User) {
async function permissionAdminAssigned(user: User, timestamp?: number) {
const properties: UserPermissionAssignedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(
Event.USER_PERMISSION_ADMIN_ASSIGNED,
@ -60,6 +65,7 @@ async function permissionAdminAssigned(user: User, timestamp?: number) {
async function permissionAdminRemoved(user: User) {
const properties: UserPermissionRemovedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties)
}
@ -67,6 +73,7 @@ async function permissionAdminRemoved(user: User) {
async function permissionBuilderAssigned(user: User, timestamp?: number) {
const properties: UserPermissionAssignedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(
Event.USER_PERMISSION_BUILDER_ASSIGNED,
@ -78,20 +85,22 @@ async function permissionBuilderAssigned(user: User, timestamp?: number) {
async function permissionBuilderRemoved(user: User) {
const properties: UserPermissionRemovedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_PERMISSION_BUILDER_REMOVED, properties)
}
// INVITE
async function invited() {
const properties: UserInvitedEvent = {}
async function invited(email: string) {
const properties: UserInvitedEvent = { email }
await publishEvent(Event.USER_INVITED, properties)
}
async function inviteAccepted(user: User) {
const properties: UserInviteAcceptedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_INVITED_ACCEPTED, properties)
}
@ -101,6 +110,7 @@ async function inviteAccepted(user: User) {
async function passwordForceReset(user: User) {
const properties: UserPasswordForceResetEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_PASSWORD_FORCE_RESET, properties)
}
@ -108,6 +118,7 @@ async function passwordForceReset(user: User) {
async function passwordUpdated(user: User) {
const properties: UserPasswordUpdatedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_PASSWORD_UPDATED, properties)
}
@ -115,6 +126,7 @@ async function passwordUpdated(user: User) {
async function passwordResetRequested(user: User) {
const properties: UserPasswordResetRequestedEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_PASSWORD_RESET_REQUESTED, properties)
}
@ -122,6 +134,7 @@ async function passwordResetRequested(user: User) {
async function passwordReset(user: User) {
const properties: UserPasswordResetEvent = {
userId: user._id as string,
email: user.email,
}
await publishEvent(Event.USER_PASSWORD_RESET, properties)
}

View File

@ -227,6 +227,7 @@ export async function getBuildersCount() {
*/
export async function platformLogout(opts: PlatformLogoutOpts) {
const ctx = opts.ctx
const email = ctx.user?.email!
const userId = opts.userId
const keepActiveSession = opts.keepActiveSession
@ -247,7 +248,7 @@ export async function platformLogout(opts: PlatformLogoutOpts) {
const sessionIds = sessions.map(({ sessionId }) => sessionId)
await invalidateSessions(userId, { sessionIds, reason: "logout" })
await events.auth.logout()
await events.auth.logout(email)
await userCache.invalidateUser(userId)
}

View File

@ -3,50 +3,61 @@ import { BaseEvent } from "./event"
export interface AppCreatedEvent extends BaseEvent {
appId: string
version: string
name: string
}
export interface AppUpdatedEvent extends BaseEvent {
appId: string
version: string
name: string
}
export interface AppDeletedEvent extends BaseEvent {
appId: string
name: string
}
export interface AppPublishedEvent extends BaseEvent {
appId: string
name: string
}
export interface AppUnpublishedEvent extends BaseEvent {
appId: string
name: string
}
export interface AppFileImportedEvent extends BaseEvent {
appId: string
name: string
}
export interface AppTemplateImportedEvent extends BaseEvent {
appId: string
templateKey: string
name: string
}
export interface AppVersionUpdatedEvent extends BaseEvent {
appId: string
currentVersion: string
updatedToVersion: string
name: string
}
export interface AppVersionRevertedEvent extends BaseEvent {
appId: string
currentVersion: string
revertedToVersion: string
name: string
}
export interface AppRevertedEvent extends BaseEvent {
appId: string
name: string
}
export interface AppExportedEvent extends BaseEvent {
appId: string
name: string
}

View File

@ -7,10 +7,12 @@ export type SSOType = ConfigType.OIDC | ConfigType.GOOGLE
export interface LoginEvent extends BaseEvent {
userId: string
source: LoginSource
email: string
}
export interface LogoutEvent extends BaseEvent {
userId: string
email: string
}
export interface SSOCreatedEvent extends BaseEvent {

View File

@ -5,6 +5,7 @@ export interface AppBackupRestoreEvent extends BaseEvent {
appId: string
restoreId: string
backupCreatedAt: string
name: string
}
export interface AppBackupTriggeredEvent extends BaseEvent {
@ -12,4 +13,5 @@ export interface AppBackupTriggeredEvent extends BaseEvent {
appId: string
trigger: AppBackupTrigger
type: AppBackupType
name: string
}

View File

@ -182,8 +182,102 @@ export enum Event {
ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED = "environment_variable:upgrade_panel_opened",
}
export const AuditedEventFriendlyName = {
[Event.USER_CREATED]: "user created",
export class AuditedEventFriendlyName {
// USER
static USER_CREATED = "User {{ email }} created"
static USER_UPDATED = "User {{ email }} updated"
static USER_DELETED = "User {{ email }} deleted"
static USER_PERMISSION_ADMIN_ASSIGNED = "User {{ email }} admin role assigned"
static USER_PERMISSION_ADMIN_REMOVED = "User {{ email }} admin role removed"
static USER_PERMISSION_BUILDER_ASSIGNED =
"User {{ email }} builder role assigned"
static USER_PERMISSION_BUILDER_REMOVED =
"User {{ email }} builder role removed"
static USER_INVITED = "User {{ email }} invited"
static USER_INVITED_ACCEPTED = "User {{ email }} accepted invite"
static USER_PASSWORD_UPDATED = "User {{ email }} password updated"
static USER_PASSWORD_RESET_REQUESTED =
"User {{ email }} password reset requested"
static USER_PASSWORD_RESET = "User {{ email }} password reset"
static USER_GROUP_CREATED = "User group {{ name }} created"
static USER_GROUP_UPDATED = "User group {{ name }} updated"
static USER_GROUP_DELETED = "User group {{ name }} deleted"
static USER_GROUP_USERS_ADDED =
"User group {{ name }} {{ count }} users added"
static USER_GROUP_USERS_REMOVED =
"User group {{ name }} {{ count }} users removed"
static USER_GROUP_PERMISSIONS_EDITED =
"User group {{ name }} permissions edited"
// EMAIL
static EMAIL_SMTP_CREATED = "Email configuration created"
static EMAIL_SMTP_UPDATED = "Email configuration updated"
// AUTH
static AUTH_SSO_CREATED = "SSO configuration created"
static AUTH_SSO_UPDATED = "SSO configuration updated"
static AUTH_SSO_ACTIVATED = "SSO configuration activated"
static AUTH_SSO_DEACTIVATED = "SSO configuration deactivated"
static AUTH_LOGIN = "User {{ email }} logged in"
static AUTH_LOGOUT = "User {{ email }} logged out"
// ORG
static ORG_NAME_UPDATED = "Organisation name updated"
static ORG_LOGO_UPDATED = "Organisation logo updated"
static ORG_PLATFORM_URL_UPDATED = "Organisation platform URL updated"
// APP
static APP_CREATED = "App {{ name }} created"
static APP_UPDATED = "App {{ name }} updated"
static APP_DELETED = "App {{ name }} deleted"
static APP_PUBLISHED = "App {{ name }} published"
static APP_UNPUBLISHED = "App {{ name }} unpublished"
static APP_TEMPLATE_IMPORTED = "App {{ name }} template imported"
static APP_FILE_IMPORTED = "App {{ name }} file imported"
static APP_VERSION_UPDATED = "App {{ name }} version updated"
static APP_VERSION_REVERTED = "App {{ name }} version reverted"
static APP_REVERTED = "App {{ name }} reverted"
static APP_EXPORTED = "App {{ name }} exported"
static APP_BACKUP_RESTORED = "App backup {{ name }} restored"
static APP_BACKUP_TRIGGERED = "App backup {{ name }} triggered"
// DATASOURCE
static DATASOURCE_CREATED = "Datasource created"
static DATASOURCE_UPDATED = "Datasource updated"
static DATASOURCE_DELETED = "Datasource deleted"
// QUERY
static QUERY_CREATED = "Query created"
static QUERY_UPDATED = "Query updated"
static QUERY_DELETED = "Query deleted"
static QUERY_IMPORT = "Query import"
// TABLE
static TABLE_CREATED = "Table created"
static TABLE_UPDATED = "Table updated"
static TABLE_DELETED = "Table deleted"
static TABLE_EXPORTED = "Table exported"
static TABLE_IMPORTED = "Table imported"
static TABLE_DATA_IMPORTED = "Data imported to table"
// ROWS
static ROWS_CREATED = "Rows created"
static ROWS_IMPORTED = "Rows imported"
// AUTOMATION
static AUTOMATION_CREATED = "Automation created"
static AUTOMATION_DELETED = "Automation deleted"
// SCREEN
static SCREEN_CREATED = "Screen created"
static SCREEN_DELETED = "Screen deleted"
// COMPONENT
static COMPONENT_CREATED = "Component created"
static COMPONENT_DELETED = "Component deleted"
static ENVIRONMENT_VARIABLE_CREATED = "Environment variable created"
static ENVIRONMENT_VARIABLE_DELETED = "Environment variable deleted"
}
// properties added at the final stage of the event pipeline

View File

@ -2,47 +2,60 @@ import { BaseEvent } from "./event"
export interface UserCreatedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserUpdatedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserDeletedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserOnboardingEvent extends BaseEvent {
userId: string
step?: string
email: string
}
export interface UserPermissionAssignedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserPermissionRemovedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserInvitedEvent extends BaseEvent {}
export interface UserInvitedEvent extends BaseEvent {
email: string
}
export interface UserInviteAcceptedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserPasswordForceResetEvent extends BaseEvent {
userId: string
email: string
}
export interface UserPasswordUpdatedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserPasswordResetRequestedEvent extends BaseEvent {
userId: string
email: string
}
export interface UserPasswordResetEvent extends BaseEvent {
userId: string
email: string
}

View File

@ -2,27 +2,38 @@ import { BaseEvent } from "./event"
export interface GroupCreatedEvent extends BaseEvent {
groupId: string
name: string
}
export interface GroupUpdatedEvent extends BaseEvent {
groupId: string
name: string
}
export interface GroupDeletedEvent extends BaseEvent {
groupId: string
name: string
}
export interface GroupUsersAddedEvent extends BaseEvent {
count: number
groupId: string
name: string
}
export interface GroupUsersDeletedEvent extends BaseEvent {
count: number
groupId: string
name: string
}
export interface GroupAddedOnboardingEvent extends BaseEvent {
groupId: string
onboarding: boolean
}
export interface GroupPermissionsEditedEvent extends BaseEvent {
permissions: Record<string, string>
name: string
groupId: string
}

View File

@ -54,7 +54,7 @@ export const authenticate = async (ctx: any, next: any) => {
async (err: any, user: User, info: any) => {
await authInternal(ctx, user, err, info)
await context.identity.doInUserContext(user, async () => {
await events.auth.login("local")
await events.auth.login("local", user.email)
})
ctx.status = 200
}
@ -208,7 +208,7 @@ export const googleAuth = async (ctx: any, next: any) => {
async (err: any, user: User, info: any) => {
await authInternal(ctx, user, err, info)
await context.identity.doInUserContext(user, async () => {
await events.auth.login("google-internal")
await events.auth.login("google-internal", user.email)
})
ctx.redirect("/")
}
@ -272,7 +272,7 @@ export const oidcAuth = async (ctx: any, next: any) => {
async (err: any, user: any, info: any) => {
await authInternal(ctx, user, err, info)
await context.identity.doInUserContext(user, async () => {
await events.auth.login("oidc")
await events.auth.login("oidc", user.email)
})
ctx.redirect("/")
}

View File

@ -623,7 +623,7 @@ export const invite = async (
}
await sendEmail(user.email, EmailTemplatePurpose.INVITATION, opts)
response.successful.push({ email: user.email })
await events.user.invited()
await events.user.invited(user.email)
} catch (e) {
console.error(`Failed to send email invitation email=${user.email}`, e)
response.unsuccessful.push({