Commit Graph

26 Commits

Author SHA1 Message Date
Stanko K.R. 80c9e7fbfe Adjust to the in-house style
- Use jbuilder instead of hashes
- Use resource instead of direct HTTP verbs
    Verbs only make sense if you have one or two routes, if there are
    multiple that emulate what resource does then it's better to use resource.
- Paginate using link headers
- Cache responses
2026-08-11 13:15:38 +02:00
John-Mason Shackelford 20ab5b1bc6 feat: Add bot API endpoint for adding reactions (boosts) to messages
Adds a new endpoint that allows bots to add emoji reactions (boosts) to messages:
POST /rooms/:room_id/:bot_key/messages/:message_id/boosts

This enables bots to acknowledge messages with reactions like 👀 (eyes) when
mentioned, providing immediate feedback to users before generating a full response.

The endpoint:
- Validates the bot is a member of the room
- Validates the message exists in the room
- Broadcasts the boost to connected clients via Turbo Streams
- Returns 201 Created on success, 404 if room/message not found

Co-authored-by: openhands <openhands@all-hands.dev>
2026-04-08 18:53:03 -04:00
John-Mason Shackelford c82a8d38c0 fix: Use correct room messages in pagination tests
Fixed test bug identified by Copilot code review: pagination tests were
using Message.first and Message.last which could return messages from
different rooms than the test's @room (watercooler).

Now explicitly using messages(:fourth) and messages(:thirteenth) which
are fixtures belonging to the watercooler room where bender bot is a member.

Co-authored-by: openhands <openhands@all-hands.dev>
2026-04-08 14:45:02 -04:00
John-Mason Shackelford 057d56513e fix: Align create and index to both return 404 for non-member rooms
Both create and index now return HTTP 404 Not Found when a bot tries to
access a room it's not a member of. This is consistent with REST API
security best practices (not revealing resource existence) and ensures
read and write permissions are handled identically.

Changed create action to no longer call super (which rendered HTML) and
instead directly handle the request with proper JSON API error responses.

Added test to verify create returns 404 for non-member rooms.

Co-authored-by: openhands <openhands@all-hands.dev>
2026-04-08 13:59:56 -04:00
John-Mason Shackelford 5340f3da01 fix: Ensure bot can only read messages from rooms it is a member of
Added explicit RecordNotFound handling to return 404 when a bot tries to
read messages from a room it's not a member of. This matches the security
model used by the create action.

Added tests to verify:
- Bot gets 404 when trying to read from room it's not a member of
- Bot can successfully read from room it IS a member of

Co-authored-by: openhands <openhands@all-hands.dev>
2026-04-08 13:56:02 -04:00
John-Mason Shackelford d4a56784e0 feat: Add bot API endpoint for reading room messages
Adds a new GET endpoint at /rooms/:room_id/:bot_key/messages that allows
bots to read messages from rooms they are members of.

The endpoint returns JSON with:
- Room info (id, name)
- Messages array with body (plain/html), created_at, and creator info
- Pagination info (oldest_id, newest_id, has_more)

Supports pagination via ?before=:id and ?after=:id query parameters,
consistent with the existing pagination in the messages controller.

This enables AI bots and other automated agents to understand conversation
context when responding to messages, rather than only receiving the single
message that triggered the webhook.

