nightpass
v1.0.1
Published
Bouton OIDC/PKCE NightPASS pour React et web components
Maintainers
Readme
NightPASS
Sommaire
Mission
NightPASS réunifie :
- un
<enterprise-login-button>web component prêt à brancher sur n’importe quel site statique ; - une panoplie React (boutons plein/outline, contexte
OidcAuthProvider, hookuseOidcCallback) alignée avec les attentes d’apps Betterhost/BetteOS multi-tenant ; - une implémentation PKCE solide : génération secure, stockage session isolé, parsing du callback, appel
/tokenet nettoyage automatique.
Installation
# npm
npm install nightpass
# pnpm
pnpm add nightpass
# yarn (classic)
yarn add nightpassUsage rapide
import {
EnterpriseLoginButton,
OidcAuthProvider,
useOidcAuth,
} from "nightpass";
function Ctas() {
const { isAuthenticating } = useOidcAuth();
return (
<>
<EnterpriseLoginButton
clientId="app1-spa"
redirectUri="https://app1.com/auth/callback"
theme="dark"
icon="https://cdn.powerglove.tech/brand/pg-icon.png"
loadingLabel="Connexion en cours..."
/>
<EnterpriseLoginButton
clientId="app1-spa"
outline
label={isAuthenticating ? "Veuillez patienter..." : "Connexion secondaire"}
/>
</>
);
}
export function App() {
const isCallbackRoute = window.location.pathname.startsWith("/auth/callback");
return (
<OidcAuthProvider
enableCallback={isCallbackRoute}
callbackOptions={{
clientId: "app1-spa",
redirectUri: "https://app1.com/auth/callback",
}}
onTokens={(tokens) => authStore.persist(tokens)}
onError={(error) => reportError(error)}
>
<Ctas />
</OidcAuthProvider>
);
}Variante outline (secondaire)
<EnterpriseLoginButton
clientId="app1-spa"
outline
label="Connexion secondaire"
buttonStyle={{ borderColor: "#6366f1", color: "#6366f1" }}
/>Le booléen outline applique un style transparent + bord (les couleurs par défaut dépendent de theme). Vous pouvez ensuite raffiner via className/buttonStyle.
Hook useOidcCallback
const { status, tokens, error, exchange } = useOidcCallback({
authBase: "https://auth.powerglove.tech",
realm: "powerglove",
redirectUri: "https://app1.com/auth/callback",
});Retour :
status:idle | no_code | loading | success | errortokens: payload JSON du token endpointexchange(): relance manuelle de l’échange (utile siimmediate: false)
Props détaillés
EnterpriseLoginButton
| Prop | Type | Description | Défaut |
| --- | --- | --- | --- |
| clientId | string | Identifiant Keycloak. Obligatoire sinon le composant throw. | — |
| redirectUri | string | URL de retour après authentification. | window.location.origin + "/auth/callback" |
| label | string | Texte affiché dans le bouton. | Connexion entreprise |
| theme | "light" \| "dark" | Ajuste la palette (outline s’appuie aussi sur ce thème). | light |
| icon | string | URL vers une icône (PNG, SVG, data URL). | Dégradé interne |
| scope | string | Scopes OIDC séparés par des espaces. | openid profile email |
| authBase | string | Base URL Keycloak (https://…). | https://auth.powerglove.tech |
| realm | string | Nom du realm Keycloak. | powerglove |
| iconSize | number | Largeur/hauteur de l’icône (px). | 18 |
| buttonStyle | React.CSSProperties | Styles inline additionnels (merge). | {} |
| className | string | Classe(s) CSS perso. | undefined |
| disabled | boolean | Force la désactivation (ex. maintenance). | false |
| loading | boolean | Force l’état busy (couplé à loadingLabel). | false |
| loadingLabel | string | Texte en mode loading. | Connexion... |
| outline | boolean | Passe le bouton en style secondaire (fond transparent + bord). | false |
| onNavigate | (url: string) => void | Callback perso pour gérer la redirection (tests, analytics). Si absent, window.location.assign est utilisé. | undefined |
Le composant consomme
OidcAuthContextpour se désactiver automatiquement dès queisAuthenticating === true.
OidcAuthProvider
| Prop | Type | Description | Défaut |
| --- | --- | --- | --- |
| enableCallback | boolean | Active useOidcCallback automatiquement (mettre true sur /auth/callback). | false |
| callbackOptions | object | Options transmises à useOidcCallback (clientId, redirectUri, scope, authBase, realm, autoClear, immediate). | {} |
| onTokens | (tokens) => void | Callback déclenché quand l’échange /token réussit. Idéal pour persister access_token/refresh_token. | undefined |
| onError | (error) => void | Callback déclenché en cas d’échec /token. | undefined |
Le contexte expose : isAuthenticating, status, tokens, error, beginAuthentication(), endAuthentication(), exchange() (du hook) et reset().
Web component – attributs
| Attribut | Description | Défaut |
| --- | --- | --- |
| client-id | Identifiant Keycloak. | "" |
| redirect-uri | URL de retour. | window.location.origin + "/auth/callback" |
| auth-base | Base Keycloak. | https://auth.powerglove.tech |
| realm | Realm ciblé. | powerglove |
| scope | Scopes OIDC. | openid profile email |
| label | Texte du bouton. | Connexion entreprise |
| theme | light ou dark. | light |
| icon | URL d’icône. | Dégradé interne |
Web Component
<script type="module" src="https://cdn.powerglove.tech/nightpass/web.js"></script>
<enterprise-login-button
client-id="app1-spa"
redirect-uri="https://app1.com/auth/callback"
theme="dark"
icon="https://cdn.powerglove.tech/brand/pg-icon.png">
</enterprise-login-button>Attributs acceptés : client-id, redirect-uri, auth-base, realm, scope, label, theme, icon.
Besoin d’un tag custom ? registerEnterpriseLoginButton("pg-login").
Scripts & workflow
| Commande | Rôle |
| --- | --- |
| npm run build | Build librairie (Vite lib mode → dist/index.js + dist/web.js). |
| npm run dev:e2e | Lance le harnais Vite (e2e-app) sur http://127.0.0.1:4173. |
| npm run test:e2e | Exécute Playwright headless (flux bouton → callback). |
| npm run test:e2e:headed | Même scénario, mais en mode graphique. |
| npm run build:e2e | Build production du harnais (utile pour démo). |
Tests E2E
- Le test
tests/e2e/oidc-flow.spec.tsinterceptehttps://auth.powerglove.tech/.../token, renvoie un token mocké et vérifie :- stockage PKCE avec clé
oidc.pkce.{state}puis purge (autoClear); - capture de l’URL d’autorisation (via
window.location.assign); - propagation
status: success+ enregistrement des tokens danswindow.__lastTokens.
- stockage PKCE avec clé
- Pour lancer localement :
npm install npx playwright install npm run test:e2e
