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.
|
||||
Review real iPhone foreground/background behaviour and restrictive NAT failure.
|
||||
|
||||
## Implementation status
|
||||
## Implemented behaviour
|
||||
|
||||
This document records the pre-implementation audit and design. Transport,
|
||||
authorization and UI changes described above are not yet implemented.
|
||||
- `direct-protocol.js` strips unexpected fields and validates file claims and
|
||||
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