Browser-safe, framework-agnostic EmpowerNow security SDK (OAuth 2.1, AuthZEN, FIPS checks)
npm install @empowernow/commonurn:ietf:params:oauth:grant-type:token-exchange).
ErrorCode enum for telemetry & UX.
bash
npm install @empowernow/common
`
Quick-start (browser)
`ts
import { OAuthClient } from "@empowernow/common";
const oauth = new OAuthClient(
"https://idp.example.com", // issuer
"client_id_123", // OAuth client id
{ redirectUri: window.location.origin, scopes: ["openid", "profile"] }
);
// 1) Start login ► redirect the user
window.location.assign(await oauth.createAuthorizationUrl());
// 2) On the redirect URI page
await oauth.handleRedirectCallback();
const accessToken = await oauth.getAccessToken();
`
Quick-start (Node – token exchange)
`ts
import { exchangeToken } from "@empowernow/common";
const jwt = await exchangeToken(
{
tokenEndpoint: "https://idp.example.com/oauth2/token",
clientId: "backend-client",
clientSecret: process.env.CLIENT_SECRET!,
audience: "https://api.example.com"
},
{ subjectToken: userAccessToken }
);
`
AuthZEN PDP evaluation
`ts
import { PDPClient } from "@empowernow/common";
const pdp = new PDPClient({
pdpUrl: "https://authz.example.com",
clientId: "pdp-client",
clientSecret: process.env.PDP_SECRET,
cacheSize: 1000,
ttl: 300
});
const decision = await pdp.evaluate({
subject: { id: "alice", type: "user" },
action: { name: "transfer" },
resource: { id: "account-123" },
context: { amount: 250 }
});
if (decision.decision === "ALLOW") {
// …
}
`
Error handling
`ts
import { TokenValidationError, ErrorCode } from "@empowernow/common";
try {
await oauth.handleRedirectCallback();
} catch (e) {
if (e instanceof TokenValidationError && e.errorCode === ErrorCode.ID_NONCE_MISMATCH) {
// display friendly error …
}
}
`
Browser / Node support
* Modern browsers (ES2019 & fetch, crypto.subtle available).
* Node ≥ 18 (global fetch + crypto` APIs). For Node 16 use a polyfill.