npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@congo-digital/auth

v0.1.0

Published

Reusable CDS auth helpers for Keycloak/OIDC with React bindings and pluggable storage.

Readme

@congo-digital/auth

SDK TypeScript pour intégrer l'authentification CDS basée sur Keycloak / OpenID Connect, avec support PKCE, bindings React et helpers Expo / React Native.

Fonctionnalités

  • Génération d'URL d'authentification OIDC avec PKCE
  • Gestion du cycle login, register et reset-credentials
  • Échange du code d'autorisation contre des tokens
  • Récupération du profil utilisateur via userinfo
  • Rafraîchissement et vérification de token
  • Adaptateurs de stockage pour navigateur, mémoire, AsyncStorage et Expo Secure Store
  • Composants React prêts à l'emploi
  • Helpers Expo pour lancer et traiter le callback
  • Appels d'administration Keycloak pour supprimer un utilisateur

Installation

npm install @congo-digital/auth

Selon votre cible, ajoutez aussi les dépendances de pair utiles :

npm install react
npm install expo-secure-store @react-native-async-storage/async-storage

Configuration

Le client peut être configuré par code ou via variables d'environnement.

Règle de résolution

Lors de l'instanciation, le SDK suit cette logique :

  • si une valeur est fournie dans config, elle est prioritaire
  • sinon le SDK lit la variable d'environnement correspondante
  • si une valeur obligatoire n'existe ni dans config ni dans l'environnement, une erreur est levée immédiatement

Exemple :

import { createCdsAuth } from "@congo-digital/auth";

const auth = createCdsAuth({
  issuer: "https://your-keycloak.example.com/realms/your-realm",
  clientId: "your-client-id",
  callbackUrl: "https://your-app.example.com/api/auth/callback",
});

Ici, même si aucune variable d'environnement n'est définie, l'instance fonctionne car les valeurs requises sont passées en paramètre.

Variables d'environnement supportées

KEYCLOAK_ISSUER=https://your-keycloak.example.com/realms/your-realm
KEYCLOAK_CLIENT_ID=your-client-id
KEYCLOAK_CLIENT_SECRET=your-client-secret
KEYCLOAK_ADMIN_CLIENT_ID=your-admin-client-id
KEYCLOAK_ADMIN_CLIENT_SECRET=your-admin-client-secret
NEXT_PUBLIC_APP_URL=https://your-app.example.com

Configuration TypeScript

import { createCdsAuth } from "@congo-digital/auth";

const auth = createCdsAuth({
  issuer: "https://your-keycloak.example.com/realms/your-realm",
  clientId: "your-client-id",
  appUrl: "https://your-app.example.com",
  callbackPath: "/api/auth/callback",
});

Paramètres requis si les variables d'environnement sont absentes

Si l'environnement ne contient pas les variables nécessaires, il faut fournir ces paramètres à l'instanciation :

  • issuer si KEYCLOAK_ISSUER est absent
  • clientId si KEYCLOAK_CLIENT_ID est absent
  • callbackUrl ou appUrl si NEXT_PUBLIC_APP_URL est absent

Notes :

  • callbackUrl peut être donné directement
  • sinon appUrl permet de construire automatiquement l'URL de callback avec callbackPath
  • clientSecret, adminClientId et adminClientSecret restent optionnels sauf si vous utilisez les fonctions qui en dépendent

Erreurs levées si la configuration est incomplète

L'instanciation échoue explicitement avec les messages suivants :

  • Missing KEYCLOAK_ISSUER or config.issuer
  • Missing KEYCLOAK_CLIENT_ID or config.clientId
  • Missing callbackUrl or appUrl to derive it

Exemple invalide :

import { createCdsAuth } from "@congo-digital/auth";

// Lève une erreur si les variables d'environnement ne sont pas définies
const auth = createCdsAuth();

Exemple valide sans variables d'environnement :

import { createCdsAuth } from "@congo-digital/auth";

