Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steipete
Copy link
Contributor

Summary

Testing

  • pnpm lint
  • pnpm build
  • pnpm test

@cursor
Copy link

cursor bot commented Jan 23, 2026

PR Summary

Strengthens BlueBubbles voice memo sending and tightens attachment safety.

  • attachments.ts: remove Opus/ffmpeg conversion; require MP3/CAF when asVoice=true, set isAudioMessage, normalize extensions (.mp3/.caf), and sanitize filenames before upload
  • actions.ts: add local boolean parsing and pass asVoice to sendBlueBubblesAttachment
  • Tests: add coverage for voice memo rules (format validation, filename normalization/sanitization) and action passthrough
  • Docs: update BlueBubbles actions to document sendAttachment(..., asVoice) and MP3/CAF requirements; CHANGELOG entry added

Written by Cursor Bugbot for commit d0ffad7. This will update automatically on new commits. Configure here.

@steipete steipete merged commit 9207840 into main Jan 23, 2026
37 of 42 checks passed
@steipete steipete deleted the fix/bluebubbles-voice-memos branch January 23, 2026 04:38
@steipete
Copy link
Contributor Author

Landed via temp rebase onto main.

Thanks @Nicell!

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

if (trimmed === "false") return false;
}
return undefined;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate readBooleanParam function implementation

Low Severity

The readBooleanParam helper function is duplicated identically in both actions.ts and message-action-runner.ts. This increases maintenance burden since any bug fixes or improvements need to be applied in multiple places, and creates inconsistency risk across the codebase.

Fix in Cursor Fix in Web

const trimmed = input?.trim() ?? "";
const base = trimmed ? path.basename(trimmed) : "";
return base || fallback;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insufficient filename sanitization breaks multipart form encoding

Medium Severity

The sanitizeFilename function only removes directory traversal via path.basename() but doesn't sanitize special characters like double quotes, newlines, or carriage returns. These characters will corrupt the multipart form data at line 209 where the filename is interpolated into the Content-Disposition header with double-quote delimiters, potentially breaking attachment uploads or allowing header injection.

Fix in Cursor Fix in Web

const trimmed = input?.trim() ?? "";
const base = trimmed ? path.basename(trimmed) : "";
return base || fallback;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid filenames not rejected by sanitization

Medium Severity

The sanitizeFilename function returns invalid filenames like / or \ instead of falling back to the fallback name when path.basename() returns a path separator. This happens because path separators are truthy strings, so the base || fallback check fails to catch them, leading to malformed filenames in the multipart form data that could cause BlueBubbles attachment uploads to fail.

Fix in Cursor Fix in Web

contentType = contentType ?? "audio/mpeg";
} else if (voiceInfo.isCaf) {
filename = ensureExtension(filename, ".caf", fallbackName);
contentType = contentType ?? "audio/x-caf";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent contentType when filename and MIME type conflict

Medium Severity

For voice memos, when the filename extension and provided contentType indicate different formats (e.g., filename is voice.mp3 but contentType is audio/x-caf), the code uses contentType ?? defaultType which preserves the conflicting contentType. This sends inconsistent metadata to BlueBubbles where the filename says MP3 but the Content-Type header says CAF, potentially causing voice memo conversion or upload to fail.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants