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

@gugupy/adminjs-keycloak

v1.2.0

Published

Keycloak authentication provider for AdminJS.

Readme

@gugupy/adminjs-keycloak

A minimal AdminJS auth provider for Keycloak (OpenID Connect). Exchanges an authorization code for tokens, fetches user info, and returns an AdminJS CurrentAdmin object.

⚠️ Compatibility Note: This package has been tested and verified to work with the @adminjs/express plugin only. While it may work with other AdminJS plugins (Fastify, Hapi, etc.), it has not been tested with those frameworks. If you use this package with other plugins, please test thoroughly and report any issues.

Installation

npm install @gugupy/adminjs-keycloak

Example

A minimal, runnable example is available: gugupy/adminjs-express-keycloak.

  • Simple Express + AdminJS integration using this Keycloak auth provider.
  • Demonstrates environment variable usage for configuration.
  • Includes OAuth callback middleware that converts Keycloak's GET (with code) into a POST AdminJS can process.
  • Exchanges the authorization code for tokens and populates the AdminJS CurrentAdmin object.
  • Implements a logout flow that clears the session and redirects to Keycloak's logout endpoint.
  • Use this example as a reference for configuration and a runnable implementation you can run locally.

Demo — Keycloak OAuth Flow

Watch the authentication flow in action:

Demo

The animation demonstrates the complete Keycloak OAuth flow integration with AdminJS, showing the user experience from login button click to successful authentication.

Express Middleware Configuration

Important: This configuration is specifically for Express.js applications using @adminjs/express. You need to add a custom middleware to handle the Keycloak OAuth callback. This middleware intercepts the authorization code from Keycloak and converts it to a POST request that AdminJS can process:

import express from 'express';
import AdminJSExpress from '@adminjs/express';

const app = express();

// ... your AdminJS setup ...

// Add a custom middleware to handle Keycloak OAuth callback (GET request with code)
app.get(admin.options.rootPath + '/login', async (req, res, next) => {
  
  // Check if this is a Keycloak callback with authorization code
  if (req.query.code) {
    console.log('Found authorization code, creating form to POST to AdminJS...');
    
    // Instead of handling authentication manually, create a form that POSTs to AdminJS
    // This way AdminJS handles the session properly
    const html = `
      <!DOCTYPE html>
      <html>
      <head>
        <title>Processing Login...</title>
      </head>
      <body>
        <div style="text-align: center; margin-top: 50px;">
          <h2>Processing your login...</h2>
          <p>Please wait while we complete your authentication.</p>
        </div>
        <form id="loginForm" method="POST" action="${admin.options.rootPath}/login" style="display: none;">
          <input type="hidden" name="code" value="${req.query.code}" />
          <input type="hidden" name="redirectUri" value="${req.protocol}://${req.get('host')}${admin.options.rootPath}/login" />
        </form>
        <script>
          document.getElementById('loginForm').submit();
        </script>
      </body>
      </html>
    `;
    
    return res.send(html);
  }
  
  // If no code, continue to the normal AdminJS login flow
  next();
});

app.get(admin.options.logoutPath, async (req, res) => {
  // Destroy the session and redirect to the login page
  const logoutUrl = await provider.handleLogout({ req, res });
  console.log('Logout URL:', logoutUrl);
  const session = (req as any).session;

  if (session && typeof session.destroy === 'function') {
    session.destroy(() => {
      res.redirect(logoutUrl);
    });
  } else {
    res.redirect(logoutUrl);
  }
});

Why this middleware is needed: Keycloak redirects back with a GET containing the authorization code, while AdminJS expects a POST — this middleware converts the code into an automatic POST so AdminJS can complete authentication. For logout, destroy the AdminJS session and redirect to Keycloak's logout URL (for example via provider.handleLogout) to fully sign the user out.

Tips & Caveats

  • AdminJS's default login flow is form-based and expects POST handlers for handleLogin. The provider prefers the authorization code to be submitted in form data (opts.data) but will also check the query string.
  • The provider returns a simple _auth object inside CurrentAdmin. If you need to persist tokens or implement full token revocation/end-session semantics on the server, implement a custom route that interacts directly with Keycloak's endpoints (the logout() url is a client-side redirect).
  • Ensure your Keycloak client is configured with the correct redirectUri and allowed grant types (Authorization Code + optionally Refresh Token/offline_access).

Contributing

See CONTRIBUTING.md for development setup and guidelines.

License

ISC — see the LICENSE file for details.