const auth = createCdsAuth({
  issuer: "https://your-keycloak.example.com/realms/your-realm",
  clientId: "your-client-id",
  callbackUrl: "https://your-app.example.com/api/auth/callback",
});

Utilisation de base

1. Démarrer une authentification

import { createCdsAuth, createMemoryStorage } from "@congo-digital/auth";

const auth = createCdsAuth({
  issuer: "https://your-keycloak.example.com/realms/your-realm",
  clientId: "your-client-id",
  callbackUrl: "https://your-app.example.com/api/auth/callback",
});

const storage = createMemoryStorage();

const { url } = await auth.startAuthorization({
  action: "login",
  storage,
});

// Rediriger l'utilisateur vers l'URL générée
console.log(url);

2. Traiter le callback

const result = await auth.handleCallback({
  currentUrl: "https://your-app.example.com/api/auth/callback?code=...&state=...",
  storage,
});

console.log(result.tokens);
console.log(result.user);

Adaptateurs de stockage

Le SDK stocke temporairement la transaction PKCE (state, codeVerifier) entre le démarrage du flux et le callback.

Navigateur

import { createBrowserSessionStorageAdapter } from "@congo-digital/auth";

const storage = createBrowserSessionStorageAdapter();

Web Storage personnalisé

import { createWebStorageAdapter } from "@congo-digital/auth";

const storage = createWebStorageAdapter(window.localStorage);

React Native AsyncStorage

import AsyncStorage from "@react-native-async-storage/async-storage";
import { createAsyncStorageAdapter } from "@congo-digital/auth";

const storage = createAsyncStorageAdapter(AsyncStorage);

Expo Secure Store

import * as SecureStore from "expo-secure-store";
import { createExpoSecureStoreAdapter } from "@congo-digital/auth";

const storage = createExpoSecureStoreAdapter(SecureStore);

React

Le point d'entrée @congo-digital/auth/react expose un bouton générique et trois variantes prêtes à l'emploi.

import { LoginButton } from "@congo-digital/auth/react";

export function SignIn() {
  return (
    <LoginButton
      config={{
        issuer: "https://your-keycloak.example.com/realms/your-realm",
        clientId: "your-client-id",
        callbackUrl: "https://your-app.example.com/api/auth/callback",
      }}
      className="btn"
      onAuthError={(error) => console.error(error)}
    >
      Se connecter
    </LoginButton>
  );
}

Exports React disponibles :

  • AuthButton
  • LoginButton
  • RegisterButton
  • ForgotPasswordButton

Expo

Le point d'entrée @congo-digital/auth/expo fournit des helpers pour lancer le flux et traiter le callback.

import * as SecureStore from "expo-secure-store";
import { createCdsAuth, createExpoSecureStoreAdapter } from "@congo-digital/auth";
import { createExpoAuthFlow } from "@congo-digital/auth/expo";

const auth = createCdsAuth({
  issuer: "https://your-keycloak.example.com/realms/your-realm",
  clientId: "your-client-id",
  callbackUrl: "myapp://auth/callback",
});

const storage = createExpoSecureStoreAdapter(SecureStore);
const flow = createExpoAuthFlow(auth, storage);

await flow.startLogin(async (url) => {
  // Exemple: WebBrowser.openAuthSessionAsync(url, redirectUrl)
  console.log(url);
});

const session = await flow.handleCallback("myapp://auth/callback?code=...&state=...");

Vérification et rafraîchissement des tokens

const refreshed = await auth.refreshAccessToken(refreshToken);
const user = await auth.verifyAccessToken(refreshed.access_token);

verifyAccessToken() renvoie null si le token est invalide.

Déconnexion

const logoutUrl = auth.getLogoutUrl(idToken);

Administration Keycloak

Si adminClientId et adminClientSecret sont configurés, le client peut obtenir un token d'administration et supprimer un utilisateur :

await auth.deleteUser("user-id");

Référence API

@congo-digital/auth

createCdsAuth(config?)

Crée une instance de CdsAuthClient.

Paramètres :

  • config?: CdsAuthConfigInput : configuration du client.

Comportement :

  • si config contient les champs requis, ils sont utilisés directement
  • sinon les valeurs sont cherchées dans l'environnement
  • si issuer, clientId ou une valeur permettant de construire callbackUrl sont absents, l'instanciation lève une erreur

Retour :

  • CdsAuthClient

new CdsAuthClient(config?)

Construit un client d'authentification et résout automatiquement la configuration via les variables d'environnement si nécessaire.

Paramètres :

  • config?: CdsAuthConfigInput

Propriétés :

  • config: ResolvedCdsAuthConfig : configuration finale utilisée par le client.

Erreurs possibles :

  • Missing KEYCLOAK_ISSUER or config.issuer
  • Missing KEYCLOAK_CLIENT_ID or config.clientId
  • Missing callbackUrl or appUrl to derive it

auth.getAuthorizationUrl(action?, callbackUrl?)

Génère une URL OIDC avec PKCE sans persister la transaction.

Paramètres :

  • action?: AuthAction : "login", "register" ou "reset-credentials". Défaut : "login".
  • callbackUrl?: string : URL de redirection à utiliser à la place de celle configurée.

Retour :

  • Promise<AuthorizationResult>
  • AuthorizationResult.url : URL à ouvrir.
  • AuthorizationResult.state : état PKCE généré.
  • AuthorizationResult.codeVerifier : vérificateur PKCE à conserver.

auth.startAuthorization(options)

Démarre le flux d'authentification et stocke la transaction PKCE dans le stockage fourni.

Paramètres :

  • options.action?: AuthAction : type d'action à lancer.
  • options.storage: StorageAdapter : stockage temporaire de la transaction.
  • options.callbackUrl?: string : URL de callback spécifique à cet appel.

Retour :

  • Promise<AuthorizationResult>

auth.exchangeCodeForTokens(code, codeVerifier, callbackUrl?)

Échange un code d'autorisation contre un jeu de tokens.

Paramètres :

  • code: string : code renvoyé par Keycloak.
  • codeVerifier: string : PKCE verifier généré lors du démarrage du flux.
  • callbackUrl?: string : URL de callback utilisée pendant l'échange.

Retour :

  • Promise<TokenSet>

auth.fetchUserInfo(accessToken)

Récupère le profil utilisateur depuis l'endpoint userinfo.

Paramètres :

  • accessToken: string : token d'accès valide.

Retour :

  • Promise<UserInfo>

auth.handleCallback(options)

Valide l'URL de callback, recharge la transaction stockée, échange le code puis récupère l'utilisateur.

Paramètres :

  • options.currentUrl: string : URL complète du callback reçue par l'application.
  • options.storage: StorageAdapter : stockage contenant la transaction initiale.
  • options.callbackUrl?: string : URL de callback à utiliser pour l'échange du code.

Retour :

  • Promise<CallbackResult>
  • CallbackResult.tokens : tokens OIDC.
  • CallbackResult.user : profil utilisateur.

auth.refreshAccessToken(refreshToken)

Rafraîchit un token d'accès à partir d'un refresh_token.

Paramètres :

  • refreshToken: string

Retour :

  • Promise<TokenSet>

auth.verifyAccessToken(accessToken)

Vérifie la signature et l'émetteur d'un token JWT via les certificats du realm.

Paramètres :

  • accessToken: string

Retour :

  • Promise<UserInfo | null> : null si le token est invalide.

auth.getLogoutUrl(idToken)

Construit l'URL de déconnexion Keycloak.

Paramètres :

  • idToken: string : id_token de la session.

Retour :

  • string

auth.getAdminAccessToken()

Demande un token d'administration avec le flux client_credentials.

Pré-requis :

  • adminClientId
  • adminClientSecret

Retour :

  • Promise<string>

auth.deleteUser(userId)

Supprime un utilisateur via l'API d'administration Keycloak.

Paramètres :

  • userId: string : identifiant Keycloak de l'utilisateur.

Retour :

  • Promise<void>

resolveCdsAuthConfig(input?, env?)

