Refactor authentication structure by removing 'auth' package#1
Refactor authentication structure by removing 'auth' package#1voidtopixel wants to merge 9 commits intogs-layer:feat/auth-providerfrom
Conversation
Add @hai3/auth package (L1 SDK, types only) defining the AuthProvider contract with support for bearer tokens, cookie-sessions, and custom auth mechanisms via the AuthSession.kind discriminant. Add auth() framework plugin that wires any AuthProvider into the @hai3/api REST transport layer: - Bearer header attachment on every request - Cookie-session with withCredentials and optional CSRF header - Automatic 401 refresh+retry with concurrent refresh deduplication - Pluggable transport binder (default: hai3ApiTransport) - app.auth runtime surface via new generic provides.app mechanism Enhance @hai3/api REST protocol: - RestRequestOptions (params, signal, withCredentials) with backward-compatible overloads - AbortSignal propagation through plugin context and axios - axios.isCancel bypass of onError chain - Retry preserves plugin-modified request context Additional fixes: - MockEventSource async open and abort handling - BaseApiService.registerPlugin test for unregistered protocol - isMockPlugin test for inherited MOCK_PLUGIN symbol - ESLint config: exclude .artifacts and .agents directories Update AI guidelines: add AUTH.md target, document auth plugin in FRAMEWORK.md, document RestRequestOptions in API.md.
Resolve conflicts from @hai3 -> @cyberfabric package rename: - Rename @hai3/auth to @cyberfabric/auth across all auth files - Update peer dependencies to @cyberfabric/* namespace - Update build scripts with @cyberfabric/auth workspace - Regenerate package-lock.json from upstream base
- Exclude packages/auth/ from cypilot spec-coverage (types-only, no runtime logic to trace) - Add @cpt- scope and block markers to auth.ts plugin - Move @cyberfabric/auth from dependencies to peerDependencies (optional: true) in framework — auth is opt-in and not yet published to npm, so it must not be a required transitive dep
…overage Markers referenced spec IDs not defined in any artifact (code-orphan-ref). Exclude auth.ts from coverage scanning until a backing CDSL artifact is created. Auth package already excluded.
Blocking: - Fix protocol-relative URL credential leak (//host treated as relative) - Add HEAD/OPTIONS to AuthTransportRequest method union and isSupportedAuthTransportMethod so onTransportError fires for all methods - Filter opaque "null" origin in getRuntimeOrigin (sandboxed iframe/file://) Recommended: - Wrap refresh promise await in try/catch — concurrent waiters no longer receive unhandled rejections when refresh fails - Document SSE auth as out-of-scope in auth() plugin JSDoc - Add explicit comments for custom session kind pass-through (intentional) Tests added (5 new, 48 total): - Protocol-relative URL does not receive withCredentials - Opaque "null" origin does not match URL origins - Custom session: request unmodified, no retry after refresh - Refresh rejection: all concurrent waiters return ctx.error safely
…ignature
Replace 15 overload declarations (3 per method × 5 methods) and 4
helper functions (isAbortSignalLike, isRestRequestOptions,
normalizeGetRequestOptions, normalizeSignalOrOptions) with a single
RestRequestOptions signature per method.
At 0.x, backward-compatible overloads aren't worth the duck-typing
heuristic complexity. Callers migrate:
get(url, params, signal) → get(url, { params, signal })
post(url, data, signal) → post(url, data, { signal })
delete(url, signal) → delete(url, { signal })
Signed-off-by: G S <grigoriis.dev@gmail.com>
Major: - Remove .agents/ from PR (unrelated tooling, now gitignored) - Fix vite.config.ts resolve.dedupe: @hai3/* -> @cyberfabric/* - Re-export auth contract types (AuthProvider, AuthSession, etc.) from @cyberfabric/react for consumer convenience - Guard Object.assign in createHAI3.ts: fail fast if plugin app extension key conflicts with existing app property - Refactor AuthSession to discriminated union: BearerAuthSession (token required), CookieAuthSession (csrfToken), CustomAuthSession (open shape). Enables proper narrowing by session.kind Medium: - Remove unnecessary RestResponseContext type assertions in RestProtocol - Fix incorrect resolves.not.toThrow() matcher in auth test - Update API.md: remove deprecated positional signal example
…sitioning to a new auth plugin structure.
Code Review: PR #1 — Refactor authentication structureOverall AssessmentThis PR proposes a thoughtful restructuring of the auth architecture with a two-layer contract and React hooks. Several ideas here are genuinely valuable — identity type inference, lifecycle hooks with app context, and React hooks for common auth operations. That said, there are architectural and compatibility concerns worth discussing before merging. What works well1. React hooks out of the box 2. Identity type inference via module augmentation The This is an elegant solution to a real DX pain point. 3. Custom method pass-through 4. Provider lifecycle with app context 5. Clean file decomposition Splitting into Architectural concerns1. Two-layer contract introduces ambiguity in required methods The base This creates two different sets of required methods: A developer sees The current PR cyberfabric#260 uses a single contract: 3 required methods ( 2. Cookie-session providers often lack a programmatic login — the server sets a cookie via redirect. SAML/OIDC providers work similarly: login means redirecting to an IdP, not calling a method. Forcing In PR cyberfabric#260, 3. Removing The PR deletes
The pnpm issue has a simpler resolution: using 4. Three levels of type augmentation add complexity The PR introduces a chain: Three interface merges, a conditional type, and a global declaration. 5. The PR replaces
The React hooks compensate for this in UI code, but headless usage is a common scenario. 6. Transport binding is no longer pluggable PR cyberfabric#260 provides a This PR removes that extension point — transport is built into Compatibility with FrontX1. Layering FrontX architecture: L1 (SDK, zero deps) → L2 (framework) → L3 (React). Auth types are an L1 concern. This PR places them in L2, which conflicts with the 2. Breaking changes
Breaking changes are acceptable at 0.x, but the scope here is significant. 3. Scope This PR combines several independent concerns:
Each of these would benefit from being a separately reviewable PR. Combining them makes review harder and complicates rollback if issues arise. My recommendation for further workSeveral ideas from this PR would be valuable as incremental follow-ups to the current architecture:
Concerns that suggest keeping the current approach:
|
Verdict for RBAC
PR cyberfabric#260 is better positioned for RBAC contract integration because:
Valuable ideas from PR #1 for future RBAC work:
These can be added incrementally to the PR cyberfabric#260 architecture without the breaking changes PR #1 introduces. |
7d60d67 to
448b42a
Compare
Auth Plugin — Quick Start
Structure
Two layers: base (minimal contract, no transport assumptions) and frontx (session kinds + REST binding).
Basic Setup
That's it. Bearer tokens are auto-attached to every REST request. 401s trigger
refresh()if provided.Custom Identity Fields
Define your identity shape and the provider infers it everywhere:
After this, every hook and
app.getAuthProvider()call sees your custom fields and methods with full autocomplete — no generics needed at call-sites.React Hooks
Cookie Sessions
Cookie sessions auto-set
withCredentials: truefor same-origin and allowlisted origins.Extra Provider Methods
You can add any custom methods — they pass through with full types:
After augmenting
AppRuntimeExtensions, these methods are visible onuseAuthProvider()andapp.getAuthProvider().