Record direct transfer coverage, fallback paths and verification results
This commit is contained in:
@@ -63,7 +63,91 @@ into OPFS through WebRTC and assert that server HTTP/WS logs contain only
|
|||||||
signalling and metadata. Exercise interruption/resume and explicit fallback.
|
signalling and metadata. Exercise interruption/resume and explicit fallback.
|
||||||
Review real iPhone foreground/background behaviour and restrictive NAT failure.
|
Review real iPhone foreground/background behaviour and restrictive NAT failure.
|
||||||
|
|
||||||
## Implementation status
|
## Implemented behaviour
|
||||||
|
|
||||||
This document records the pre-implementation audit and design. Transport,
|
- `direct-protocol.js` strips unexpected fields and validates file claims and
|
||||||
authorization and UI changes described above are not yet implemented.
|
bounded signalling; `direct-relay.js` binds invitations to authenticated room
|
||||||
|
members. Accepting an invitation is one-use, and only the bound pair can signal.
|
||||||
|
- Remote, presenter and party relays carry the new protocol. Presenter and OBS
|
||||||
|
still display lyrics/control metadata; they do not automatically play media.
|
||||||
|
A presenter can explicitly accept a file sent by its paired host.
|
||||||
|
- Settings → Direct device transfer provides the default-on toggle and send
|
||||||
|
buttons for currently connected paired/party/profile peers. Send the currently
|
||||||
|
playing **saved** song; the receiving device confirms every copy.
|
||||||
|
- The paired remote has “Play here from paired screen” when its host has saved
|
||||||
|
media. Party guests and ordinary playback resolve an advertised direct source
|
||||||
|
before loading media. Saves and exports do the same; the existing OS export
|
||||||
|
sheet is preserved.
|
||||||
|
- `/ws/p2p` now has a profile-scoped, ephemeral file-id directory. Protected
|
||||||
|
profiles require password/key proof, checked against the server profile hash.
|
||||||
|
Unprotected profiles retain their existing name-based access policy. Claims
|
||||||
|
are **not** admitted as server-verified media. Each device advertises at most
|
||||||
|
1,000 local ids per directory update; use paired-room sending for larger libraries.
|
||||||
|
- The legacy unconfirmed global signalling path is refused. Older clients need
|
||||||
|
to reload the updated application to transfer files. This closes a bypass of
|
||||||
|
receiver confirmation and room/profile membership.
|
||||||
|
- `direct-media.js` uses public STUN, ordered 64 KiB DataChannel chunks and
|
||||||
|
bufferedAmount backpressure. `direct-recv-worker.js` writes partials directly
|
||||||
|
to OPFS, rehashes their retained prefix and verifies exact size plus SHA-256
|
||||||
|
before promotion. File extensions are preserved. A disconnected partial can
|
||||||
|
be resumed by sending/requesting the same file again, including non-aligned offsets.
|
||||||
|
- The 10-second deadline covers connection establishment. Prefix rehashing and
|
||||||
|
final verification do not consume it. Idle transfer timeout is 30 seconds.
|
||||||
|
Failures retain partial data and offer an explicit **Use server copy** action.
|
||||||
|
Automatic holder-to-server rehydration is blocked while direct mode is on;
|
||||||
|
**Verify & share** remains an intentional, explicit server upload.
|
||||||
|
- `direct-stream.js` supports progressive preview for compatible fragmented
|
||||||
|
H.264 MP4 through MediaSource. Ordinary faststart MP4, unsupported codecs,
|
||||||
|
unavailable MediaSource and preview buffer exhaustion use the complete file.
|
||||||
|
iPhone playback should be reviewed using that completed-file path. A preview
|
||||||
|
is interactive and independent of the main player's host clock; main party
|
||||||
|
playback follows the host after the verified copy is ready.
|
||||||
|
|
||||||
|
## Paths that still use server media
|
||||||
|
|
||||||
|
Original YouTube acquisition, server uploads, intentional Verify & share intake,
|
||||||
|
external VLC/M3U HTTP URLs and explicitly accepted server fallbacks still use the
|
||||||
|
server. If no connected device advertises a local copy, normal original-source
|
||||||
|
playback/download is preserved; this is not a transfer of another device's file.
|
||||||
|
Profile/playlist shares, chapters, lyrics, presenter state and OBS state remain
|
||||||
|
metadata/control only. Direct discovery requires an online paired room or an
|
||||||
|
existing profile, and the browser must remain available to serve its OPFS file.
|
||||||
|
No TURN service, deployment change or secret configuration is required.
|
||||||
|
|
||||||
|
## Checks and reviewer follow-up
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
node --test frontend/*.test.js
|
||||||
|
node --check frontend/app.js
|
||||||
|
bun build --no-bundle server/server.js
|
||||||
|
bun test server/direct-relay.test.js server/p2p-hub.test.js server/remote.test.js server/party.test.js
|
||||||
|
npx playwright test -c playwright.direct.config.js
|
||||||
|
npx playwright test -c playwright.glass-navigation.config.js
|
||||||
|
```
|
||||||
|
|
||||||
|
The two-page localhost test uses the production relay and transport, separate
|
||||||
|
browser stores, a real RTCDataChannel and actual OPFS writes. It resumes a 2 MB
|
||||||
|
file at byte 12,345, verifies the resulting SHA-256 and asserts that the server
|
||||||
|
log contains only invitation/acceptance/signalling/completion. A second case
|
||||||
|
adds 12 seconds of resume preparation to prove it is outside the 10-second
|
||||||
|
connection deadline. This is a local transport proof, not proof that arbitrary
|
||||||
|
NATs will connect.
|
||||||
|
|
||||||
|
Check real iPhone foreground/background suspension, large-file quota and final
|
||||||
|
promotion, iOS completed-file playback, restrictive/symmetric NAT fallback,
|
||||||
|
paired screen playback, party host changes during a copy, protected-profile
|
||||||
|
credential changes/reconnect, OS export gestures, and an actual fragmented MP4
|
||||||
|
MediaSource preview on desktop. Public STUN cannot overcome every NAT; declined
|
||||||
|
invitations do not start media acquisition. Peer directories update when the
|
||||||
|
presence socket connects and when local saves complete, rather than promising
|
||||||
|
availability of offline/backgrounded devices.
|
||||||
|
|
||||||
|
Final verification on 2026-10-03: 123 frontend unit tests, 22 touched server
|
||||||
|
tests (including remote and party), app syntax and server build, 8 Glass/Classic
|
||||||
|
navigation browser tests at 390/1440 px, and both direct-transfer browser cases
|
||||||
|
passed. The first navigation run lost its reused localhost server; a fresh-server
|
||||||
|
rerun passed all eight cases without a code change. Classic screenshot comparisons
|
||||||
|
remain within the test's rasterization tolerance. No real iPhone or restrictive
|
||||||
|
NAT test was performed here, and no code was pushed or deployed.
|
||||||
|
|||||||
Reference in New Issue
Block a user