Résout la configuration finale du SDK à partir d'une config partielle et d'un environnement.

Paramètres :

  • input?: CdsAuthConfigInput
  • env?: EnvLike : objet clé/valeur similaire à process.env.

Retour :

  • ResolvedCdsAuthConfig

Règles importantes :

  • input.issuer est prioritaire sur KEYCLOAK_ISSUER
  • input.clientId est prioritaire sur KEYCLOAK_CLIENT_ID
  • input.callbackUrl est prioritaire sur toute valeur dérivée
  • si callbackUrl n'est pas fourni, il est construit à partir de appUrl + callbackPath
  • si aucune de ces données n'est disponible, la fonction lève une erreur

createMemoryStorage()

Crée un stockage en mémoire, utile pour les tests ou usages temporaires.

Paramètres :

  • aucun

Retour :

  • StorageAdapter

createWebStorageAdapter(storage)

Adapte un stockage compatible Web Storage.

Paramètres :

  • storage: Pick<Storage, "getItem" | "setItem" | "removeItem">

Retour :

  • StorageAdapter

createBrowserSessionStorageAdapter()

Utilise window.sessionStorage automatiquement.

Paramètres :

  • aucun

Retour :

  • StorageAdapter

createAsyncStorageAdapter(storage)

Adapte un stockage asynchrone de type React Native.

Paramètres :

  • storage: AsyncKeyValueStorage

Retour :

  • StorageAdapter

createExpoSecureStoreAdapter(storage)

Adapte Expo Secure Store au format attendu par le SDK.

Paramètres :

  • storage: ExpoSecureStoreLike

Retour :

  • StorageAdapter

@congo-digital/auth/react

AuthButton(props)

Bouton React générique qui démarre le flux d'authentification puis redirige le navigateur.

Props principales :

  • auth?: CdsAuthClient : instance existante à réutiliser.
  • config?: CdsAuthConfigInput : configuration utilisée si auth n'est pas fourni.
  • action?: AuthAction : "login", "register" ou "reset-credentials".
  • storage?: StorageAdapter : stockage de transaction. Par défaut : sessionStorage.
  • callbackUrl?: string : URL de callback spécifique.
  • children?: ReactNode : contenu du bouton.
  • onAuthError?: (error: Error) => void : callback d'erreur.
  • ...props : autres props HTML standard de <button> sauf onClick.

LoginButton(props)

Alias de AuthButton avec action="login".

Paramètres :

  • props: Omit<AuthButtonProps, "action">

RegisterButton(props)

Alias de AuthButton avec action="register".

Paramètres :

  • props: Omit<AuthButtonProps, "action">

ForgotPasswordButton(props)

Alias de AuthButton avec action="reset-credentials".

Paramètres :

  • props: Omit<AuthButtonProps, "action">

@congo-digital/auth/expo

startExpoAuthorization(auth, options)

Démarre l'authentification puis appelle openUrl avec l'URL générée.

Paramètres :

  • auth: CdsAuthClient
  • options.action?: AuthAction
  • options.storage: StorageAdapter
  • options.callbackUrl?: string
  • options.openUrl: (url: string) => Promise<void> | void

Retour :

  • Promise<string> : URL ouverte.

handleExpoCallback(auth, options)

Wrapper Expo autour de auth.handleCallback().

Paramètres :

  • auth: CdsAuthClient
  • options.currentUrl: string
  • options.storage: StorageAdapter
  • options.callbackUrl?: string

Retour :

  • Promise<CallbackResult>

createExpoAuthFlow(auth, storage, callbackUrl?)

Crée une API simplifiée pour Expo.

Paramètres :

  • auth: CdsAuthClient
  • storage: StorageAdapter
  • callbackUrl?: string

Retour :

  • objet avec :
  • startLogin(openUrl)
  • startRegister(openUrl)
  • startForgotPassword(openUrl)
  • handleCallback(currentUrl)

Développement

npm run build

Le package publie les fichiers compilés dans dist/.

Licence

MIT. Voir LICENSE.