Skip to content

Next Version - #471

Open
SciLor wants to merge 33 commits into
masterfrom
develop
Open

SciLor wants to merge 33 commits into
masterfrom
develop

Conversation

@SciLor

@SciLor SciLor commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

No description provided.

aflores-qb and others added 30 commits June 21, 2026 11:45
The aarch64 Docker images were built and tested under QEMU-user
emulation, where the ASan-instrumented binary aborts at startup
(CHECK failed: sanitizer_allocator_primary64.h) because QEMU's
emulated address space cannot host libasan's fixed 64-bit allocator
region. ASan was therefore disabled on arm64 via NO_SANITIZERS=2.

Run the arm64 build/test on native ubuntu-24.04-arm runners instead
of under QEMU, where ASan initialises normally, and drop arm64 from
noasan_fallback_platforms so it builds with ASan again (ubuntu+debian).

- publish_docker_matrix_base.yml: route linux/arm64/v8 to a native
  ubuntu-24.04-arm runner; skip the multiarch/qemu-user-static binfmt
  registration on that native runner (it is amd64-only and fails with
  "Exec format error" there, and is unneeded since arm64 containers run
  natively); lower vm.mmap_rnd_bits to 28 before the arm64 test as cheap
  CI-only insurance for older base-image libasan.
- publish_docker_matrix_all.yml: remove linux/arm64/v8 from
  noasan_fallback_platforms (ubuntu, debian); narrow the AsanTest
  canaries to the platforms still under QEMU (armv7, ppc64le).
- Makefile: drop the dead -DSANITIZER_CAN_USE_ALLOCATOR64=0 blocks
  (the define only affects libasan's own build, not the application)
  and document the real cause and fix.
Adds a minimal, standalone "listened" flag for library files, kept
deliberately separate from contentJson_t (which describes a Tonie
tag's content assignment - source, live, cache, cloud auth, ... -
none of which applies to a plain library audio file):

- New GET field "listened" on /api/fileIndexV2 for library entries.
- New POST /api/fileSetListened to toggle it for an arbitrary file.
- Sidecar (<file>.json) reads/writes preserve any existing foreign
  keys already in the file (e.g. from the "migrate to library"
  feature) instead of overwriting them.
- New "cloud.autoMarkListenedOnSync" setting (on by default): marks
  a library-sourced tag's file as listened once a Toniebox actually
  downloads/plays it locally.
- Fixes a pre-existing duplicate-key bug in fileIndexV2's directory
  listing branch (the "hide" field was being added once per scanned
  subentry instead of once per directory).
- Orphaned sidecars (whose original file was deleted, e.g. by cache
  eviction) are intentionally left visible in listings rather than
  hidden, so they can be spotted and cleaned up manually.

Pairs with the corresponding frontend changes in teddycloud_web
(feature/listened branch).
…ative-runner

Re-enable AddressSanitizer on aarch64 via native arm64 runners
Protects only the web interface (off by default), stores salted password hashes, and leaves Toniebox APIs unchanged.
httpSendResponseStreamUnsafe() serves a stream file while the encoder task is
still appending to it. Once the reader catches up, fread() sets the stdio EOF
indicator, and that indicator is sticky: every later fread() on the same FILE
returns 0 without going to the fd again. The retry path in the send loop
therefore spins in osDelayTask() forever and never sends another byte,
although the file keeps growing.

Seek to the current position before retrying, which clears the indicator. The
taf_chapter_split path was unaffected because it already seeks on every
iteration.
With encode.ffmpeg_stream_restart enabled, a range request on a stream is
answered with the real file size instead of stream_max_size, so the box
discards its cached prefix and requests the stream again from offset 0.

teddyCloud started the encoder for that request anyway and waited for the
sweep and prebuffer delays before answering, so every restart ran the full
startup sequence twice and threw the first run away.

Skip the encoder for that request and answer immediately.

Fixes #407
- rename auth user routes to users/get, users/create, users/delete, users/updatePassword
- drop the route ordering comment
- README: recovery hint and warning against public exposure

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The streaming pipeline was only documented by the one-line setting
descriptions the web UI shows. Nothing explained how they interact, why
playback is not live, or why a returning tag replays cached audio.

Add docs/webradio-streaming.md covering the pipeline, the constraints the
box imposes on it, the encode.* settings and where startup latency comes
from.
fix: keep serving stream files past the first EOF
…coder-on-restart

perf: skip encoding for range requests that force a box restart
Runs a program with an argv array (no shell), so callers don't need to
build and escape a command-line string. Mirrors the existing osPopen
per-platform split: fork/execvp/waitpid on POSIX, _spawnvp on Windows.

Intended for #484 (export TAF tracks), which currently builds a `zip`
command as a hand-escaped shell string.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…arness

Moves the existing Python integration tests into tests/py/ and extracts
the start-server/wait-ready/stop-server logic (duplicated once already
between test_api_custom_json_with_server and #477's auth test) into
tests/py/with_server.sh, shared by any test needing a running server.

Adds tests/c/ for pure C unit tests that don't need a server: a small
assert()-based runner plus a first real test for osSpawnvp. `make test`
runs both suites; `make test_c` runs just the C side.

Documents the layout in docs/architecture.md and CONTRIBUTING.md.
feat: track listened status for library files
CC3235 uses the Boxine CA and v1 API like CC3200/ESP32, so it must
be GENERATION_TB1, not TB2.

Fixes #483
feat: add optional web UI login with cookie sessions
cert_load_ca allocated the CA certificate DER and never freed it, so every RSA certificate signed against the CA leaked it. It also leaked on each error path. Sanitizer builds report this and exit non-zero after --generate-client-cert, even though the certificate is written.
connection->private.authenticated is set true when a client
certificate authenticates a request, but httpServerRequestCallback
never resets it to false. Connection objects come from a static
32-slot pool (HTTP_SERVER_MAX_CONNECTIONS) handed out from index 0,
so a slot that last served a certificate-authenticated request stays
authenticated=true for whichever unrelated client's connection gets
that slot next - skipping client-certificate verification entirely
at the api_access_only + boxCertAuth gate.

Reset it alongside api_access_only, the other per-request field this
callback already refreshes, so every request starts from a clean
slate before the certificate block re-establishes it if warranted.
fix(server): clear authenticated on every pooled connection reuse
The web UI session token (64 hex chars) matched the length of the
never-finished JWT stub in httpParseAuthorizationField, which then
parsed from the wrong offset (3 instead of 7) and logged a WARN with
the full token on every request. The stub never succeeded, so drop it;
the bearer token is only stored for validation by the web auth handlers.

Fixes #485

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The HTTP parser rewrites "/" to the default document "index.shtm"
(without leading slash) before the request callback runs, so the
public-route check never matched and the root URL answered 401
"Login required" instead of redirecting to /web.

Fixes toniebox-reverse-engineering/teddycloud_web#333

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(server): stop logging web UI bearer tokens as parse failures
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.

5 participants