@plasius/auth
v1.0.9
Published
Authentication helpers and React context for Plasius applications.
Readme
@plasius/auth
Authentication helpers and React context components for Plasius applications.
Apache-2.0. ESM + CJS builds. TypeScript types included.
Requirements
- Node.js 24+ (matches
.nvmrc) - React 19 (
peerDependencies) - Browser runtime for hooks (
window/documentare used)
Installation
npm install @plasius/authExports
import {
AuthProvider,
useAuth,
useAuthorizedFetch,
createAuthorizedFetch,
useLogin,
useLogout,
} from "@plasius/auth";Quick Start
import { AuthProvider, useAuth, useLogin, useLogout } from "@plasius/auth";
import type { AuthProvider as OAuthProviderId } from "@plasius/entity-manager";
function AccountPanel() {
const { userId, validateSession } = useAuth();
const login = useLogin();
const logout = useLogout();
const provider = "github" as OAuthProviderId;
return (
<div>
<p>Signed in as: {userId ?? "anonymous"}</p>
<button onClick={() => login(provider)}>Log in</button>
<button onClick={() => logout()}>Log out</button>
<button onClick={() => validateSession()}>Revalidate session</button>
</div>
);
}
export default function App() {
return (
<AuthProvider>
<AccountPanel />
</AuthProvider>
);
}API
AuthProvider
Provides auth state through context and runs session validation on mount.
useAuth()
Returns:
userId: string | nullsetUserId(userId: string | null)validateSession(): Promise<void>
validateSession() calls GET /oauth/me and updates userId from a userId field in the response body.
useAuthorizedFetch()
React hook that returns an authorized fetch wrapper.
createAuthorizedFetch()
Non-hook function that creates the same authorized fetch wrapper.
Behavior:
- Always sends requests with
credentials: "include". - Reads
csrf-tokenfrom browser cookies and sends it asx-csrf-tokenwhen present. - On
401, callsPOST /oauth/refresh-tokenand retries the original request. - Deduplicates concurrent refresh calls with a shared promise.
- Limits refresh to one retry cycle per request (prevents recursive retry loops).
- Applies cooldown after refresh failure or repeated
401so clients return failure instead of repeatedly hitting auth endpoints. - For outage responses (
429/5xx) on refresh, uses randomized logarithmic backoff with an increasing cooldown window. - Honors
Retry-After(seconds) from refresh responses before retrying.
useLogin()
Returns a function that redirects to:
/oauth/{provider}?state={base64(currentPath)}
The provider identifier type comes from @plasius/entity-manager (AuthProvider), and is separate from this package's React AuthProvider component.
useLogout()
Returns a function that:
- Sends
POST /oauth/logout. - Redirects the browser to
/regardless of request outcome.
Server Integration Guide
This package is frontend-only. It assumes your backend owns authentication and issues cookies.
End-to-End Flow
- User clicks login and
useLogin()redirects browser toGET /oauth/{provider}?state={base64(path)}. - Backend starts OAuth with the provider, completes callback handling, then sets auth cookies.
AuthProvidercallsGET /oauth/meon mount to populateuserId.- API calls through
useAuthorizedFetch()include cookies and optionalx-csrf-token. - If a protected call returns
401, package sendsPOST /oauth/refresh-tokenonce for concurrent callers. - On successful refresh, original request is retried automatically.
useLogout()sendsPOST /oauth/logoutthen redirects to/.
Required API Contract
| Route | Method | Called by | Required behavior |
| --- | --- | --- | --- |
| /oauth/{provider} | GET | useLogin() | Start provider login flow; accept state query param. |
| /oauth/me | GET | AuthProvider.validateSession() | Return 200 with JSON containing userId when authenticated, otherwise non-2xx (typically 401). |
| /oauth/refresh-token | POST | createAuthorizedFetch() after 401 | Attempt token/session refresh using cookies; return 2xx on success, non-2xx on failure. |
| /oauth/logout | POST | useLogout() | Invalidate session cookies/server session and return 2xx/204 when possible. |
Endpoint Response Shapes
GET /oauth/me success example:
{
"userId": "user_123"
}GET /oauth/me should return 401 (or another non-2xx) when no valid session exists.
POST /oauth/refresh-token may optionally return a Retry-After response header (seconds).
If present and greater than zero, the package waits before retrying the original request.
Cookies, CSRF, and Headers
- Auth/session cookie must be sent on credentialed requests (
credentials: "include"is always used). - For CSRF protection, expose a readable cookie named
csrf-tokenif you want the package to sendx-csrf-token. useAuthorizedFetch()addsx-csrf-tokenonly when thecsrf-tokencookie exists.- Refresh calls to
/oauth/refresh-tokendo not includex-csrf-tokenautomatically; protect this route with cookie policy and origin checks. useLogout()uses authorized fetch, so logout receivesx-csrf-tokenwhen available.
Cross-Origin Deployment (If API and App Origins Differ)
Configure backend CORS and cookies for credentialed requests:
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Originmust be a specific origin, not*- Session cookies should use
Secureand an appropriateSameSitepolicy for your topology.
Security Notes for /oauth/{provider} state
state is set by the client as base64(window.location.pathname). Backend should:
- Treat
stateas untrusted input. - Validate/decode safely.
- Restrict post-login redirects to allowed in-app paths to prevent open redirects.
Minimal Backend Checklist
- Implement all four routes above.
- Issue and clear session cookies reliably.
- Return
userIdfrom/oauth/mefor authenticated sessions. - Return
401for expired/invalid sessions. - Make
/oauth/refresh-tokenidempotent and safe for concurrent requests. - Enforce CSRF/origin protections for state-changing endpoints.
OAuth 2.0 Standards Alignment
This package is designed to align with OAuth 2.0 and current IETF security guidance when paired with a compliant backend.
Core Standards
- OAuth 2.0 Framework (RFC 6749): https://www.rfc-editor.org/info/rfc6749
- Bearer Token Usage (RFC 6750): https://www.rfc-editor.org/info/rfc6750
- PKCE for Authorization Code Grant (RFC 7636): https://www.rfc-editor.org/info/rfc7636
- Token Revocation (RFC 7009): https://www.rfc-editor.org/info/rfc7009
- Authorization Server Metadata (RFC 8414): https://www.rfc-editor.org/info/rfc8414
- OAuth 2.0 Security Best Current Practice (RFC 9700 / BCP 240): https://www.rfc-editor.org/info/rfc9700
Browser-Based App Guidance
- OAuth 2.0 for Browser-Based Applications (IETF WG draft, latest): https://datatracker.ietf.org/doc/draft-ietf-oauth-browser-based-apps/
Practical Alignment Notes for This Package
- The frontend uses a server-backed session model (cookie-based), which helps avoid exposing long-lived OAuth tokens to browser JavaScript.
- The backend should use Authorization Code + PKCE with the identity provider.
- The backend should enforce exact redirect URI matching and reject open redirects.
- The backend should treat the incoming
statevalue as untrusted input. - The backend should generate and validate its own CSRF correlation/anti-forgery value for OAuth redirects and state-changing endpoints.
- The backend should revoke or invalidate tokens/sessions during logout.
- The backend should use HTTPS everywhere and secure cookie settings (
Secure,HttpOnly,SameSitealigned to deployment topology).
Compliance Checklist (Backend)
- Do not use Implicit Grant or Resource Owner Password Credentials flows.
- Use Authorization Code grant with PKCE for user login.
- Validate redirect URIs exactly against registered values.
- Protect state-changing endpoints (
/oauth/logout,/oauth/refresh-token) against CSRF. - Avoid putting access tokens in URL query parameters.
- Return non-2xx for invalid sessions and avoid leaking sensitive error detail.
Build Outputs
The package publishes:
- ESM bundle:
dist/index.js - CJS bundle:
dist/index.cjs - Type definitions:
dist/index.d.ts
Development
npm run clean
npm run build
npm test
npm run test:coverage
npm run lintDemo scaffold:
npm run build
node demo/example.mjsRelease Policy
Package publishing is performed through GitHub CD workflows only. Do not publish directly from local machines.
Contributing
- Open issues/PRs at Plasius-LTD/auth.
- Read CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.
