Commit Graph

6 Commits

Author SHA1 Message Date
Alexa f0e4679887 feat(auth): external sign-in for the website and admin panel
Players sign in to the website, and admins to the admin panel, with an
OpenID Connect provider (DorkNet:SignIn:*). The first sign-in links the
provider identity (issuer + subject) to a DorkNet account with that
account's password; after that the provider sign-in is enough.

- Cookie sessions per host, keys persisted in the database so redeploys
  keep people signed in; unlink, deletion or a ban ends the session.
- Link attempts limited to 5 failures per 15 minutes per identity and
  per username.
- Admin panel: "Sign in with ..." exchanges the session for the usual
  admin tokens via GET /api/admin/v1/sso (IsAdmin still required).
- Downloads: optional DorkNet:Downloads:RequireSignIn serves the
  manifest and files only to signed-in players; the Downloads and Quest
  pages offer sign-in instead.
- Website: sign-in in the header, /link and /account pages.

The game client's login is unchanged.
2026-10-25 15:47:56 +02:00
Alexa cc7f77b7de feat(site): Downloads page and Quest install from the latest build
When the server is pointed at the bucket CI publishes builds to
(DorkNet:Downloads:BaseUrl), the site lists them on a new Downloads page and
the Quest page offers "Latest build" next to "Choose file".

The server reads manifest.json and the files over HTTP on the internal network
and streams them through with Range support (DownloadsController); only files
the manifest lists are served. The xapk reader now reads from a byte source,
either the picked File or the server URL via Range requests, so the browser
installer streams the APK and OBB to the headset without downloading the
package first. Unset, both features stay hidden.
2026-10-25 10:55:43 +02:00
Alexa a7879d7ede feat: install the Quest build from the website
A Quest page on the public site (/quest) installs a DorkNet .xapk from
Chrome or Edge over WebUSB, with no adb, SideQuest or scripts: pick the
.xapk, connect the headset, install. It installs the APK, copies the OBB
to its install path (skipped when an identical one is already there) and
launches the app, with progress bars and plain-language errors for an
unsupported browser, a headset held by adb/SideQuest, a disconnect and a
copy signed with a different key.

The .xapk is read from the player's own disk: the APK and OBB are stored
uncompressed, so they stream straight out of the file without loading
1.4 GB into memory, and the server never hosts game files.

Uses Tango (@yume-chan/adb 2.6.4 and friends, MIT), pinned and bundled;
the page is lazy-loaded so the rest of the site doesn't grow. Credited in
NOTICE; README, DorkNet.Quest/README.md, docs/quest.md and the packaged
README.txt point players at the page.
2026-10-15 22:34:25 +03:00
Alexa bb04782e11 chore(deps): clear Dependabot alerts — React 19, react-router 8, Vite 7
Bumps both frontend apps (site, admin-ui):
- vite 5.4 -> 7.3.6 (pulls esbuild 0.28, patched dev-server CVEs)
- @vitejs/plugin-react 4 -> 5 (babel 7.29.7)
- postcss 8.4 -> 8.5.25
- react-router-dom 6.27 -> react-router 8.3.0 (package renamed
  upstream in v8; imports swapped in src). Fixes the open-redirect
  advisories with no patched 6.x, plus the RSC CSRF advisory
  (GHSA-qwww-vcr4-c8h2) that only 8.3.0 patches.
- react/react-dom 18.3 -> 19.2 (required by react-router 8)

npm audit: 0 vulnerabilities in both apps. tsc + vite build clean.
2026-08-02 00:57:34 +03:00
Alexa 3480ca21fa signup codes: admin-issued invite codes + site /join redemption
While account creation is disabled, the only way in is now an
admin-issued single-use signup code (Discord-invite style), redeemed on
the public site's /join page.

Because the 2020 watch login is device-id-bound with no code field, the
flow captures it server-side instead: a new device refused at the
signups-disabled gate (PlatformLogin / account create) is stashed in a
PendingDevices table keyed by the real client IP (CF-Connecting-IP aware).
The /join page then shows the player the device their own client just
reported, they enter their code + username, and the account is minted
bound to that device — so the next launch logs straight in via the
existing device-id path. No watch changes.

- SignupCodeEntity (code, descriptor, optional expiry, redeemer) +
  PendingDeviceEntity; idempotent CREATE TABLE in DatabaseBootstrap so
  both providers pick them up without a new migration.
- SignupCodeService: generate / list / revoke / redeem + pending-device
  capture, single-use + expiry + revoke validation.
- Admin: GET/POST signup-codes + revoke endpoints and a Signup codes
  admin-ui page (generate with descriptor/expiry, status table, revoke).
- Public: anonymous /api/site/v1/join pending-devices + redeem, and a
  /join site page (+ header link).
- README documents the flow + the post-Initial table-create approach.
2026-05-31 20:00:35 +03:00
Alexa 4edf25b2d5 Import december-2020-12-18 from private repo (scrubbed 2026-05-27)
Targets Rec Room 2020.12.18 client.

Re-import after adding:
- DorkNet.ClientMod/dorknet-clientmod.json.template — config schema
  the launcher's manifest-driven patcher renders into UserData/.
- tools/build-patcher-zip.ps1 — produces the dorknet-clientpatch-{key}.zip
  Release asset the launcher fetches.
- .github/workflows/release.yml — auto-publishes both Release assets
  on v1-december-* tag push.

Scrubbed via maintainer-side scrub-for-public.ps1: same drop rules as
the prior import, plus build-patcher-zip.ps1 added to the tools/
allow-list so it survives the scrub.
2026-05-27 01:04:12 +03:00