Moost Integration
This section answers: how do I plug aoothjs into a Moost HTTP app, in what order, with which decorators, and which extension seams should I override? It covers two packages that together form the framework glue layer:
| Package | Concern |
|---|---|
@aooth/auth-moost | Authentication. authGuardInterceptor, useAuth(), AuthController, the unified AuthWorkflow (login / invite / recovery / signup / federated), ConsentStore, magic-link outlets, the OAuthController + federated leg of auth/login/flow over @aooth/idp. |
@aooth/arbac-moost | Authorization. arbacAuthorizeInterceptor, useArbac(), @ArbacResource / @ArbacAction / @ArbacAuthorize, AsArbacDbController, atscript-driven user provider. |
The two packages share one decorator on purpose: @Public() writes both authPublic=true and arbacPublic=true, so a single annotation hides a route from both guards. Splitting the two into separate decorators was — in practice — a foot-gun.
Both guards are GUARD-priority interceptors
The auth guard and the ARBAC interceptor are both defineBeforeInterceptor at TInterceptorPriority.GUARD. The auth guard runs first (it has no dependencies on ARBAC state); the ARBAC interceptor calls useAuth().getUserId() indirectly through your ArbacUserProvider. Apply them in that order.
Where to start
| If you want to… | Read |
|---|---|
| Bootstrap a fresh app with both layers wired | Setup |
Understand authGuardInterceptor token extraction, public-route handling, 401 mapping | AuthGuard & useAuth |
Understand arbacAuthorizeInterceptor resource/action resolution, scope plumbing, 403 mapping | ARBAC Authorize |
| Look up every decorator and composable in one place | Decorators |
Wire up /auth/logout / /auth/refresh / /auth/status / /auth/trigger | REST Controllers |
List a user's signed-in devices, revoke one / log out others, mount SessionsController | Sessions |
Configure the unified AuthWorkflow, subclass it, override resolveXxx, hook the email outlet | Workflows |
| Let users log in / recover by phone, deliver the recovery OTP to a verified channel, auto-promote handles | Phone, Recovery Channels & Handles |
Wire "Sign in with Google" — login-form SSO button, OAuthController, connected accounts, callback bridge | Federated Login (OAuth) |
| Turn the app INTO an OAuth/OIDC provider — CLI loopback login + first-party "Sign in with the main app" | Authorization Server |
| Render the workflow forms (QR, consents, password rules) in your SPA | SPA Components |
Add ARBAC scopes to your AsDbController-derived REST endpoints | DB Controllers |
Drive @arbac.* annotations from .as user models | Atscript Models |
| Wire an audit sink | Audit Log |
Look up AuthOptions and AuthWorkflowOpts tuning knobs | Config Reference |
Mental model
HTTP request
│
▼
authGuardInterceptor (GUARD) ← reads bearer / cookie token, sets AuthContext or null
│
▼
arbacAuthorizeInterceptor (GUARD) ← resolves resource/action via @ArbacResource/@ArbacAction
│ evaluates against ArbacUserProvider(roles, attrs)
│ sets per-event scopes; 403 on deny
▼
@Intercept / @Pipe (INTERCEPTOR / PIPE priorities)
│
▼
Handler
│ useAuth().getUserId() ← throws 401 if no context
│ useArbac().getScopes() ← reads scopes set by the interceptor
▼
ResponseWorkflow events (@moostjs/event-wf) inherit the originating HTTP event's AuthContext and option slot through Moost's parent chain. useAuth() and useArbac() traverse the parent chain so handler code inside a @Step can call them as if it were running inline. See Workflows for the details.