diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/datadog-configuration.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/datadog-configuration.ts index 51217a85877..4f84c0bcef6 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/datadog-configuration.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/datadog-configuration.ts @@ -4,15 +4,19 @@ import { OrganizationIntegrationServiceName } from "../organization-integration- export class DatadogConfiguration implements OrgIntegrationConfiguration { uri: string; apiKey: string; - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; - constructor(uri: string, apiKey: string, service: OrganizationIntegrationServiceName) { + constructor(uri: string, apiKey: string, bw_serviceName: OrganizationIntegrationServiceName) { this.uri = uri; this.apiKey = apiKey; - this.service = service; + this.bw_serviceName = bw_serviceName; } - toString(): string { - return JSON.stringify(this); + toString() { + return JSON.stringify({ + Uri: this.uri, + ApiKey: this.apiKey, + bw_serviceName: this.bw_serviceName, + }); } } diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/hec-configuration.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/hec-configuration.ts index d7e0cec1840..275ff82e9bd 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/hec-configuration.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/hec-configuration.ts @@ -5,15 +5,21 @@ export class HecConfiguration implements OrgIntegrationConfiguration { uri: string; scheme = "Bearer"; token: string; - service: OrganizationIntegrationServiceName; + service?: string; + bw_serviceName: OrganizationIntegrationServiceName; - constructor(uri: string, token: string, service: OrganizationIntegrationServiceName) { + constructor(uri: string, token: string, bw_serviceName: OrganizationIntegrationServiceName) { this.uri = uri; this.token = token; - this.service = service; + this.bw_serviceName = bw_serviceName; } toString(): string { - return JSON.stringify(this); + return JSON.stringify({ + Uri: this.uri, + Scheme: this.scheme, + Token: this.token, + bw_serviceName: this.bw_serviceName, + }); } } diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/webhook-configuration.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/webhook-configuration.ts index 2b9ed6f7bda..f8243d3aac6 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/webhook-configuration.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/configuration/webhook-configuration.ts @@ -5,12 +5,12 @@ import { OrganizationIntegrationServiceName } from "../organization-integration- export class WebhookConfiguration implements OrgIntegrationConfiguration { propA: string; propB: string; - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; - constructor(propA: string, propB: string, service: OrganizationIntegrationServiceName) { + constructor(propA: string, propB: string, bw_serviceName: OrganizationIntegrationServiceName) { this.propA = propA; this.propB = propB; - this.service = service; + this.bw_serviceName = bw_serviceName; } toString(): string { diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-builder.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-builder.ts index ae790a67408..db682d58db4 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-builder.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-builder.ts @@ -9,7 +9,7 @@ import { OrganizationIntegrationType } from "./organization-integration-type"; * Defines the structure for organization integration configuration */ export interface OrgIntegrationConfiguration { - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; toString(): string; } @@ -17,7 +17,7 @@ export interface OrgIntegrationConfiguration { * Defines the structure for organization integration template */ export interface OrgIntegrationTemplate { - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; toString(): string; } @@ -28,24 +28,26 @@ export class OrgIntegrationBuilder { static buildHecConfiguration( uri: string, token: string, - service: OrganizationIntegrationServiceName, + bw_serviceName: OrganizationIntegrationServiceName, ): OrgIntegrationConfiguration { - return new HecConfiguration(uri, token, service); + return new HecConfiguration(uri, token, bw_serviceName); } static buildHecTemplate( index: string, - service: OrganizationIntegrationServiceName, + bw_serviceName: OrganizationIntegrationServiceName, ): OrgIntegrationTemplate { - return new HecTemplate(index, service); + return new HecTemplate(index, bw_serviceName); } static buildDataDogConfiguration(uri: string, apiKey: string): OrgIntegrationConfiguration { return new DatadogConfiguration(uri, apiKey, OrganizationIntegrationServiceName.Datadog); } - static buildDataDogTemplate(service: OrganizationIntegrationServiceName): OrgIntegrationTemplate { - return new DatadogTemplate(service); + static buildDataDogTemplate( + bw_serviceName: OrganizationIntegrationServiceName, + ): OrgIntegrationTemplate { + return new DatadogTemplate(bw_serviceName); } static buildConfiguration( @@ -55,7 +57,7 @@ export class OrgIntegrationBuilder { switch (type) { case OrganizationIntegrationType.Hec: { const hecConfig = this.convertToJson(configuration); - return this.buildHecConfiguration(hecConfig.uri, hecConfig.token, hecConfig.service); + return this.buildHecConfiguration(hecConfig.uri, hecConfig.token, hecConfig.bw_serviceName); } case OrganizationIntegrationType.Datadog: { const datadogConfig = this.convertToJson(configuration); @@ -73,11 +75,11 @@ export class OrgIntegrationBuilder { switch (type) { case OrganizationIntegrationType.Hec: { const hecTemplate = this.convertToJson(template); - return this.buildHecTemplate(hecTemplate.index, hecTemplate.service); + return this.buildHecTemplate(hecTemplate.index, hecTemplate.bw_serviceName); } case OrganizationIntegrationType.Datadog: { const datadogTemplate = this.convertToJson(template); - return this.buildDataDogTemplate(datadogTemplate.service); + return this.buildDataDogTemplate(datadogTemplate.bw_serviceName); } default: throw new Error(`Unsupported integration type: ${type}`); @@ -86,9 +88,33 @@ export class OrgIntegrationBuilder { private static convertToJson(jsonString?: string): T { try { - return JSON.parse(jsonString || "{}") as T; + const parsed = JSON.parse(jsonString || "{}"); + return this.normalizePropertyCase(parsed) as T; } catch { throw new Error("Invalid integration configuration: JSON parse error"); } } + + /** + * Recursively normalizes object property names to camelCase + * Converts the first character of each property to lowercase + */ + private static normalizePropertyCase(obj: any): any { + if (obj === null || typeof obj !== "object") { + return obj; + } + + if (Array.isArray(obj)) { + return obj.map((item) => this.normalizePropertyCase(item)); + } + + const normalized: any = {}; + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + const normalizedKey = key.charAt(0).toLowerCase() + key.slice(1); + normalized[normalizedKey] = this.normalizePropertyCase(obj[key]); + } + } + return normalized; + } } diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/datadog-template.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/datadog-template.ts index d8e168aacbe..b5816ba34a2 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/datadog-template.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/datadog-template.ts @@ -2,17 +2,54 @@ import { OrgIntegrationTemplate } from "../../integration-builder"; import { OrganizationIntegrationServiceName } from "../../organization-integration-service-type"; export class DatadogTemplate implements OrgIntegrationTemplate { - source_type_name = "Bitwarden"; - title: string = "#Title#"; - text: string = - "ActingUser: #ActingUserId#\nUser: #UserId#\nEvent: #Type#\nOrganization: #OrganizationId#\nPolicyId: #PolicyId#\nIpAddress: #IpAddress#\nDomainName: #DomainName#\nCipherId: #CipherId#\n"; - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; constructor(service: OrganizationIntegrationServiceName) { - this.service = service; + this.bw_serviceName = service; + } + + private toJSON() { + return { + bw_serviceName: this.bw_serviceName, + ddsource: "bitwarden", + service: "event-logs", + event: { + service: "payments", + object: "event", + type: "#Type#", + itemId: "#CipherId#", + collectionId: "#CollectionId#", + groupId: "#GroupId#", + policyId: "#PolicyId#", + memberId: "#UserId#", + actingUserId: "#ActingUserId#", + installationId: "#InstallationId#", + date: "#DateIso8601#", + device: "#DeviceType#", + ipAddress: "#IpAddress#", + secretId: "#SecretId#", + projectId: "#ProjectId#", + serviceAccountId: "#ServiceAccountId#", + }, + enrichment_details: { + actingUser: { + name: "#ActingUserName#", + email: "#ActingUserEmail#", + type: "#ActingUserType#", + }, + member: { + name: "#UserName#", + email: "#UserEmail#", + type: "#UserType#", + }, + group: { + name: "#GroupName#", + }, + }, + }; } toString(): string { - return JSON.stringify(this); + return JSON.stringify(this.toJSON()); } } diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/hec-template.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/hec-template.ts index e1b474d0e77..27d71f29e59 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/hec-template.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/hec-template.ts @@ -5,14 +5,19 @@ export class HecTemplate implements OrgIntegrationTemplate { event = "#EventMessage#"; source = "Bitwarden"; index: string; - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; constructor(index: string, service: OrganizationIntegrationServiceName) { this.index = index; - this.service = service; + this.bw_serviceName = service; } toString(): string { - return JSON.stringify(this); + return JSON.stringify({ + Event: this.event, + Source: this.source, + Index: this.index, + bw_serviceName: this.bw_serviceName, + }); } } diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/webhook-template.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/webhook-template.ts index fb482d1f367..2472fb5912e 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/webhook-template.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-configuration-config/configuration-template/webhook-template.ts @@ -3,12 +3,12 @@ import { OrganizationIntegrationServiceName } from "../../organization-integrati // Added to reflect how future webhook integrations could be structured within the OrganizationIntegration export class WebhookTemplate implements OrgIntegrationTemplate { - service: OrganizationIntegrationServiceName; + bw_serviceName: OrganizationIntegrationServiceName; propA: string; propB: string; - constructor(service: OrganizationIntegrationServiceName, propA: string, propB: string) { - this.service = service; + constructor(bw_serviceName: OrganizationIntegrationServiceName, propA: string, propB: string) { + this.bw_serviceName = bw_serviceName; this.propA = propA; this.propB = propB; } diff --git a/bitwarden_license/bit-common/src/dirt/organization-integrations/services/organization-integration-service.ts b/bitwarden_license/bit-common/src/dirt/organization-integrations/services/organization-integration-service.ts index cd153bc1133..c9457f4bcfc 100644 --- a/bitwarden_license/bit-common/src/dirt/organization-integrations/services/organization-integration-service.ts +++ b/bitwarden_license/bit-common/src/dirt/organization-integrations/services/organization-integration-service.ts @@ -266,7 +266,7 @@ export class OrganizationIntegrationService { return new OrganizationIntegration( integrationResponse.id, integrationResponse.type, - config.service, + config.bw_serviceName, config, [integrationConfig], );