@chainvue/verusid-oauth
v0.1.5
Published
TypeScript SDK for server-side VerusID OAuth/OIDC login
Readme
@chainvue/verusid-oauth
TypeScript SDK for server-side VerusID OAuth/OIDC login.
This package helps confidential Node.js backends start a VerusID OAuth login, exchange the returned authorization code, verify the OIDC ID token through Hydra discovery and JWKS, introspect the access token, compare Verus claims, and return a sanitized application session.
Install
npm install @chainvue/verusid-oauthUsage
import {
VerusOAuthError,
assertProductionConfig,
createConfig,
createVerusOAuthClient,
} from "@chainvue/verusid-oauth"
const config = createConfig(process.env)
if (process.env.NODE_ENV === "production") {
assertProductionConfig(config)
}
const verusOAuth = createVerusOAuthClient(config)
app.get("/login", (req, res) => {
const login = verusOAuth.createLoginRequest()
req.session.oauth = {
state: login.state,
nonce: login.nonce,
codeVerifier: login.codeVerifier,
}
res.redirect(login.authorizationUrl.toString())
})
app.get("/callback", async (req, res, next) => {
try {
const saved = req.session.oauth || {}
delete req.session.oauth
req.session.login = await verusOAuth.completeLogin({
code: req.query.code,
codeVerifier: saved.codeVerifier,
returnedState: req.query.state,
expectedState: saved.state,
expectedNonce: saved.nonce,
})
res.redirect("/")
} catch (error) {
if (error instanceof VerusOAuthError) {
res.status(400).json({ error: error.code, message: error.message })
return
}
next(error)
}
})completeLogin() returns a sanitized session by default:
{
"subject": "i...",
"verus": {
"verus_id": "i...",
"verus_id_name": "name@",
"verus_chain": "VRSCTEST",
"verus_auth_method": "verus_login_consent",
"verus_login_at": 1780828245
},
"grantedScope": "openid offline verusid",
"refreshTokenPresent": true
}Raw OAuth tokens are returned only when includeRawTokens: true is passed to completeLogin().
SDK-created login requests use PKCE by default. Store codeVerifier in the
user session with state and nonce, then pass it to completeLogin().
completeLogin() rejects SDK-created login callbacks that do not provide the
saved verifier.
Production deployments can provide accessTokenVerifier on the config to
validate access tokens without exposing Hydra admin introspection to the app
runtime. The verifier receives { accessToken, tokenSet, idTokenClaims, config }
and returns { active, claims }; the returned Verus claims must still match the
verified ID-token claims. Without a custom verifier, the SDK keeps using Hydra
admin introspection.
Production Guard
Call assertProductionConfig(config) during production startup, or use
getProductionConfigErrors(config) if you need to render/report all failures.
The guard rejects local example secrets, HTTP redirect URIs, public-looking HTTP
Hydra admin URLs, non-HTTPS Hydra issuer URLs, invalid URLs, invalid numeric
port/timeout values, non-default scopes, and starter-only local host defaults.
Environment
HYDRA_PUBLIC_URL, defaulthttp://$LOCAL_HOST:4444HYDRA_ADMIN_URL, defaulthttp://127.0.0.1:4445CLIENT_ID, defaultverus-express-loginCLIENT_SECRET, defaultverus-express-secretREDIRECT_URI, defaulthttp://$LOCAL_HOST:5560/callbackSCOPES, defaultopenid offline verusidOAUTH_HTTP_TIMEOUT_MS, default10000
Release Checklist
Use this checklist for future releases. npm versions are immutable, so push the release tag only after the package version and release contents are final.
- Update the
package.jsonversion. - Run
npm test. - Commit the release changes.
- Tag the commit as
vX.Y.Z. - Push the tag.
- Confirm GitHub Actions publishes the package.
- Verify the published version with:
npm view @chainvue/verusid-oauth versionnpm Trusted Publishing must remain configured for package
@chainvue/verusid-oauth with:
- GitHub repository:
chainvue/verusid-oauth - Workflow:
release.yml - Permission: npm publish
License
MIT
