440 Commits

Author SHA1 Message Date
Raymon Mens
49ec2a5c2e fix(s3): fix path prefix not applied during segment cleanup (#4799)
* fix(s3): scope segment cleanup to path prefix, fix slice panic, batch deletes

When a path prefix is configured for S3 storage, uploads correctly
write to <prefix>/hls/... but cleanup lists objects from the bucket
root without the prefix. This causes a panic when the resulting
segment list is empty, due to unsafe slicing with a negative index.

- Centralize prefix construction in remoteHLSPrefix() so Save(),
  retrieveAllVideoSegments(), and rewritePlaylistLocations() all
  share the same logic. remoteHLSListingPrefix() adds a trailing
  slash for directory-scoped S3 listing.
- Use strings.Trim to normalize both leading and trailing slashes
  from the configured path prefix.
- Replace ListObjects with ListObjectsPages to handle buckets with
  more than 1000 segments.
- Batch DeleteObjects calls in chunks of 1000 to respect the S3
  API limit, and log per-object errors from the response.
- Guard getDeletableVideoSegmentsWithOffset against empty result
  sets to prevent the slice bounds panic.

Fixes #4784

* fix(s3): handle empty hlsPrefix in rewritePlaylistLocations

LocalStorage calls rewritePlaylistLocations with an empty prefix.
The previous refactor removed the fallback to "/hls", causing
double slashes and missing path segments in playlist URLs.

Default hlsPrefix to "hls" when empty to preserve existing behavior
for local storage setups with a custom video serving endpoint.
2026-02-23 14:46:43 -08:00
Gabe Kangas
5a4af3a294 ActivityPub background actor validation, update and cleanup process (#4765)
* feat(ap): add validation+update+cleanup AP actor job

* fix(test): use time.Time instead of sql.NullTime

* feat(test): add integration test for AP follower cleanup/validation job
2026-02-02 17:34:25 -08:00
Gabe Kangas
93b482871f Require authentication to participate in chat (#4762)
* feat(chat): require authentication to participate in chat

* fix: it's pretty much impossible to bypass the auth requirement, addressing review feedback anyway

* feat(chat): render chat text input as disabled if chat auth is required

* Commit updated API documentation

---------

Co-authored-by: Owncast <owncast@owncast.online>
2026-01-28 11:49:07 -08:00
Gabe Kangas
de6468ad89 Add shared inbox support for ActivityPub delivery (#4755)
* feat(ap): add support for shared inboxes to reduce outbound load

* feat(db): refactor ap followers db into followers repository

* fix(ap): use the updated activity library to pull out the shared inbox endpoint

* chore(deps): point at updated build of owncast/activity

* fix(ap): typeless endpoints

* feat(test): update ActivityPub test to support shared inboxes

* chore(test): remove unused variable

* fix: feedback from review. Guard against SSRF/non-HTTPS/local and handle transaction errors
2026-01-22 15:33:22 -08:00
Gabe Kangas
a272d8fbe3 Fix linter errors (#4733) 2026-01-13 15:25:53 -08:00
Gabe Kangas
fea4339e94 Notifications repository + service (#4565)
* Notifications repository

* feat: notifications repo + service

* fix: remove use of notifications/notifications.go

* Update persistence/notificationsrepository/notificationsrepository.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: remove unused method

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-21 15:34:01 -08:00
fortyoneplustwo
80850b15d0 feat: Adds a webhook for when a user follows the stream (#4362)
* feat: Adds a webhook for when a user follow the stream

Frontend:
Adds a checkbox which renders only when social features are enabled.

Backend:
- Defines a new type for the event
- Implements the webhook including unit testing
- Fires the webhook inside the ApproveFollower handler

* Removes unnecessary Type fiels from Events struct

* refactor: renames SendUserFollowedEvent func to FediverseEngagementFollow and fixes linting errors

* fix: fixes unit test to reflect removed Type field from FediverseEngagementFollowEvent

* feat: fires webhook also when manual approvals are not required

* chore: slight cleanup

---------

Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2025-11-21 13:47:50 -08:00
Nicholas Kwan
fd89c6e8f2 Add native support for Windows (#4491)
* Add support for Windows

* Fixes for Windows

* Update unit tests

* Fix ffreport setting

* Add test script equivalents

* Fix fontconfig error in test stream

* Fix thumbnail generator

* Fix lint warnings

* Fix warnings in test stream script

* Implement cross-platform ocTestStream

* Migrate to cross-platform script

* Revert ocTestStream.sh

* Add missing EOL

* Alternative test scripts for non-linux environments

---------

Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2025-10-13 15:55:13 -07:00
Copilot
a0066fcf54 Fix all golangci-lint warnings surfaced by v2.4.0 (#4567)
* Initial plan

* Fix all golangci-lint warnings (21 issues resolved)

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gabek <414923+gabek@users.noreply.github.com>
2025-09-25 20:03:40 -07:00
Gabe Kangas
8eb8bdc18b Stop using empty/whitespace as chat display names (#4553)
* fix(chat): fixes #4522 to stop people from setting invalid display names

* fix(chat): also guard against non-ascii whitespace like non breaking space

* Update web/utils/displayNameValidation.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: handle additional whitespace

* Update web/utils/displayNameValidation.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Javascript formatting autofixes

* fix: deduplicate running of validation

* fix: fix error with useMemo

* Update web/utils/displayNameValidation.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update web/utils/displayNameValidation.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Javascript formatting autofixes

* fix: fix component rendering issue

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Owncast <owncast@owncast.online>
2025-09-15 13:37:39 -07:00
Copilot
740dd9c6fa Add server status as a default field in all webhooks using BaseWebhookData struct (#4410)
* Initial plan

* Add server status as default field in all webhooks

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Fix goimports linter error by removing trailing whitespace

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Move serverURL from status object to separate webhook field per feedback

Per code review feedback, serverURL is a configuration value, not a status property. This change:
- Removes ServerURL from models.Status struct
- Adds ServerURL as separate field in WebhookEvent
- Populates ServerURL directly when sending webhooks using configrepository.GetServerURL()
- Updates all tests to expect new structure

This provides the same functionality (server URL in all webhooks) while correctly treating it as configuration rather than status.

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Add omitempty tag to ServerURL field in WebhookEvent struct

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Fix webhook duplication by moving status to eventData for all events

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Restore type safety to webhook EventData using proper typed structs

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Move ServerURL from top-level WebhookEvent to eventData for all webhook types

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Update core/webhooks/webhooks.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Create BaseWebhookData struct for common webhook fields using struct embedding

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gabek <414923+gabek@users.noreply.github.com>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-31 17:12:38 -07:00
Gabe Kangas
92d1b79a80 fix(chat): fix emoji rendering as text. Fixes #4287 2025-04-23 18:13:29 -07:00
Gabe Kangas
4b627f0693 chore(go): migrate more models to codegen versions. For #3778 2025-02-12 21:18:47 -08:00
Gabe Kangas
c1f4096e11 chore(go): new chat message db repository. Closes #3081 (#4161) 2025-01-20 16:32:25 -08:00
Gabe Kangas
e78d62ce63 chore(go): move stream keys to use generated type. For #3778 2025-01-18 16:38:59 -08:00
Gabe Kangas
6abbf8f50c chore(go): create webhooks repository. Closes #4085 (#4146) 2025-01-18 15:40:10 -08:00
Gabe Kangas
b45552ade0 fix(video): remove persistent HTTP connection. Hopefully fixes #4106 2025-01-14 08:37:27 -08:00
Martin Wimpress
8ce270b02f feat: enable Intel Quicksync with support for FFmpeg 4.x to 7.1 (#4028)
* feat: enable Intel Quicksync with support for FFmpeg 4.x to 7.1

* fix(go): fix linter warning

---------

Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2025-01-12 20:38:26 -08:00
Martin Wimpress
bb4a7479b5 fix: universal Intel and AMD VA-API accelerated pipeline for FFmpeg 4 - 7 (#4022) 2025-01-12 20:10:00 -08:00
Gabe Kangas
0b5d7c8a4d Config repository (#3988)
* WIP

* fix(test): fix ap test failing

* fix: fix unkeyed fields being used

* chore(tests): clean up browser tests by splitting out federation UI tests
2024-11-15 19:20:58 -08:00
Gabe Kangas
c44d56af63 fix(test): update tests to reflect the new transcoder flag 2024-10-26 15:09:47 -07:00
Gabe Kangas
05545cb6da Add persistent http connection optimization. Closes #3985 2024-10-26 11:58:02 -07:00
Gabe Kangas
3050d64909 fix(go): fix type conversion for windows 2024-09-17 19:11:16 -07:00
Gabe Kangas
6d768f0b0a fix(go): fix type conversions for FreeBSD and Windows methods 2024-09-17 08:28:01 -07:00
Gabe Kangas
7a65e6d808 fix(go): int64 -> uint64 for connection limit value 2024-09-17 08:12:09 -07:00
renovate[bot]
4c4bc90460 fix(deps): update module mvdan.cc/xurls to v2 (#3815)
* fix(deps): update module mvdan.cc/xurls to v2

* mvdan/xurls 2.x bump fixes (#3823)

* Bump xurls import to v2

* Change Strict to function calls, v2.0.0 change

* Add go.sum entry for xurls/v2

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: mahmed2000 <mahmad2000@protonmail.com>
2024-07-08 11:24:48 -07:00
Gabe Kangas
c963512934 chore: move geoip into services directory 2024-07-02 21:26:43 -07:00
G2G2G2G
4c64fa26ac fixing grammar (#3801)
I guess California no speak english
2024-07-02 11:55:25 -07:00
Gabe Kangas
2ccd3aad87 User repository (#3795)
* It builds with the new user repository

* fix(test): fix broken test

* fix(api): fix registration endpoint that was broken after the change

* fix(test): update test to reflect new user repository

* fix: use interface type instead of concrete type

* fix: restore commented out code
2024-07-01 18:58:50 -07:00
mahmed2000
a7e5f20337 Implement admin password hashing with bcrypt (#3754)
* Add bcrypt hashing helpers

* SetAdminPassword now hashes the password before saving it

* BasicAuth now compares the bcrypt hash for the password

* Modify migration2 to avoid a double password hash when upgrading

* Add migration for bcrypt hashed password

* Do not show admin password hash as initial value

* Update api tests to compare the bcrypt hash of the admin password instead

* Remove old admin password api tests

---------

Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2024-06-26 21:20:22 -07:00
Vivian Lim ⭐
f81e8dcda7 Mute the 'stream ended' clip's audio (#3630)
* Mute the 'stream ended' clip's audio

The 'stream ended' clip plays at the at the end of every stream broadcast using owncast.
It currently contains audio that peaks at -7.1db. (according to ffmpeg's volumedetect audio filter)
This can result in a bad experience for viewers if the stream that they were just watching had a much lower average volume, and they had turned up their speakers or headphones to compensate. In extreme cases this could theoretically cause harm to viewers and/or their equipment.
As an admin running owncast, there is no way to remove this audio *except* for patching the file. Even if you do patch the file, you need to notify your viewers to clear their browser caches if they have ever seen the clip, because offline.ts has a cache-control max-age header specifying 365 days. The caching of the previous version of this clip is out of scope of this PR.

This issue is discussed in more detail in #1965.

Unlike my previous attempt in #3332, which removed the audio track, this PR *mutes* the audio.

Specifically, I used this ffmpeg command:
```
ffmpeg -i offline.ts -filter:a "volume=0.0" output.ts
```

There are no other modifications to the clip.

* Commit updated API documentation

* feat(video): make compatible muted offline clip. Rename clip as a v2 so it is not cached

* Fix conflict

* force add new offline file

---------

Co-authored-by: vivlim <vivlim@vivl.im>
Co-authored-by: Owncast <owncast@owncast.online>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2024-04-17 11:44:19 -07:00
Gabe Kangas
a450e62397 Optionally disable chat rate limiter and add optional chat slur/language filter (#3681)
* feat(chat): basic profanity filter. For #3139

* feat(chat): add setting for disabling chat spam protection. Closes #3523

* feat(chat): wire up the new chat slur filter to admin and chat. Closes #3139
2024-04-09 22:25:41 -07:00
Gabe Kangas
ebf64dd17d fix(chat): do not send chat join message
If a user is already connected to chat from elsewhere, do not send an
additional chat join message. Closes #3487
2024-02-18 15:49:50 -08:00
Aziz Rmadi
b532b1545c Modified rate limit conditions to exclude moderators (#3534) 2024-01-24 10:27:38 -08:00
Gabe Kangas
841c300431 fix: share local hls file cleanup between s3 and filesystem providers. Fixes #3522 (#3531) 2024-01-22 20:26:36 -08:00
Gabe Kangas
7399bee276 Gek/cache bot search page (#3530)
* feat: add general purpose key/val caching layer

* feat: cache bot/metadata response page for 10 seconds
2024-01-21 17:18:47 -08:00
Gabe Kangas
5bb8a8b5aa fix: address potential crash that can happen with queued object storage uploads. Fixes #3440 2023-12-18 21:12:50 -08:00
Gabe Kangas
b4c73315fa feat(log): point to passthrough as a potential issue when unable to generate thumbnails
Re: #3433 and #3431
2023-11-20 18:04:01 -08:00
Gabe Kangas
027f2544e3 fix(emoji): hopefully guard against the crash in #3331 2023-10-21 22:13:13 -07:00
Gabe Kangas
8e79e2acfa chore(go): run betteralign and gofumpt on codebase 2023-10-08 14:22:28 -07:00
Gabe Kangas
03b785fbe2 fix: remove whitespace to resolve linter warning 2023-09-21 18:04:06 -07:00
Tom Funken
e375ea232a Renamed rewriteRemotePlaylist (#3313)
* Add support for remote serving endpoint on local storage

* Renamed rewriteRemotePlaylist
2023-09-21 17:58:02 -07:00
Gabe Kangas
169c11596c feat(chat): add support for chat part messages. Closes #3201 (#3291) 2023-09-10 10:58:11 -07:00
Gabe Kangas
3174eb20e5 fix: updates for new linter rules. Closes #3277 2023-08-25 19:58:44 -07:00
Gabe Kangas
1a7b6b99d5 feat(storage): support a object storage custom path prefix 2023-08-11 22:18:45 -07:00
Gabe Kangas
0fba5f70e2 feat(video): add IP address to RTMP logs. Closes #3212 (#3233) 2023-08-03 20:54:56 -07:00
Gabe Kangas
c9298def5b Cleanup object storage files on success or failure (#3231)
* fix: cleanup object storage files on success or failure. Closes #3230

* fix: clean filepath when deleting for safety
2023-08-03 20:33:44 -07:00
John Regan
b2a80f2149 s3Storage: fix slice bounds out of range error (#3208) 2023-07-24 15:12:04 -07:00
Gabe Kangas
d0376cdc75 fix: limit the different worker pools to available CPU cores. Should resolve #3189 2023-07-18 20:26:44 -07:00
John Regan
dfa3a2a273 chat: check that a new username is different before sending out updates (#3162) 2023-07-10 23:16:36 -07:00