From 57252579d3fa7ce1c2ab7a3a3b1f172b6d74e542 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Mon, 10 Aug 2026 18:38:45 +0200 Subject: [PATCH 1/6] docs: thank TypeType sponsors --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 8f08a01..3275dac 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,16 @@ The installer creates `~/typetype-stack`, generates installation-specific secret - SponsorBlock, DeArrow, content blocking, imports, OIDC, and instance administration - No TypeType telemetry; the instance operator controls the deployment and its data +## Sponsors + +A big thx to [@Toastienergy](https://github.com/Toastienergy) and +[@filippobaroni](https://github.com/filippobaroni) for supporting TypeType through +GitHub Sponsors. Their support helps me cover the infrastructure and spend more +time improving the project. + +If u want to support TypeType financially, u can do so through +[GitHub Sponsors](https://github.com/sponsors/Priveetee). + ## For developers Each component has its own repository, tests, release cycle, and license. Pull requests belong in the repository that owns the changed code. Bug reports and feature requests stay in the central issue tracker. From f90022debc7673894d446c97a65718e18b2da297 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Wed, 12 Aug 2026 14:33:47 +0200 Subject: [PATCH 2/6] fix: remove Python dependency from stack scripts --- scripts/bootstrap-env.sh | 12 +----- scripts/bootstrap-garage.sh | 12 +----- scripts/install-stack.sh | 71 ++++++++++++++--------------------- scripts/install-stack.test.sh | 17 +++++++++ scripts/setup-stack.sh | 71 ++++++++++++++--------------------- 5 files changed, 78 insertions(+), 105 deletions(-) diff --git a/scripts/bootstrap-env.sh b/scripts/bootstrap-env.sh index b2de019..c9fbcd0 100755 --- a/scripts/bootstrap-env.sh +++ b/scripts/bootstrap-env.sh @@ -16,11 +16,7 @@ generate_secret() { return fi - python3 - <<'PY' -import secrets - -print(secrets.token_urlsafe(48)) -PY + head -c 48 /dev/urandom | base64 | tr '+/' '-_' | tr -d '=\n' } generate_hex_secret() { @@ -29,11 +25,7 @@ generate_hex_secret() { return fi - python3 - <<'PY' -import secrets - -print(secrets.token_hex(32)) -PY + od -An -N 32 -tx1 /dev/urandom | tr -d '[:space:]' } set_env_var() { diff --git a/scripts/bootstrap-garage.sh b/scripts/bootstrap-garage.sh index d6b02d4..047ef22 100755 --- a/scripts/bootstrap-garage.sh +++ b/scripts/bootstrap-garage.sh @@ -14,17 +14,7 @@ STATIC_RPC_SECRET="f4db2c1d5aef1dce278d4315b80425e98831714a48c059e22c2a39001b15c generate_hex() { local bytes="$1" - if command -v openssl >/dev/null 2>&1; then - openssl rand -hex "${bytes}" - return - fi - - python3 - "${bytes}" <<'PY' -import secrets -import sys - -print(secrets.token_hex(int(sys.argv[1]))) -PY + od -An -N "${bytes}" -tx1 /dev/urandom | tr -d '[:space:]' } generate_downloader_access_key() { diff --git a/scripts/install-stack.sh b/scripts/install-stack.sh index 3fa24e7..f7a30ee 100755 --- a/scripts/install-stack.sh +++ b/scripts/install-stack.sh @@ -141,17 +141,7 @@ confirm_tty() { generate_hex() { local bytes="$1" - if command -v openssl >/dev/null 2>&1; then - openssl rand -hex "${bytes}" - return - fi - - python3 - "${bytes}" <<'PY' -import secrets -import sys - -print(secrets.token_hex(int(sys.argv[1]))) -PY + od -An -N "${bytes}" -tx1 /dev/urandom | tr -d '[:space:]' } generate_downloader_access_key() { @@ -232,20 +222,24 @@ ensure_youtube_remote_login_env() { fi } -require_free_port() { +port_is_listening() { local port="$1" - python3 - < 1 && toupper(substr($2, length($2) - 3)) == port && $4 == "0A" { found = 1; exit } + END { exit found ? 0 : 1 } + ' "${socket_tables[@]}" + return + fi + (exec 3<>"/dev/tcp/127.0.0.1/${port}") 2>/dev/null +} + +require_free_port() { + ! port_is_listening "$1" } get_env_var() { @@ -261,24 +255,17 @@ is_valid_port() { } find_random_free_port() { - python3 - <<'PY' -import random -import socket - -for _ in range(500): - port = random.randint(20000, 60999) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - s.bind(("0.0.0.0", port)) - except OSError: - continue - finally: - s.close() - print(port) - break -else: - raise SystemExit("no free port found") -PY + local attempt + local port + for ((attempt = 0; attempt < 500; attempt++)); do + port=$((20000 + (((RANDOM << 15) | RANDOM) % 41000))) + if require_free_port "${port}"; then + echo "${port}" + return + fi + done + echo "[install] No free port found between 20000 and 60999." >&2 + return 1 } existing_stack_port() { diff --git a/scripts/install-stack.test.sh b/scripts/install-stack.test.sh index 9ce23fe..de8fe54 100755 --- a/scripts/install-stack.test.sh +++ b/scripts/install-stack.test.sh @@ -8,6 +8,7 @@ trap 'rm -rf "$temporary"' EXIT fake_bin="${temporary}/bin" install_dir="${temporary}/stack" docker_log="${temporary}/docker.log" +python_log="${temporary}/python.log" mkdir -p "$fake_bin" cat > "${fake_bin}/docker" <<'EOF' @@ -18,8 +19,16 @@ printf '\n' >> "$FAKE_DOCKER_LOG" EOF chmod +x "${fake_bin}/docker" +cat > "${fake_bin}/python3" <<'EOF' +#!/usr/bin/env bash +printf 'called\n' >> "$FAKE_PYTHON_LOG" +exit 99 +EOF +chmod +x "${fake_bin}/python3" + PATH="${fake_bin}:${PATH}" \ FAKE_DOCKER_LOG="$docker_log" \ +FAKE_PYTHON_LOG="$python_log" \ bash "${repository}/scripts/install-stack.sh" \ --source-dir "$repository" \ --dir "$install_dir" \ @@ -42,3 +51,11 @@ done grep -q '^compose version ' "$docker_log" grep -q 'compose .*config -q ' "$docker_log" grep -q '\[install\] Download-only complete\.' "${temporary}/install.log" +test ! -e "$python_log" + +downloader_access_key="$(grep '^DOWNLOADER_S3_ACCESS_KEY=' "${install_dir}/.env" | cut -d= -f2-)" +downloader_secret_key="$(grep '^DOWNLOADER_S3_SECRET_KEY=' "${install_dir}/.env" | cut -d= -f2-)" +remote_login_token="$(grep '^YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN=' "${install_dir}/.env" | cut -d= -f2-)" +[[ "$downloader_access_key" =~ ^GK[0-9a-f]{24}$ ]] +[[ "$downloader_secret_key" =~ ^[0-9a-f]{64}$ ]] +[[ "$remote_login_token" =~ ^[A-Za-z0-9_-]{64}$ ]] diff --git a/scripts/setup-stack.sh b/scripts/setup-stack.sh index a380388..43cbefb 100755 --- a/scripts/setup-stack.sh +++ b/scripts/setup-stack.sh @@ -27,17 +27,7 @@ PLACEHOLDER_YOUTUBE_REMOTE_LOGIN_INTERNAL_TOKEN="SET_ME_SHARED_SECRET" generate_hex() { local bytes="$1" - if command -v openssl >/dev/null 2>&1; then - openssl rand -hex "${bytes}" - return - fi - - python3 - "${bytes}" <<'PY' -import secrets -import sys - -print(secrets.token_hex(int(sys.argv[1]))) -PY + od -An -N "${bytes}" -tx1 /dev/urandom | tr -d '[:space:]' } generate_downloader_access_key() { @@ -61,20 +51,24 @@ ensure_generated_secrets() { fi } -require_free_port() { +port_is_listening() { local port="$1" - python3 - < 1 && toupper(substr($2, length($2) - 3)) == port && $4 == "0A" { found = 1; exit } + END { exit found ? 0 : 1 } + ' "${socket_tables[@]}" + return + fi + (exec 3<>"/dev/tcp/127.0.0.1/${port}") 2>/dev/null +} + +require_free_port() { + ! port_is_listening "$1" } set_env_var() { @@ -131,24 +125,17 @@ is_valid_port() { } find_random_free_port() { - python3 - <<'PY' -import random -import socket - -for _ in range(500): - port = random.randint(20000, 60999) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - s.bind(("0.0.0.0", port)) - except OSError: - continue - finally: - s.close() - print(port) - break -else: - raise SystemExit("no free port found") -PY + local attempt + local port + for ((attempt = 0; attempt < 500; attempt++)); do + port=$((20000 + (((RANDOM << 15) | RANDOM) % 41000))) + if require_free_port "${port}"; then + echo "${port}" + return + fi + done + echo "[setup] No free port found between 20000 and 60999." >&2 + return 1 } is_arm64_host() { From 624b5c74deb041ef71f32cc06d276d4c8354dd31 Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 18 Aug 2026 15:59:47 +0100 Subject: [PATCH 3/6] Update busybox image version to 1.38 for garage-config- #220 --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1fe6da2..a942f3d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -188,7 +188,7 @@ services: test: ["CMD", "redis-cli", "ping"] restart: unless-stopped garage-config: - image: busybox:1.37 + image: busybox:1.38 command: - /bin/sh - -ec From ad6858be47073df5cffb0f1482d8787194b16d1b Mon Sep 17 00:00:00 2001 From: Priveetee Date: Fri, 21 Aug 2026 12:11:07 +0200 Subject: [PATCH 4/6] chore: align beta Garage BusyBox image --- docker-compose.dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 25f78e5..8bed84d 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -149,7 +149,7 @@ services: restart: unless-stopped garage-config: - image: busybox:1.37 + image: busybox:1.38 command: - /bin/sh - -ec From f9b26fbeaa1e9e9d8f83990a8aba029673130099 Mon Sep 17 00:00:00 2001 From: Priveetee Date: Sat, 22 Aug 2026 11:27:53 +0200 Subject: [PATCH 5/6] docs: prepare TypeType 1.6.0 notes --- RELEASE_NOTES.md | 111 ++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 63 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ad886d3..f65e4d1 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,84 +1,69 @@ -# TypeType 1.5.0 +# TypeType 1.6.0 -TypeType 1.5.0 adds private RSS feeds, new-upload notifications and better -control over live content. It also closes a security issue in the public media -proxy and improves SABR playback during resumes and long-distance seeks. +TypeType 1.6.0 improves web playback, connected YouTube accounts, subscription feeds, downloads, authentication and notifications. -## RSS And Notifications - -- Add private RSS feeds for all subscriptions or a selected set of channels. -- Filter feeds by service and content type, with direct shortcuts from channel - pages. -- Regenerate, disable or delete feed links without affecting subscriptions. -- Show compact in-app notifications when subscribed channels publish new - videos. [#211](https://github.com/TypeType-Video/TypeType/issues/211) -- Give instance administrators control over RSS availability, public base URL, - account limits, polling intervals and request rate limits. +## Playback -RSS access is private to each account. Feed tokens can be revoked at any time -and do not expose the account session itself. +- Resume playback after returning to a suspended browser tab instead of stopping or restarting from the beginning. [#219](https://github.com/TypeType-Video/TypeType/issues/219) +- Stop replaying the current video when autoplay is disabled. [#224](https://github.com/TypeType-Video/TypeType/issues/224) +- Show the correct resolution and codec labels in the quality selector. [#227](https://github.com/TypeType-Video/TypeType/issues/227) +- Preserve the exact playback position when changing video quality instead of jumping backward. [#229](https://github.com/TypeType-Video/TypeType/issues/229) +- Preserve saved progress through MSE source transitions and expire stale cached positions before resume. +- Keep Safari playback transitions bounded when autoplay permission or user activation has expired. -## Subscriptions +## YouTube Accounts -- Add account settings to hide live streams, upcoming streams or both from the - subscription feed. [#213](https://github.com/TypeType-Video/TypeType/issues/213) -- Remove stale live entries after they stop being available from the provider. -- Normalize channel tab URLs before fetching and caching subscription pages. +- Preserve the selected connected YouTube account through SABR preparation, token refresh and playback recovery. +- Bind the YouTube player and media tokens to the same selected account. +- Guide content requiring authentication to the YouTube account connection flow. +- Add an option to hide members-only videos. [#225](https://github.com/TypeType-Video/TypeType/issues/225) -## Playback +## Subscription Feeds -- Restore saved playback positions reliably in Safari after SABR preparation. -- Preserve the requested position while a SABR session is being prepared or - recovered. -- Seek directly to distant positions before decoder preroll instead of replaying - unnecessary media. -- Preserve play and pause intent through seeks and quality changes. -- Update the web player to `@typetype/mse` 0.1.44. +- Correctly classify scheduled, active and finished live streams when applying the live visibility setting. [#213](https://github.com/TypeType-Video/TypeType/issues/213) +- Preserve the original ordering of scheduled live streams instead of continually promoting them. +- Remove finished or stale live entries from subscription feeds. -## Security +## Subscription Groups API -- Restrict the public media proxy to supported provider hosts and approved - media paths. -- Block private, loopback and local-network destinations, including redirect - and DNS resolution checks. -- Keep cross-provider redirects outside the proxy allowlist. -- Report YouTube remote-login readiness accurately instead of exposing an - unusable login flow. -- Update application and build dependencies across the released services. +- Add the complete Server contract for named subscription groups. [#172](https://github.com/TypeType-Video/TypeType/issues/172) +- Create, rename and delete groups. +- Assign a subscribed channel to multiple groups. +- Filter subscriptions and feeds by group or show ungrouped channels. +- Preserve stable pagination while group membership changes. +- Include groups and memberships in TypeType backups. -## Self-Hosting +**Subscription groups are API-only in this release. There is no web interface for creating or managing groups yet.** The frontend integration remains tracked in [#172](https://github.com/TypeType-Video/TypeType/issues/172). -No manual database migration is required. +## Accounts And Notifications -RSS is disabled by default. Instance administrators can enable it and configure -the public feed base URL from the documented environment settings. +- Fix initial OIDC installations requiring users to sign in twice. [#221](https://github.com/TypeType-Video/TypeType/issues/221) +- Add a setting to mute notification popups while keeping notifications available in the notification center. [#231](https://github.com/TypeType-Video/TypeType/issues/231) -The account session lifetime and insecure-cookie development settings are now -documented in English, French and Spanish. +## Downloads -## Known Limitations +- Allow downloads to work when Garage is only available through the internal TypeType network. A separate public Garage endpoint is no longer required. [#222](https://github.com/TypeType-Video/TypeType/issues/222) +- Keep artifact delivery behind the authenticated Server gateway. -- YouTube may still throttle subtitle retrieval with HTTP 429 on some egress - addresses. [#210](https://github.com/TypeType-Video/TypeType/issues/210) -- Native SABR playback on ARM64 remains under investigation. - [#204](https://github.com/TypeType-Video/TypeType/issues/204) +No configuration change or manual database migration is required. Server creates the subscription-group tables through its normal schema initialization. ## Thx -- A big thx to @LuckeeSoft for the RSS and notification ideas and for the - detailed feedback while the feature was taking shape. -- Thx to @CCGcastiel for proposing granular live-content controls for the - subscription feed. -- Thx to @Buage for privately and responsibly reporting the public proxy issue - before disclosure. [#212](https://github.com/TypeType-Video/TypeType/issues/212) -- Thx to @VitoItalianGamer for the detailed browser playback reports and the - time spent reproducing intermittent buffering behavior. -- A big thx to [@Toastienergy](https://github.com/Toastienergy) and - [@filippobaroni](https://github.com/filippobaroni) for supporting TypeType - through GitHub Sponsors. Their support helps me cover the infrastructure and - spend more time improving the project. -- Thx as well to everyone testing beta, sharing logs and helping other - self-hosters. +A huge thx to @kapdon for implementing the complete subscription-groups Server contract and for the careful work on pagination, backups and tests. + +Thx to @CCGcastiel for proposing the live-stream visibility controls and helping improve subscription feeds. + +Thx to @arcoast for reporting the OIDC first-login problem and the Garage download configuration issue. + +Thx to @mfuchsberger for reporting the autoplay loop and proposing the option to hide members-only content. + +Thx to @therealresonix for the detailed quality selector and playback-position reports. + +Thx to @Toni-Vide for proposing the notification mute setting. + +A special thx to my sponsors @Toastienergy and @filippobaroni for supporting TypeType. + +Thx as well to everyone testing the beta, reporting playback problems, sharing logs, improving the documentation and helping other self-hosters. ## Updating From 6f85e4f498b76472c85eafc61f23f86a20ca6dcc Mon Sep 17 00:00:00 2001 From: Priveetee Date: Sat, 22 Aug 2026 11:46:09 +0200 Subject: [PATCH 6/6] chore: point release at merged components --- TypeType-Downloader | 2 +- TypeType-Frontend | 2 +- TypeType-Player | 2 +- TypeType-Server | 2 +- TypeType-Token | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TypeType-Downloader b/TypeType-Downloader index 3fb485e..e27e618 160000 --- a/TypeType-Downloader +++ b/TypeType-Downloader @@ -1 +1 @@ -Subproject commit 3fb485eb9cc84905c8a3e66740e7ce15597c7afc +Subproject commit e27e61828ae5f80de736184f8eb39823b5acf9df diff --git a/TypeType-Frontend b/TypeType-Frontend index 1cd5839..d3c43fb 160000 --- a/TypeType-Frontend +++ b/TypeType-Frontend @@ -1 +1 @@ -Subproject commit 1cd58390ef9d6bb83a4a30a74848ded25de09846 +Subproject commit d3c43fba08f7116373bede6ad1f88091378022b2 diff --git a/TypeType-Player b/TypeType-Player index 1266d1a..6f07ef1 160000 --- a/TypeType-Player +++ b/TypeType-Player @@ -1 +1 @@ -Subproject commit 1266d1a776964f819a2eca7db00142a5f9ba1419 +Subproject commit 6f07ef18401f1df5a094c720007f7f5e81c25e7e diff --git a/TypeType-Server b/TypeType-Server index e1b9e04..4717181 160000 --- a/TypeType-Server +++ b/TypeType-Server @@ -1 +1 @@ -Subproject commit e1b9e04de73c68e501e1899ba66b284a600adb71 +Subproject commit 471718143ea6f42dffe626b340fe74dc4c6522e9 diff --git a/TypeType-Token b/TypeType-Token index b49fc94..ea097dd 160000 --- a/TypeType-Token +++ b/TypeType-Token @@ -1 +1 @@ -Subproject commit b49fc9425a0ca1f2ebe02dca6040a8c5820575fa +Subproject commit ea097dd36e43e2ea6a6b3ab84cba49807804f88a