Merge remote-tracking branch 'origin/main' into item-62
CI / full-gate (push) Successful in 4m0s
Mirror / github-mirror (push) Successful in 4s

This commit was merged in pull request #231.
This commit is contained in:
2026-11-09 00:05:38 +01:00
20 changed files with 75 additions and 62 deletions
+2 -1
View File
@@ -4,8 +4,9 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { createPrivateKey, sign, type JsonWebKey } from "node:crypto";
import { createPrivateKey, sign } from "node:crypto";
import { generateJwks, rotateJwks } from "./gen-jwks.ts";
import type { JsonWebKey } from "./jwks.ts";
import { verifyJws } from "./jwt.ts";
const b64url = (s: string) => Buffer.from(s).toString("base64url");
+2 -2
View File
@@ -1,9 +1,9 @@
import assert from "node:assert/strict";
import { generateKeyPairSync, type JsonWebKey } from "node:crypto";
import { generateKeyPairSync } from "node:crypto";
import { dirname, join } from "node:path";
import { test } from "node:test";
import { fileURLToPath, pathToFileURL } from "node:url";
import { cachingJwks, createJwksProvider, loadJwks, staticJwks } from "./jwks.ts";
import { cachingJwks, createJwksProvider, loadJwks, staticJwks, type JsonWebKey } from "./jwks.ts";
const jwk = (kid: string): JsonWebKey => ({ ...(generateKeyPairSync("ec", { namedCurve: "P-256" }).publicKey.export({ format: "jwk" }) as JsonWebKey), alg: "ES256", kid });
const committed = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "ory/kratos/tokenizer/jwks.json");
+5 -1
View File
@@ -1,4 +1,4 @@
import type { JsonWebKey } from "node:crypto";
import type { webcrypto } from "node:crypto";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { currentLog } from "../logger.ts";
@@ -8,6 +8,10 @@ import { currentLog } from "../logger.ts";
// (or re-reads a mounted file), caches for a TTL, and reloads once on a `kid` miss so a rotated-
// in key is picked up without a restart (README: zero-downtime rotation). `createJwksProvider`
// picks the right one from the configured URL scheme and primes it at boot (fail loud).
// node:crypto exports the JWK type only under webcrypto since @types/node 26, and that type lacks
// the `kid` a JWKS selects a key by.
export type JsonWebKey = webcrypto.JsonWebKey & { kid?: string };
export interface JwksProvider {
getKey(kid: string | undefined): Promise<JsonWebKey | null>;
}
+2 -2
View File
@@ -1,7 +1,7 @@
import assert from "node:assert/strict";
import { generateKeyPairSync, sign, type JsonWebKey, type KeyObject } from "node:crypto";
import { generateKeyPairSync, sign, type KeyObject } from "node:crypto";
import { test } from "node:test";
import { staticJwks } from "./jwks.ts";
import { staticJwks, type JsonWebKey } from "./jwks.ts";
import { authenticate, claimsToUser, resolveSession, verifyToken } from "./jwt-middleware.ts";
import { SESSION_COOKIE } from "./login.ts";
+2 -1
View File
@@ -1,6 +1,7 @@
import assert from "node:assert/strict";
import { generateKeyPairSync, sign } from "node:crypto";
import type { JsonWebKey, KeyObject } from "node:crypto";
import type { KeyObject } from "node:crypto";
import type { JsonWebKey } from "./jwks.ts";
import { test } from "node:test";
import { decodeJws, verifyJws } from "./jwt.ts";
+2 -1
View File
@@ -1,5 +1,6 @@
import { createPublicKey, verify } from "node:crypto";
import type { JsonWebKey, KeyObject } from "node:crypto";
import type { KeyObject } from "node:crypto";
import type { JsonWebKey } from "./jwks.ts";
// JWS signature verification with the Node stdlib — no `jose`/JWT dep:
// `createPublicKey({format:"jwk"})` imports a JWK and verifies the RS*/ES* signatures
+1
View File
@@ -20,6 +20,7 @@ export interface ProvisionResult {
// so it is swallowed here. The driver, not `new URL`, decides what parses: it takes a multi-host DSN.
function connect(adminUrl: string): ReturnType<typeof postgres> {
try {
new URL(adminUrl); // postgres 4 connects to whatever a malformed DSN parses to, and its error names that host
return postgres(adminUrl, { connect_timeout: 10, max: 1 });
} catch {
throw new Error("PLUGIN_DB_ADMIN_URL must be a Postgres URL (its value is not shown; percent-encode special characters in a password)");
+2 -1
View File
@@ -1,4 +1,5 @@
import { generateKeyPairSync, sign, type JsonWebKey } from "node:crypto";
import { generateKeyPairSync, sign } from "node:crypto";
import type { JsonWebKey } from "../auth/jwks.ts";
import type { AddressInfo } from "node:net";
import type { TestContext } from "node:test";
import type { HydraAdmin } from "../auth/hydra-admin.ts";