oidc-provider-knex-adapter
v0.1.1
Published
Persistent Knex adapter for oidc-provider (PostgreSQL/MySQL/SQLite), single-table JSONB storage with grant/account-level revocation
Maintainers
Readme
oidc-provider-knex-adapter
Persistent Knex adapter for oidc-provider (v7–v9). Single-table storage with JSONB payloads, built for PostgreSQL (also works with MySQL / SQLite via Knex dialects).
oidc-provider is a pure protocol engine — it does not persist anything. It defines a storage interface (upsert / find / consume / destroy / revokeByGrantId) and ships only an in-memory implementation. This package implements that interface on top of Knex so sessions, grants, codes and tokens survive restarts.
Install
npm install oidc-provider-knex-adapterPeer dependencies: knex (>=2) and your Knex dialect driver (pg, mysql2, sqlite3, …).
Usage
import Provider from 'oidc-provider';
import knexFactory from 'knex';
import { KnexAdapter } from 'oidc-provider-knex-adapter';
const knex = knexFactory({
client: 'pg',
connection: process.env.DATABASE_URL,
});
const provider = new Provider('https://id.example.com/oauth', {
adapter: (name) => new KnexAdapter(knex, name),
// ... rest of your configuration
});Database schema (PostgreSQL)
CREATE TABLE oidc_adapter (
id varchar(255) PRIMARY KEY,
kind varchar(64) NOT NULL, -- Session / Grant / AuthorizationCode / RefreshToken / Client ...
grant_id varchar(255),
uid varchar(255),
user_code varchar(255),
account_id varchar(255),
data jsonb NOT NULL, -- model payload, stored verbatim
expires_at timestamptz,
consumed_at timestamptz
);
CREATE INDEX idx_oidc_adapter_grant ON oidc_adapter (grant_id);
CREATE INDEX idx_oidc_adapter_account ON oidc_adapter (account_id);
CREATE INDEX idx_oidc_adapter_uid ON oidc_adapter (uid) WHERE uid IS NOT NULL;
CREATE INDEX idx_oidc_adapter_user_code ON oidc_adapter (user_code) WHERE user_code IS NOT NULL;All models share one table, distinguished by the kind column. Payloads are stored verbatim in a JSONB column, so anything oidc-provider puts in a model round-trips unchanged.
Revocation
Two batch-revocation helpers that are not part of the oidc-provider interface but are exactly what an IdP needs:
revokeByGrantId(grantId)— delete every row sharing a grant (used by refresh-token reuse detection; built intooidc-provider's flow).destroyByAccountId(accountId, kinds?)— delete every row belonging to a user. Call this on password change / email rebind / ban / account deletion to kill all of a user's sessions and tokens at once:
await adapter.destroyByAccountId(userSub);
// optionally scope to specific models:
await adapter.destroyByAccountId(userSub, ['Grant', 'RefreshToken', 'AuthorizationCode', 'Session']);For this to work, write accountId into the payload — it is mapped to the account_id column on upsert.
Options
| option | default | description |
|---|---|---|
| tableName | 'oidc_adapter' | table to store rows in |
| expiresAtColumn | 'expires_at' | expiry column (note: seconds are converted to a timestamp on write) |
Tests
npm testRuns against an in-memory SQLite database (Knex dialect layer keeps behavior identical; production schema above is for PostgreSQL).
License
MIT
