feat(auth)+refactor(app): identifier at the access barrier; adopt the lib fidelity refactor
Consumer-side of the @ng-eventually/client fidelity pass, plus the identifier UX: - Identity: the user types an IDENTIFIER at the access barrier (AccessGateScreen), in the same act that opens the shared wallet — the separate 'pick a username' screen (ConnexionScreen) is removed. The identifier is a technical id (a pseudo in practice, not a Festipod username), normalized (trim, @-stripped, lowercased) and persisted before the broker redirect, then handed to the SDK as the identity. AccountContext keeps its API but its stored value is now this normalized id. - Relationship/connections are app-owned: new src/shared/utils/connections.ts holds the bilateral registry and maps each link to the SDK's directed grantRead(doc, grantee); the lib no longer carries a connection concept. Rewired FestipodData and the @data harness to it. - Login removed: accounts use the SDK's IdentityStore (set/clear/get); no faux login/logout framing in the SDK boundary. Doctrine reconciled: app-security (knowledge_authentication flow, knowledge_trust-model directed grants, decision_2026-07-06_identifier-at-access-barrier), data-layer (knowledge_context-internals: stable id principal + single-seed), app-architecture (knowledge_screens auth inventory), bdd-testing (caveat_wallet-bloat-hang). App gates: tsc no new errors, build OK. @data path unaffected (harness bypasses the gate and sets identity directly; login() is not on that path). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+16
-15
@@ -1,9 +1,10 @@
|
||||
/**
|
||||
* AuthGate — the stopgap access flow (see decision_2026-06-15_shared-wallet-login-flow):
|
||||
* 1. Technical access barrier (AccessGateScreen) → opens the SHARED wallet via
|
||||
* the broker redirect (with the wallet file + guide it hands the user).
|
||||
* 2. Perceived app login (ConnexionScreen) → pick a username.
|
||||
* 3. The app.
|
||||
* 1. Access barrier + identifier (AccessGateScreen) → the user names their
|
||||
* virtual space (an identifier) and opens the SHARED wallet via the broker
|
||||
* redirect (with the wallet file + guide it hands the user). Naming the
|
||||
* space and opening it are ONE act.
|
||||
* 2. The app.
|
||||
*
|
||||
* The gate is ON BY DEFAULT (Festipod never functions without NextGraph). It is
|
||||
* disabled only when `globalThis.__FESTIPOD_ACCESS_GATE_DISABLED__ === true` —
|
||||
@@ -16,7 +17,6 @@ import type { ReactNode } from 'react';
|
||||
import { useNextGraph } from '../shared/context/NextGraphContext';
|
||||
import { useAccount } from '../shared/context/AccountContext';
|
||||
import { AccessGateScreen } from '../modules/auth/screens/AccessGateScreen';
|
||||
import { ConnexionScreen } from '../modules/auth/screens/ConnexionScreen';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
@@ -26,23 +26,24 @@ const GATE_DISABLED = globalThis.__FESTIPOD_ACCESS_GATE_DISABLED__ === true;
|
||||
|
||||
export function AuthGate({ children }: { children: ReactNode }) {
|
||||
const { status, error, connect } = useNextGraph();
|
||||
const { username } = useAccount();
|
||||
const { username, login } = useAccount();
|
||||
|
||||
// Gate explicitly disabled (no-gate build / @e2e harness) → straight to app.
|
||||
if (GATE_DISABLED) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
// 1. Technical access barrier (real NG login) — until the shared wallet opens.
|
||||
if (status !== 'connected') {
|
||||
return <AccessGateScreen status={status} error={error} onEnter={connect} />;
|
||||
// Access barrier — shown until BOTH the wallet is open AND the space is named.
|
||||
// "Entrer" records the identifier (persisted immediately, so it survives the
|
||||
// broker redirect) and, if the wallet isn't open yet, triggers the connect.
|
||||
if (status !== 'connected' || !username) {
|
||||
const onEnter = (identifier: string) => {
|
||||
login(identifier);
|
||||
if (status !== 'connected') connect();
|
||||
};
|
||||
return <AccessGateScreen status={status} error={error} onEnter={onEnter} />;
|
||||
}
|
||||
|
||||
// 2. Perceived app login — until a username is chosen.
|
||||
if (!username) {
|
||||
return <ConnexionScreen />;
|
||||
}
|
||||
|
||||
// 3. The app.
|
||||
// The app.
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user