Add an option at the config and state level to disable hook bodies.

This commit is contained in:
Will Hunt 2024-12-23 17:13:29 +00:00
parent bff68d8a6e
commit 61e061d554
2 changed files with 12 additions and 3 deletions

View File

@ -36,6 +36,8 @@ export interface GenericHookConnectionState extends IConnectionState {
* (in UTC) time. * (in UTC) time.
*/ */
expirationDate?: string; expirationDate?: string;
includeHookBody?: boolean;
} }
export interface GenericHookSecrets { export interface GenericHookSecrets {
@ -152,7 +154,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
} }
static validateState(state: Partial<Record<keyof GenericHookConnectionState, unknown>>): GenericHookConnectionState { static validateState(state: Partial<Record<keyof GenericHookConnectionState, unknown>>): GenericHookConnectionState {
const {name, transformationFunction, waitForComplete, expirationDate: expirationDateStr} = state; const {name, transformationFunction, waitForComplete, expirationDate: expirationDateStr, includeHookBody} = state;
if (!name) { if (!name) {
throw new ApiError('Missing name', ErrCode.BadValue); throw new ApiError('Missing name', ErrCode.BadValue);
} }
@ -162,6 +164,9 @@ export class GenericHookConnection extends BaseConnection implements IConnection
if (waitForComplete !== undefined && typeof waitForComplete !== "boolean") { if (waitForComplete !== undefined && typeof waitForComplete !== "boolean") {
throw new ApiError("'waitForComplete' must be a boolean", ErrCode.BadValue); throw new ApiError("'waitForComplete' must be a boolean", ErrCode.BadValue);
} }
if (includeHookBody !== undefined && typeof includeHookBody !== "boolean") {
throw new ApiError("'includeHookBody' must be a boolean", ErrCode.BadValue);
}
// Use !=, not !==, to check for both undefined and null // Use !=, not !==, to check for both undefined and null
if (transformationFunction != undefined) { if (transformationFunction != undefined) {
if (!this.quickModule) { if (!this.quickModule) {
@ -186,6 +191,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
name, name,
transformationFunction: transformationFunction || undefined, transformationFunction: transformationFunction || undefined,
waitForComplete, waitForComplete,
includeHookBody: includeHookBody ?? true,
expirationDate, expirationDate,
}; };
} }
@ -249,7 +255,6 @@ export class GenericHookConnection extends BaseConnection implements IConnection
throw new ApiError('Expiration date must be set', ErrCode.BadValue); throw new ApiError('Expiration date must be set', ErrCode.BadValue);
} }
await GenericHookConnection.ensureRoomAccountData(roomId, intent, hookId, validState.name); await GenericHookConnection.ensureRoomAccountData(roomId, intent, hookId, validState.name);
await intent.underlyingClient.sendStateEvent(roomId, this.CanonicalEventType, validState.name, validState); await intent.underlyingClient.sendStateEvent(roomId, this.CanonicalEventType, validState.name, validState);
const connection = new GenericHookConnection(roomId, validState, hookId, validState.name, messageClient, config.generic, as, intent, storage); const connection = new GenericHookConnection(roomId, validState, hookId, validState.name, messageClient, config.generic, as, intent, storage);
@ -580,7 +585,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
await ensureUserIsInRoom(senderIntent, this.intent.underlyingClient, this.roomId); await ensureUserIsInRoom(senderIntent, this.intent.underlyingClient, this.roomId);
// Matrix cannot handle float data, so make sure we parse out any floats. // Matrix cannot handle float data, so make sure we parse out any floats.
const safeData = GenericHookConnection.sanitiseObjectForMatrixJSON(data); const safeData = (this.config.includeHookBody && this.state.includeHookBody) ? GenericHookConnection.sanitiseObjectForMatrixJSON(data) : undefined;
await this.messageClient.sendMatrixMessage(this.roomId, { await this.messageClient.sendMatrixMessage(this.roomId, {
msgtype: content.msgtype || "m.notice", msgtype: content.msgtype || "m.notice",
@ -617,6 +622,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
waitForComplete: this.waitForComplete, waitForComplete: this.waitForComplete,
name: this.state.name, name: this.state.name,
expirationDate: this.state.expirationDate, expirationDate: this.state.expirationDate,
includeHookBody: this.config.includeHookBody && this.state.includeHookBody,
}, },
...(showSecrets ? { secrets: { ...(showSecrets ? { secrets: {
url: new URL(this.hookId, this.config.parsedUrlPrefix), url: new URL(this.hookId, this.config.parsedUrlPrefix),

View File

@ -19,6 +19,7 @@ export interface BridgeGenericWebhooksConfigYAML {
maxExpiryTime?: string; maxExpiryTime?: string;
sendExpiryNotice?: boolean; sendExpiryNotice?: boolean;
requireExpiryTime?: boolean; requireExpiryTime?: boolean;
includeHookBody?: boolean;
} }
export class BridgeConfigGenericWebhooks { export class BridgeConfigGenericWebhooks {
@ -33,6 +34,7 @@ export class BridgeConfigGenericWebhooks {
public readonly allowJsTransformationFunctions?: boolean; public readonly allowJsTransformationFunctions?: boolean;
public readonly waitForComplete?: boolean; public readonly waitForComplete?: boolean;
public readonly enableHttpGet: boolean; public readonly enableHttpGet: boolean;
public readonly includeHookBody: boolean;
@hideKey() @hideKey()
public readonly maxExpiryTimeMs?: number; public readonly maxExpiryTimeMs?: number;
@ -47,6 +49,7 @@ export class BridgeConfigGenericWebhooks {
this.enableHttpGet = yaml.enableHttpGet || false; this.enableHttpGet = yaml.enableHttpGet || false;
this.sendExpiryNotice = yaml.sendExpiryNotice || false; this.sendExpiryNotice = yaml.sendExpiryNotice || false;
this.requireExpiryTime = yaml.requireExpiryTime || false; this.requireExpiryTime = yaml.requireExpiryTime || false;
this.includeHookBody = yaml.includeHookBody || false;
try { try {
this.parsedUrlPrefix = makePrefixedUrl(yaml.urlPrefix); this.parsedUrlPrefix = makePrefixedUrl(yaml.urlPrefix);
this.urlPrefix = () => { return this.parsedUrlPrefix.href; } this.urlPrefix = () => { return this.parsedUrlPrefix.href; }