diff --git a/packages/backend-core/src/events/publishers/scim.ts b/packages/backend-core/src/events/publishers/scim.ts index 992fd4a3e0..e35cc52730 100644 --- a/packages/backend-core/src/events/publishers/scim.ts +++ b/packages/backend-core/src/events/publishers/scim.ts @@ -1,5 +1,9 @@ import { publishEvent } from "../events" -import { Event, ScimUserCreatedEvent } from "@budibase/types" +import { + Event, + ScimUserCreatedEvent, + ScimUserUpdatedEvent, +} from "@budibase/types" async function SCIMUserCreated(props: { email: string @@ -11,6 +15,17 @@ async function SCIMUserCreated(props: { await publishEvent(Event.SCIM_USER_CREATED, properties, props.timestamp) } +async function SCIMUserUpdated(props: { + email: string + timestamp?: string | number +}) { + const properties: ScimUserUpdatedEvent = { + email: props.email, + } + await publishEvent(Event.SCIM_USER_UPDATED, properties, props.timestamp) +} + export default { SCIMUserCreated, + SCIMUserUpdated, } diff --git a/packages/backend-core/tests/utilities/mocks/events.ts b/packages/backend-core/tests/utilities/mocks/events.ts index dc901f3a2c..5626fd9a01 100644 --- a/packages/backend-core/tests/utilities/mocks/events.ts +++ b/packages/backend-core/tests/utilities/mocks/events.ts @@ -122,3 +122,4 @@ jest.spyOn(events.plugin, "imported") jest.spyOn(events.plugin, "deleted") jest.spyOn(events.scim, "SCIMUserCreated") +jest.spyOn(events.scim, "SCIMUserUpdated") diff --git a/packages/types/src/sdk/events/event.ts b/packages/types/src/sdk/events/event.ts index 0267847ac1..79361d2b18 100644 --- a/packages/types/src/sdk/events/event.ts +++ b/packages/types/src/sdk/events/event.ts @@ -187,6 +187,7 @@ export enum Event { // SCIM SCIM_USER_CREATED = "scim:user:created", + SCIM_USER_UPDATED = "scim:user:updated", } // all events that are not audited have been added to this record as undefined, this means @@ -370,6 +371,7 @@ export const AuditedEventFriendlyName: Record = { // SCIM [Event.SCIM_USER_CREATED]: `SCIM user "{{ email }}" created`, + [Event.SCIM_USER_UPDATED]: `SCIM user "{{ email }}" updated`, } // properties added at the final stage of the event pipeline diff --git a/packages/types/src/sdk/events/scim.ts b/packages/types/src/sdk/events/scim.ts index 00e38e34cd..e8e34f1e04 100644 --- a/packages/types/src/sdk/events/scim.ts +++ b/packages/types/src/sdk/events/scim.ts @@ -3,3 +3,7 @@ import { BaseEvent } from "./event" export interface ScimUserCreatedEvent extends BaseEvent { email: string } + +export interface ScimUserUpdatedEvent extends BaseEvent { + email: string +} diff --git a/packages/worker/src/api/routes/global/tests/scim/users.spec.ts b/packages/worker/src/api/routes/global/tests/scim/users.spec.ts index 733cd90ce0..4437ee77c6 100644 --- a/packages/worker/src/api/routes/global/tests/scim/users.spec.ts +++ b/packages/worker/src/api/routes/global/tests/scim/users.spec.ts @@ -437,6 +437,27 @@ describe("/api/global/scim/v2/users", () => { const persistedUser = await config.api.scimUsersAPI.find(user.id) expect(persistedUser).toEqual(expectedScimUser) }) + + it.only("an event is dispatched", async () => { + const body: ScimUpdateRequest = { + schemas: ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], + Operations: [ + { + op: "Replace", + path: "userName", + value: structures.generator.name(), + }, + ], + } + + await patchScimUser({ id: user.id, body }) + + expect(events.scim.SCIMUserUpdated).toBeCalledTimes(1) + expect(events.scim.SCIMUserUpdated).toBeCalledWith({ + email: user.emails[0].value, + timestamp: mockedTime.toISOString(), + }) + }) }) describe("DELETE /api/global/scim/v2/users/:id", () => {