feat: browser-native client — wire SPA to the SDK, delete the Go gateway
Phase 2 of issue 0001. uniweb becomes a pure frontend (web/ only), like unibus_android: the SPA talks directly to the bus and the Go gateway is gone. - busService.ts: the new data layer over the bus SDK, replacing the old api module. It holds the user's wallet identity and a connected BusClient IN THE BROWSER and opens the session locally — the private key is never sent anywhere (closes the gateway-era hole where the browser POSTed its private key to /api/session). - Wire account/App/ChatShell/ChatPanel/WalletLogin/Recover/Join to busService; subscribeRoom replaces the SSE streamRoom; ApiError -> SessionError. - SDK: ControlPlane.createRoom + listMemberRooms, and fetchRoom mapped to the real control-plane wire shape (snake_case, no id) — all verified by the live round-trip. - Delete cmd/webgw, go.mod, go.sum, src/api.ts and the orphan operator Login. uniweb now has zero Go and no dependency on unibus as a module. - vite: drop the /api proxy, dev server on 5173 to match the bus CORS allowlist; add vite-env typings. app.md: lang ts, no uses_functions, e2e_checks are now web-only. Bump 0.3.0. Onboarding by token is now admin-side (the bus has no self-register endpoint; the gateway only mocked it). tsc + pnpm build + 19/19 unit green.
This commit is contained in:
+13
-6
@@ -21,7 +21,7 @@ import {
|
||||
IconKey,
|
||||
IconShieldLock,
|
||||
} from "@tabler/icons-react";
|
||||
import { api, ApiError } from "./api";
|
||||
import { SessionError } from "./busService";
|
||||
import { AuthCard, AuthHeader } from "./AuthShell";
|
||||
import type { User } from "./types";
|
||||
import { newMnemonic, mnemonicWords } from "./wallet/bip39";
|
||||
@@ -124,14 +124,21 @@ export function Join({
|
||||
setStep("joining");
|
||||
setError(null);
|
||||
try {
|
||||
// Register the PUBLIC identity with the bus (token authorizes), then
|
||||
// encrypt the private key locally and open the per-user session.
|
||||
const res = await api.register(token, identity.signPub, identity.kexPub);
|
||||
const user = await saveAndOpen(identity, res.handle, password);
|
||||
// The bus has no token-register endpoint (that was a gateway mock): a
|
||||
// browser cannot self-register on an enforce cluster. The identity must be
|
||||
// allow-listed by an admin first. We persist it locally and try to open the
|
||||
// session; if the identity is not yet authorized, openSession fails and we
|
||||
// tell the user to have an admin authorize their public key.
|
||||
const handle = identity.signPub.slice(0, 8);
|
||||
const user = await saveAndOpen(identity, handle, password);
|
||||
onJoined(user);
|
||||
} catch (e) {
|
||||
const base =
|
||||
e instanceof SessionError || e instanceof Error
|
||||
? e.message
|
||||
: "No se pudo completar el alta.";
|
||||
setError(
|
||||
e instanceof ApiError ? e.message : "No se pudo completar el alta.",
|
||||
`${base}. Pide a un administrador que autorice tu clave pública: ${identity.signPub}`,
|
||||
);
|
||||
setStep("password");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user