@revidp/identity-platform
v0.1.0
Published
Framework-neutral OAuth 2.0 + PKCE helpers for REVID brand integrations.
Readme
@revidp/identity-platform
Framework-neutral OAuth 2.0 authorization-code + PKCE helpers for REVID brand integrations. It matches the existing Mediator SSO contract: authorize at /authorize, then exchange at /api/v1/token using code_verifier.
Install
npm install @revidp/identity-platformScaffold a Next.js integration
From an existing Next.js App Router project, run:
npx revid-identity init --client-id brand-client-id --mediator-url https://identity.example.com --redirect-uri http://localhost:3000/auth/revid/callback --brand-name "Example Brand"It generates the login page, browser callback page, server token-exchange route, and .env.local.example. Existing generated files are protected; pass --force only when you intend to replace them. Add --demo to also create a test-only session/logout implementation for local flow testing. Replace that demo session with the brand's real server-side session storage before production.
Remove a scaffold
The scaffold records exactly what it generated in .revid-identity.json. To remove it later:
npx revid-identity removeThe command deletes only generated files that are unchanged. Modified files are kept and reported; pass --force only if you intend to remove those files too. It never deletes .env.local.
Browser: start login or registration
import { createIdentityConfig, createAuthorizationRequest } from '@revidp/identity-platform/browser'
const config = createIdentityConfig({
clientId: import.meta.env.VITE_REVID_CLIENT_ID,
mediatorUrl: import.meta.env.VITE_REVID_MEDIATOR_URL, // https://identity.example.com
redirectUri: 'https://brand.example.com/auth/revid/callback',
brandName: 'Example Brand'
})
const { url } = await createAuthorizationRequest(config, { intent: 'login' })
window.location.assign(url)Use intent: 'register' to create a registration-oriented authorization URL. The current Mediator uses the same /authorize endpoint; intent=register is supplied as a UI hint.
createAuthorizationRequest writes a one-time state/verifier transaction to sessionStorage. For another storage system, pass { store } with get, set, and remove methods. Never place a client secret in browser code.
Callback and server exchange
On your browser callback page, call validateAuthorizationCallback(location.href). It validates and consumes state, returning { code, verifier }. Send those values to your own server route over HTTPS. The route calls the server-only entrypoint:
import { exchangeAuthorizationCode } from '@revidp/identity-platform/server'
const tokens = await exchangeAuthorizationCode({
clientId: process.env.REVID_CLIENT_ID,
mediatorUrl: process.env.REVID_MEDIATOR_URL,
redirectUri: process.env.REVID_REDIRECT_URI
}, { code, verifier })Store the result in an HttpOnly, secure, application-managed session. createSessionAdapter({ getUser, setSession, clearSession }) is provided as a small interface for plugging in that session layer; it deliberately does not prescribe storage or expose tokens to UI code.
Login and entitlements
Expose only safe user fields from your own session endpoint or server component, then create helpers around it. getUser can be synchronous or asynchronous.
import { createIdentityClient } from '@revidp/identity-platform'
const identity = createIdentityClient({ getUser: () => currentUser })
await identity.isLoggedIn() // true / false
await identity.getEntitlements() // ['subscriber', 'event-access']
await identity.hasEntitlement('subscriber') // true / falsegetEntitlements() reads user.entitlements and normalizes strings or { name }, { code }, and { id } records. Authorization decisions for protected server resources must still be enforced on the server.
Next.js
See examples/nextjs. Set only public configuration in browser-visible variables and keep the exchange configuration server-side:
NEXT_PUBLIC_REVID_CLIENT_ID=example-public-client-id
NEXT_PUBLIC_REVID_MEDIATOR_URL=https://identity.example.com
NEXT_PUBLIC_REVID_REDIRECT_URI=https://brand.example.com/auth/revid/callback
REVID_CLIENT_ID=example-public-client-id
REVID_MEDIATOR_URL=https://identity.example.com
REVID_REDIRECT_URI=https://brand.example.com/auth/revid/callbackThe widget helper is intentionally tiny and style-free:
import React from 'react'
import { createIdentityWidget } from '@revidp/identity-platform/react'
const IdentityWidget = createIdentityWidget(React)
<IdentityWidget user={user} loginLabel="Sign in to Example Brand" onLogin={startLogin} onLogout={signOut} />When user is present it shows displayName, name, or email and an optional logout button. The package has no runtime dependencies. Run npm test and npm run lint before publishing.