Co-authored-by: openhands <openhands@all-hands.dev>
2026-04-08 13:53:17 -04:00
Rosa Gutierrez dde94b06ed Delete server-side session on logout
When it's set. Also, store it in current attributes for convenience.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 09:31:22 +01:00
Jeremy Daer e983e3f79f Block IPv6 SSRF bypass via ipv4_compat addresses (#153)
Adds ipv4_mapped? and ipv4_compat? checks to PrivateNetworkGuard.private_ip?
to block SSRF bypass attempts using IPv6 address formats like:
- ::ffff:169.254.169.254 (IPv4-mapped)
- ::169.254.169.254 (IPv4-compatible)

These formats could previously bypass the link_local? check since Ruby
treats them as IPv6 addresses, not IPv4.

Ref: HackerOne #3481701
2025-12-31 13:01:43 -08:00
Mike Dalessio 1feb2d94b9 Address race condition during "first run" account creation 2025-12-12 10:51:28 -05:00
Ashwin M b52c318518 Group administrators separately from members with visual divider 2025-12-09 08:42:00 +05:30
Michael Halliday b8919161a8 Allow non-admins to update their room involvements 2025-12-03 09:56:15 -05:00
Stanko K.R. 0672673916 Disallow SSRF via IPv6 addresses mapped to IPv4 addresses 2025-12-03 08:08:34 +01:00
Jeremy Daer 5667262d1c Security: disallow blind SSRF to link-local IPs via URL unfurling 2025-12-02 21:33:44 -08:00
Stanko K.R. 4d04f9beee Use urlsafe base64 decode 2025-12-02 11:34:12 +01:00
Stanko K.R. bebe518c74 Parse Rails 7 GIDs 2025-12-02 11:06:23 +01:00
David Heinemeier Hansson 5266ffc049 Always just go through the settings object 2025-12-01 15:26:06 +01:00
David Heinemeier Hansson bd3b0c5988 Not needed 2025-12-01 15:26:06 +01:00
David Heinemeier Hansson 796195c2cc Give up on the auto delegation to get a cleaner API 2025-12-01 15:26:06 +01:00
David Heinemeier Hansson d323c3cfc0 Now required to be explicitly included
Not sure why
2025-12-01 15:23:57 +01:00
David Heinemeier Hansson f7c3aaa2a9 Allow for default values 2025-12-01 15:23:23 +01:00
David Heinemeier Hansson 15db4033bc Enforce restriction to create new rooms 2025-12-01 15:22:37 +01:00
David Heinemeier Hansson bea2c89c2b Add new has_json to add Account#settings to restrict room creation to only administrators 2025-12-01 15:22:36 +01:00
Kevin McConnell 30fe6ab121 Add IP-based user banning
This adds the ability to ban a user by their IP address.

When an admin is viewing a user profile, a new "Ban user" button is
present. Clicking on that will:

- Create a ban on the IP addresses that were tracked for that user's
  sessions
- Remove all the messages authored by that user
- Log the user out immediately

In addition, that user will no longer be shown in most user lists in the
app. They are still shown to admins, in account settings. Viewing their
profile from there will now show a "Remove ban" button which can be used
to restore their access (it doesn't restore their messages though --
those are already gone -- it just removes the blocks so they can log in
again).
2025-11-26 14:30:38 +00:00
Jacopo 3d0a10dbdd Security: Fix user impersonation via custom bot token
If bot_key has no right-hand side (ex: 1-), bot_token will be nil, and the query will match a User record if bot_id matches a valid ID.
Fix it relying on `active_bots` instead.
2025-09-11 12:32:46 +02:00
Stanko Krtalić eecdb29332 Upgrade to Rails 8 and Ruby 3.4.5 (#1)
* Bump Ruby to 3.4.5
* Update dependencies
* Adjust for Rails 8 and Ruby 3.5 API changes
* Mark params strings as mutable in prepapration for frozen strings in Ruby 3.5
* Update test for HTML5 sanitizer
    With Rails 7.1 the HTML5 sanitizer became the default, this breakts this test because the old sanitizer used to delete unpermitted nodes, while the new one returns their content
    The final string is safe, but different then it used to be in Rails 7.0
* Remove direct Turbo tesh helpers require & parallelize tests
* Fix Zeitwerk issues with rails extensions
* Update Resque setup for Redis 5+
* Remove unused views
* Remove GID v1 handler
2025-09-02 17:02:41 +02:00
Kevin McConnell df76a227dc Hello world
First open source release of Campfire 🎉
2025-08-21 09:31:59 +01:00