@namoidhq/js
v3.2.0
Published
Core JavaScript SDK for NamoID Hosted Auth using OpenID Connect Authorization Code with PKCE.
Maintainers
Readme
@namoidhq/js
Core JavaScript SDK for NamoID Hosted Auth using OpenID Connect Authorization Code with PKCE.
npm i @namoidhq/jsStart hosted sign-in
import { createNamoIDClient } from "@namoidhq/js";
const namoid = createNamoIDClient({
clientId: "namoid_client_live_...",
});
const started = await namoid.hostedAuth.start({
redirectUri: "https://your-app.com/auth/callback",
});
// Retain this one-time transaction until the callback. Do not store tokens here.
sessionStorage.setItem("namoid_transaction", JSON.stringify(started.transaction));
window.location.assign(started.authorizationUrl);The Client ID resolves the correct issuer and Hosted Auth domain. The SDK then uses issuer discovery instead of hard-coded OAuth endpoints.
Complete a public-client callback
const transaction = JSON.parse(sessionStorage.getItem("namoid_transaction")!);
const callback = new URL(window.location.href);
if (callback.searchParams.get("state") !== transaction.state) {
throw new Error("Invalid authorization state");
}
const tokens = await namoid.hostedAuth.exchangeCode({
code: callback.searchParams.get("code")!,
redirectUri: transaction.redirectUri,
codeVerifier: transaction.codeVerifier,
});
const identity = await namoid.hostedAuth.userInfo(tokens.access_token);
sessionStorage.removeItem("namoid_transaction");For browser apps, prefer @namoidhq/react, which validates state, response issuer, the signed ID token, nonce, and the UserInfo subject. Do not persist bearer or refresh tokens in localStorage or sessionStorage.
For confidential Next.js apps, use @namoidhq/nextjs so the Client Secret, PKCE verifier, callback validation, refresh token, and application session remain server-side.
Hosted sign-in in a popup
Popup delivery uses the same OIDC Authorization Code + PKCE flow. Register a
same-origin callback such as https://your-app.com/auth/namoid/popup and render
this minimal bridge on that route:
import { relayHostedAuthPopupCallback } from "@namoidhq/js";
relayHostedAuthPopupCallback();Then open Hosted Auth from a direct user click:
const result = await namoid.hostedAuth.popup({
redirectUri: `${window.location.origin}/auth/namoid/popup`,
// Optional: identityProvider: "google",
// Optional: authenticationMethod: "passkey", "password", "email_otp",
// "magic_link", or "phone_otp",
});
const tokens = await namoid.hostedAuth.exchangeCode({
code: result.code,
redirectUri: result.transaction.redirectUri,
codeVerifier: result.transaction.codeVerifier,
});The SDK binds the callback to a random, same-origin per-popup channel and
validates callback origin, state, and issuer. It also verifies the exact popup
handle when the browser preserves window.opener. The bridge relays only the
code, state, issuer, or a bounded OAuth error—never tokens or profile data. If
a browser blocks the popup, catch popup_blocked and offer a fresh normal
full-page redirect.
identityProvider selects a configured social provider. authenticationMethod
selects a configured hosted passkey, password, email-code, magic-link, or
phone-code ceremony. All remain ordinary OIDC Authorization Code + PKCE
requests; provider credentials, passwords, OTPs, and WebAuthn challenges never
move into the relying-party DOM.
namoid.auth.getConfig() includes sign_in_choices, which tells UI adapters
whether each configured choice uses a native_challenge or a
browser_redirect. Consume this field instead of inferring delivery from a
method name. The older method and provider lists remain available for
compatibility with earlier NamoID deployments.
Custom SPA UI with native email OTP (Test preview)
Native email OTP is a guarded Test-only preview for trusted first-party SPA
applications provisioned for the preview. It is not a general Console setting.
Read turnstile_site_key and native_auth_turnstile_actions from
namoid.auth.getConfig() and obtain a fresh Turnstile token for each protected
step.
const started = await namoid.nativeAuth.start({
redirectUri: `${window.location.origin}/auth/callback`,
turnstileToken: startTurnstileToken,
});
await namoid.nativeAuth.requestEmailOtp({
flowToken: started.flowToken,
email,
turnstileToken: otpTurnstileToken,
});
const authorization = await namoid.nativeAuth.verifyEmailOtp({
flowToken: started.flowToken,
email,
code,
transaction: started.transaction,
});
const tokens = await namoid.hostedAuth.exchangeCode({
code: authorization.code,
redirectUri: started.transaction.redirectUri,
codeVerifier: started.transaction.codeVerifier,
});Social login, passkeys, MFA, waitlists, custom registration fields, and mobile native clients continue through Hosted Auth. Do not store bearer or refresh tokens in browser storage.
Docs: https://docs.namoid.in · Contact: [email protected]
License
MIT © PolyMindsLabs Pvt. Ltd.
