Add account admission tickets and nickname feedback for launcher 0.1.2
This commit is contained in:
+106
-10
@@ -5,9 +5,18 @@
|
||||
The launcher persists local settings, synchronises Aeronautics mod/config
|
||||
files from the signed ShaCraft v2 manifest, installs the exact Minecraft +
|
||||
NeoForge version the manifest specifies, and launches the game. A player
|
||||
signs in with the same local ShaCraft account used on the website. The game
|
||||
identity is derived only from that account's verified Aeronautics nickname;
|
||||
the legacy editable nickname setting is not trusted at launch.
|
||||
signs in with the same local ShaCraft account used on the website. The current
|
||||
admission implementation claims a free nickname for that account and requests
|
||||
a one-use permission immediately before launching Java. The game identity
|
||||
comes only from the canonical Aeronautics nickname in that permission; the
|
||||
legacy editable nickname setting is not trusted at launch.
|
||||
|
||||
The backend and admission mod were deployed to Aeronautics on 2026-09-10;
|
||||
the server is healthy with whitelist enforcement retained. Real isolated
|
||||
NeoForge connections verified successful admission, absent/replayed proof
|
||||
rejection and protection of an online player from duplicate login. A public
|
||||
production connection without the mod was rejected before world entry.
|
||||
This does not certify a full cold installation or Windows/macOS operation.
|
||||
|
||||
The interface also shows a live Aeronautics player count from the fixed,
|
||||
read-only `https://shacraft.ru/api/online/aoc` endpoint. It is display-only:
|
||||
@@ -19,7 +28,7 @@ launcher itself. Do not represent these as completed in UI or release notes.
|
||||
|
||||
## Data flow
|
||||
|
||||
Two independent pipelines feed one launch:
|
||||
Managed files, game installation and account admission meet at Java spawn:
|
||||
|
||||
```text
|
||||
ShaCraft manifest (mods/config + which MC/loader/Java version to use)
|
||||
@@ -33,9 +42,14 @@ Game itself (never controlled by the manifest above)
|
||||
-> NeoForge's own installer, run headlessly (neoforge.rs)
|
||||
-> generic inheritsFrom merge of the two version JSONs (mojang.rs)
|
||||
-> SHA-1-verified merged libraries + platform natives (mojang.rs)
|
||||
-> verified ShaCraft account link (shacraft_account.rs)
|
||||
-> deterministic offline UUID for the linked nickname (session.rs)
|
||||
-> java process spawned with the merged classpath/args (launch.rs)
|
||||
|
||||
Admission (fixed ShaCraft account API; never controlled by a manifest)
|
||||
native website session -> direct free-nickname claim or admin migration
|
||||
-> after installation: OS CSPRNG -> ephemeral Ed25519 key (admission.rs)
|
||||
-> public key + bearer session -> one-use ticket for canonical aoc nickname
|
||||
-> deterministic offline UUID for that nickname (session.rs)
|
||||
-> Java with merged classpath/args + child-only ticket/private-key environment
|
||||
-> client mod signs server challenge; server validates before world entry
|
||||
```
|
||||
|
||||
Profiles (ShaCraft-managed mods/config, and the player's own worlds/
|
||||
@@ -45,7 +59,8 @@ install (versions/libraries/assets/runtime, reused across profiles that
|
||||
target the same Minecraft version) lives at `app_data_dir()/game`. Settings
|
||||
live at `app_data_dir()/settings.json`, and the revocable ShaCraft session at
|
||||
`app_data_dir()/shacraft-session` (mode 600 on Unix). Passwords are never
|
||||
written to disk. None of these should be assumed to
|
||||
written to disk. The admission private key and ticket are ephemeral native
|
||||
values and are not persisted. None of these directories should be assumed to
|
||||
be the system `.minecraft` directory.
|
||||
|
||||
## Aeronautics contract
|
||||
@@ -60,8 +75,68 @@ be the system `.minecraft` directory.
|
||||
- ShaCraft download files: HTTPS only, exact hosts `shacraft.ru` and
|
||||
`cdn.shacraft.ru`.
|
||||
- Account API origin: fixed `https://shacraft.ru`; redirects are rejected.
|
||||
- Launch identity: the most recently verified `aoc` nickname returned by the
|
||||
authenticated account API. Local nickname edits cannot select an identity.
|
||||
- Launch identity: the canonical `aoc` nickname returned with the admission
|
||||
ticket. Local nickname edits cannot select an identity.
|
||||
|
||||
## Admission contract (implementation: 2026-09-10)
|
||||
|
||||
Both endpoints use the fixed account API origin, HTTPS without redirects and
|
||||
the native website session as bearer authentication. The session is never
|
||||
passed to the client mod or Java process.
|
||||
|
||||
`POST /api/launcher/v2/admission/nickname` accepts
|
||||
`{server_id: "aoc", mc_username: "Chosen_Name"}` and returns the existing
|
||||
account shape `{username, links}`. The backend atomically assigns a free name
|
||||
to that account. Existing player names remain reserved and require explicit
|
||||
administrator migration. The launcher no longer asks the player to enter the
|
||||
game to complete this claim. Legacy challenge IPC remains available to older
|
||||
flows, but an admission-enabled backend must block those legacy endpoints
|
||||
from bypassing reserved-name ownership.
|
||||
|
||||
After installation completes, the native launcher generates a fresh Ed25519
|
||||
key using the OS CSPRNG and calls
|
||||
`POST /api/launcher/v2/admission/tickets` with
|
||||
`{server_id: "aoc", public_key: "<standard base64 raw 32-byte public key>"}`.
|
||||
The response is `{ticket_id, mc_username, server_id, expires_in_seconds}`.
|
||||
The native boundary requires a canonical 43-character base64url ticket ID,
|
||||
an ASCII Minecraft nickname of 3–16 letters/digits/underscores, server `aoc`
|
||||
and a positive lifetime of at most 600 seconds. The backend checks the current
|
||||
account session, bound nickname and server access before issuing it.
|
||||
|
||||
`admission.rs` has no secret-bearing `Debug` or `Serialize` implementation.
|
||||
Only the final Java child's environment receives:
|
||||
|
||||
- `SHACRAFT_ADMISSION_TICKET`: the one-use ticket ID.
|
||||
- `SHACRAFT_ADMISSION_PRIVATE_KEY`: standard base64 of the Ed25519 PKCS#8
|
||||
private-key-only DER representation accepted by Java's `KeyFactory`.
|
||||
|
||||
No global environment mutation, webview/IPC payload, argument substitution,
|
||||
JVM argfile, settings file or log stores these values. The account operation
|
||||
permit remains held from issuance through spawn so local account switching
|
||||
or logout cannot race the handoff. Missing, disabled or invalid admission
|
||||
responses fail the launch with a visible error; there is no legacy-name or
|
||||
unsigned fallback. In this first version, a consumed or expired ticket needs
|
||||
a fresh game launch from the launcher; transparent in-game reconnect is not
|
||||
implemented.
|
||||
|
||||
The client mod proves possession of the ephemeral private key by signing the
|
||||
server's challenge. The server mod gates world entry on successful backend
|
||||
verification, including one-use consumption and current account/link/access
|
||||
checks. Whitelist enforcement is retained. The 2026-09-10 Aeronautics rollout
|
||||
replaced its separate LoginSystem `/register` and `/login` flow; other servers
|
||||
keep their existing authentication. Old launchers without admission proof
|
||||
cannot join Aeronautics. A required server-only Mixin rejects a duplicate
|
||||
online UUID before vanilla can disconnect the existing player. The client pins
|
||||
the actual game socket to `135.106.154.86:25567`; changing that address requires
|
||||
an explicit mod update. Server source and rollout records live in
|
||||
`/root/shacraft/services/admission-mod` and `docs/admission-2026-09-10.md` on
|
||||
the ShaCraft host.
|
||||
|
||||
This protocol prevents entry without the account's current permission. It
|
||||
does not attest that an original launcher or game binary is unmodified:
|
||||
software running as the same user can read its own process environment, and
|
||||
a compatible client can implement the protocol. Never replace account-bound
|
||||
proof with a shared key embedded in distributed binaries.
|
||||
|
||||
## Planned but not implemented
|
||||
|
||||
@@ -72,6 +147,8 @@ be the system `.minecraft` directory.
|
||||
4. Cancellation, structured logs and a full cold-install/recovery beta on
|
||||
every target OS. Install progress reports bytes or installer work counts
|
||||
depending on the stage; these units are not interchangeable.
|
||||
5. Transparent reconnect after the admission ticket has been consumed or
|
||||
expired. The current implementation requires a new launch.
|
||||
|
||||
Do not represent these as completed features in UI or release notes.
|
||||
|
||||
@@ -105,3 +182,22 @@ The package workflow runs on main pushes or manually and builds Windows
|
||||
x64, Linux x64 and both macOS architectures with named artifacts.
|
||||
Packages are not yet signed release artifacts. Native cold-install and
|
||||
launch tests are required before calling a platform release-ready.
|
||||
|
||||
The local admission checkpoint passed 64 Rust tests (5 live tests ignored),
|
||||
22 UI unit tests, TypeScript/Vite build and a Linux x86-64 release build with
|
||||
`npm run tauri:build -- --no-bundle`. Six browser scenarios with mocked Tauri
|
||||
IPC covered invalid nicknames, deleted sessions, reserved-name errors,
|
||||
successful claims, duplicate clicks and a session revoked during a claim.
|
||||
They also checked modal feedback, Escape preserving the settings drawer and
|
||||
the absence of legacy link polling. These checks used no production account
|
||||
or real Minecraft connection. The Linux output is a dynamically linked
|
||||
binary, not evidence of Windows/macOS support testing.
|
||||
|
||||
Version 0.1.2 also produced unsigned Linux amd64 AppImage and deb packages with
|
||||
`npm run tauri:build -- --bundles appimage,deb`. AppImage extraction and the
|
||||
deb's version/architecture metadata were checked without running the app or
|
||||
installing the package. The build host was Ubuntu 26.04; do not claim support
|
||||
for older Ubuntu releases from this build. For local AppImage packaging,
|
||||
linuxdeploy's GTK plugin needs `librsvg-2.0.pc` from the matching `librsvg2-dev`
|
||||
package. Extracting that package into a temporary build directory and setting
|
||||
`PKG_CONFIG_PATH` supplied the missing metadata without changing host packages.
|
||||
|
||||
Reference in New Issue
Block a user