Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fc6033dd5 | |||
| 1304cdae56 | |||
| 3f07c3e649 | |||
| 0a9c79d08f | |||
| 44f94c7ab0 | |||
| 2f75995b3d |
@@ -19,4 +19,4 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
docker run --rm -v "$PWD:/repo" -w /repo \
|
docker run --rm -v "$PWD:/repo" -w /repo \
|
||||||
-e REGISTRY_TOKEN -e REGISTRY_USER -e REPO_TOKEN -e REPOSITORY -e SERVER_URL \
|
-e REGISTRY_TOKEN -e REGISTRY_USER -e REPO_TOKEN -e REPOSITORY -e SERVER_URL \
|
||||||
node:24.22.2-alpine3.24 node registry-cleanup/cleanup.ts
|
node:26.13.0-alpine3.24 node registry-cleanup/cleanup.ts
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
GIT_TAG: ${{ github.ref_name }}
|
GIT_TAG: ${{ github.ref_name }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
docker run --rm -v "$PWD:/repo" -w /repo node:24.22.2-alpine3.24 \
|
docker run --rm -v "$PWD:/repo" -w /repo node:26.13.0-alpine3.24 \
|
||||||
node release-tooling/contract-version.ts "$GIT_TAG" src/plugin-host/plugin.ts
|
node release-tooling/contract-version.ts "$GIT_TAG" src/plugin-host/plugin.ts
|
||||||
- name: Promote the commit-hash image to semver + latest
|
- name: Promote the commit-hash image to semver + latest
|
||||||
env:
|
env:
|
||||||
@@ -100,9 +100,9 @@ jobs:
|
|||||||
VERSION=${INPUT_VERSION:-${GIT_TAG#v}}
|
VERSION=${INPUT_VERSION:-${GIT_TAG#v}}
|
||||||
VERSION=${VERSION#v}
|
VERSION=${VERSION#v}
|
||||||
# An empty dispatch input falls back to the branch name, so gate this like a tag.
|
# An empty dispatch input falls back to the branch name, so gate this like a tag.
|
||||||
docker run --rm -v "$PWD:/repo" -w /repo node:24.22.2-alpine3.24 \
|
docker run --rm -v "$PWD:/repo" -w /repo node:26.13.0-alpine3.24 \
|
||||||
node release-tooling/contract-version.ts "$VERSION" src/plugin-host/plugin.ts
|
node release-tooling/contract-version.ts "$VERSION" src/plugin-host/plugin.ts
|
||||||
docker run --rm -v "$PWD:/repo" -w /repo \
|
docker run --rm -v "$PWD:/repo" -w /repo \
|
||||||
-e DOCKERHUB_REPO -e DOCKERHUB_TOKEN -e DOCKERHUB_USER \
|
-e DOCKERHUB_REPO -e DOCKERHUB_TOKEN -e DOCKERHUB_USER \
|
||||||
node:24.22.2-alpine3.24 \
|
node:26.13.0-alpine3.24 \
|
||||||
node release-tooling/dockerhub-overview.ts "$VERSION"
|
node release-tooling/dockerhub-overview.ts "$VERSION"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
-e RENOVATE_PLATFORM=gitea \
|
-e RENOVATE_PLATFORM=gitea \
|
||||||
-e RENOVATE_REPOSITORIES=${{ github.repository }} \
|
-e RENOVATE_REPOSITORIES=${{ github.repository }} \
|
||||||
-e RENOVATE_TOKEN \
|
-e RENOVATE_TOKEN \
|
||||||
renovate/renovate:44.199.2
|
renovate/renovate:44.222.3
|
||||||
|
|
||||||
# After the renovate job, cut ONE tag covering the renovate-bot commits merged to main since the
|
# After the renovate job, cut ONE tag covering the renovate-bot commits merged to main since the
|
||||||
# last tag (batch per run). Targets origin/main — the real post-merge tip; the checkout SHA is the
|
# last tag (batch per run). Targets origin/main — the real post-merge tip; the checkout SHA is the
|
||||||
@@ -60,11 +60,11 @@ jobs:
|
|||||||
if [ -z "$BUMPS" ]; then
|
if [ -z "$BUMPS" ]; then
|
||||||
echo "Renovate commits since ${LATEST}, but none carry Release-Bump — nothing reached a running Plainpages; skipping"; exit 0
|
echo "Renovate commits since ${LATEST}, but none carry Release-Bump — nothing reached a running Plainpages; skipping"; exit 0
|
||||||
fi
|
fi
|
||||||
NEXT=$(docker run --rm -v "$PWD:/repo" -w /repo node:24.22.2-alpine3.24 \
|
NEXT=$(docker run --rm -v "$PWD:/repo" -w /repo node:26.13.0-alpine3.24 \
|
||||||
node release-tooling/next-version.ts "$LATEST" $BUMPS)
|
node release-tooling/next-version.ts "$LATEST" $BUMPS)
|
||||||
# Read the constant off origin/main, not the checkout, which lags the merges this run made.
|
# Read the constant off origin/main, not the checkout, which lags the merges this run made.
|
||||||
git show origin/main:src/plugin-host/plugin.ts \
|
git show origin/main:src/plugin-host/plugin.ts \
|
||||||
| docker run -i --rm -v "$PWD:/repo" -w /repo node:24.22.2-alpine3.24 \
|
| docker run -i --rm -v "$PWD:/repo" -w /repo node:26.13.0-alpine3.24 \
|
||||||
node release-tooling/contract-version.ts "$NEXT" -
|
node release-tooling/contract-version.ts "$NEXT" -
|
||||||
echo "Releasing $LATEST -> $NEXT"
|
echo "Releasing $LATEST -> $NEXT"
|
||||||
git tag "$NEXT" origin/main
|
git tag "$NEXT" origin/main
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Node 24 runs TypeScript directly (type stripping) — no build step. Pinned exact tag.
|
# Node 24 runs TypeScript directly (type stripping) — no build step. Pinned exact tag.
|
||||||
FROM node:24.22.2-alpine3.24
|
FROM node:26.13.0-alpine3.24
|
||||||
|
|
||||||
# Above WORKDIR so dev's `.:/app` bind mount can't shadow them; a volume at /app/node_modules
|
# Above WORKDIR so dev's `.:/app` bind mount can't shadow them; a volume at /app/node_modules
|
||||||
# instead leaves a root-owned dir in the checkout (the daemon creates mount destinations as root).
|
# instead leaves a root-owned dir in the checkout (the daemon creates mount destinations as root).
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ services:
|
|||||||
# backs it (PLUGIN_SETTING_SCHEDULING_UPSTREAM above points here). Stand-in for the customer's real service —
|
# backs it (PLUGIN_SETTING_SCHEDULING_UPSTREAM above points here). Stand-in for the customer's real service —
|
||||||
# stdlib-only, in-memory, no auth. Prod points PLUGIN_SETTING_SCHEDULING_UPSTREAM at the real backend instead.
|
# stdlib-only, in-memory, no auth. Prod points PLUGIN_SETTING_SCHEDULING_UPSTREAM at the real backend instead.
|
||||||
shifts-upstream:
|
shifts-upstream:
|
||||||
image: node:24.22.2-alpine3.24
|
image: node:26.13.0-alpine3.24
|
||||||
command: node /srv/server.ts
|
command: node /srv/server.ts
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ services:
|
|||||||
|
|
||||||
# The reference plugin's upstream (examples/shifts-upstream) so /scheduling/shifts shows real rows.
|
# The reference plugin's upstream (examples/shifts-upstream) so /scheduling/shifts shows real rows.
|
||||||
shifts-upstream:
|
shifts-upstream:
|
||||||
image: node:24.22.2-alpine3.24
|
image: node:26.13.0-alpine3.24
|
||||||
command: ["node", "/server.ts"]
|
command: ["node", "/server.ts"]
|
||||||
volumes:
|
volumes:
|
||||||
- ./examples/shifts-upstream/server.ts:/server.ts:ro
|
- ./examples/shifts-upstream/server.ts:/server.ts:ro
|
||||||
@@ -66,7 +66,7 @@ services:
|
|||||||
# Mock OIDC provider for the SSO login test — stdlib Node, auto-approves, signs an id_token Kratos
|
# Mock OIDC provider for the SSO login test — stdlib Node, auto-approves, signs an id_token Kratos
|
||||||
# verifies via its jwks. Reachable as the same host (mock-oidc:9000) by both the browser and Kratos.
|
# verifies via its jwks. Reachable as the same host (mock-oidc:9000) by both the browser and Kratos.
|
||||||
mock-oidc:
|
mock-oidc:
|
||||||
image: node:24.22.2-alpine3.24
|
image: node:26.13.0-alpine3.24
|
||||||
command: ["node", "/mock-oidc.ts"]
|
command: ["node", "/mock-oidc.ts"]
|
||||||
environment:
|
environment:
|
||||||
ISSUER: http://mock-oidc:9000
|
ISSUER: http://mock-oidc:9000
|
||||||
@@ -92,7 +92,7 @@ services:
|
|||||||
|
|
||||||
# Same-origin gateway: Kratos-owned paths → kratos, everything else → web (e2e-tests/proxy.ts).
|
# Same-origin gateway: Kratos-owned paths → kratos, everything else → web (e2e-tests/proxy.ts).
|
||||||
proxy:
|
proxy:
|
||||||
image: node:24.22.2-alpine3.24
|
image: node:26.13.0-alpine3.24
|
||||||
command: ["node", "/proxy.ts"]
|
command: ["node", "/proxy.ts"]
|
||||||
depends_on:
|
depends_on:
|
||||||
web:
|
web:
|
||||||
|
|||||||
Generated
+8
-8
@@ -7,7 +7,7 @@
|
|||||||
"name": "plainpages-e2e",
|
"name": "plainpages-e2e",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "1.64.1",
|
"@playwright/test": "1.64.1",
|
||||||
"@types/node": "24.19.2",
|
"@types/node": "26.6.6",
|
||||||
"typescript": "7.0.2"
|
"typescript": "7.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.19.2",
|
"version": "26.6.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.6.tgz",
|
||||||
"integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==",
|
"integrity": "sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": ">=7.24.0 <7.24.7"
|
"undici-types": "~8.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/typescript-aix-ppc64": {
|
"node_modules/@typescript/typescript-aix-ppc64": {
|
||||||
@@ -442,9 +442,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.24.6",
|
"version": "8.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
|
||||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
"integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "1.64.1",
|
"@playwright/test": "1.64.1",
|
||||||
"@types/node": "24.19.2",
|
"@types/node": "26.6.6",
|
||||||
"typescript": "7.0.2"
|
"typescript": "7.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+13
-13
@@ -9,12 +9,12 @@
|
|||||||
"@larvit/log": "2.4.0",
|
"@larvit/log": "2.4.0",
|
||||||
"ejs": "7.0.2",
|
"ejs": "7.0.2",
|
||||||
"lucide-static": "1.70.0",
|
"lucide-static": "1.70.0",
|
||||||
"postgres": "3.4.9"
|
"postgres": "4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mdn/browser-compat-data": "8.1.8",
|
"@mdn/browser-compat-data": "8.1.8",
|
||||||
"@types/ejs": "3.1.5",
|
"@types/ejs": "3.1.5",
|
||||||
"@types/node": "24.19.2",
|
"@types/node": "26.6.6",
|
||||||
"acorn": "8.19.0",
|
"acorn": "8.19.0",
|
||||||
"typescript": "7.0.2"
|
"typescript": "7.0.2"
|
||||||
},
|
},
|
||||||
@@ -46,13 +46,13 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.19.2",
|
"version": "26.6.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.6.tgz",
|
||||||
"integrity": "sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==",
|
"integrity": "sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": ">=7.24.0 <7.24.7"
|
"undici-types": "~8.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript/typescript-aix-ppc64": {
|
"node_modules/@typescript/typescript-aix-ppc64": {
|
||||||
@@ -427,12 +427,12 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/postgres": {
|
"node_modules/postgres": {
|
||||||
"version": "3.4.9",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/postgres/-/postgres-4.1.0.tgz",
|
||||||
"integrity": "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw==",
|
"integrity": "sha512-s+0WH67YAyLdBQUb6XczbziBhY+C9uiQsg9S8R5RHdZhk6sdyK6202E+T2tXpiInSEEjDLRSJ3OpYBe3PN6MsQ==",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -475,9 +475,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.24.6",
|
"version": "8.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
|
||||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
"integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -19,12 +19,12 @@
|
|||||||
"@larvit/log": "2.4.0",
|
"@larvit/log": "2.4.0",
|
||||||
"ejs": "7.0.2",
|
"ejs": "7.0.2",
|
||||||
"lucide-static": "1.70.0",
|
"lucide-static": "1.70.0",
|
||||||
"postgres": "3.4.9"
|
"postgres": "4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mdn/browser-compat-data": "8.1.8",
|
"@mdn/browser-compat-data": "8.1.8",
|
||||||
"@types/ejs": "3.1.5",
|
"@types/ejs": "3.1.5",
|
||||||
"@types/node": "24.19.2",
|
"@types/node": "26.6.6",
|
||||||
"acorn": "8.19.0",
|
"acorn": "8.19.0",
|
||||||
"typescript": "7.0.2"
|
"typescript": "7.0.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
import { test } from "node:test";
|
import { test } from "node:test";
|
||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import { readFileSync } from "node:fs";
|
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 { generateJwks, rotateJwks } from "./gen-jwks.ts";
|
||||||
|
import type { JsonWebKey } from "./jwks.ts";
|
||||||
import { verifyJws } from "./jwt.ts";
|
import { verifyJws } from "./jwt.ts";
|
||||||
|
|
||||||
const b64url = (s: string) => Buffer.from(s).toString("base64url");
|
const b64url = (s: string) => Buffer.from(s).toString("base64url");
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import assert from "node:assert/strict";
|
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 { dirname, join } from "node:path";
|
||||||
import { test } from "node:test";
|
import { test } from "node:test";
|
||||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
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 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");
|
const committed = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "ory/kratos/tokenizer/jwks.json");
|
||||||
|
|||||||
+5
-1
@@ -1,4 +1,4 @@
|
|||||||
import type { JsonWebKey } from "node:crypto";
|
import type { webcrypto } from "node:crypto";
|
||||||
import { readFileSync } from "node:fs";
|
import { readFileSync } from "node:fs";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import { currentLog } from "../logger.ts";
|
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-
|
// (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`
|
// 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).
|
// 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 {
|
export interface JwksProvider {
|
||||||
getKey(kid: string | undefined): Promise<JsonWebKey | null>;
|
getKey(kid: string | undefined): Promise<JsonWebKey | null>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import assert from "node:assert/strict";
|
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 { 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 { authenticate, claimsToUser, resolveSession, verifyToken } from "./jwt-middleware.ts";
|
||||||
import { SESSION_COOKIE } from "./login.ts";
|
import { SESSION_COOKIE } from "./login.ts";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import { generateKeyPairSync, sign } from "node:crypto";
|
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 { test } from "node:test";
|
||||||
import { decodeJws, verifyJws } from "./jwt.ts";
|
import { decodeJws, verifyJws } from "./jwt.ts";
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
import { createPublicKey, verify } from "node:crypto";
|
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:
|
// JWS signature verification with the Node stdlib — no `jose`/JWT dep:
|
||||||
// `createPublicKey({format:"jwk"})` imports a JWK and verifies the RS*/ES* signatures
|
// `createPublicKey({format:"jwk"})` imports a JWK and verifies the RS*/ES* signatures
|
||||||
|
|||||||
@@ -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.
|
// 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> {
|
function connect(adminUrl: string): ReturnType<typeof postgres> {
|
||||||
try {
|
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 });
|
return postgres(adminUrl, { connect_timeout: 10, max: 1 });
|
||||||
} catch {
|
} 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)");
|
throw new Error("PLUGIN_DB_ADMIN_URL must be a Postgres URL (its value is not shown; percent-encode special characters in a password)");
|
||||||
|
|||||||
@@ -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 { AddressInfo } from "node:net";
|
||||||
import type { TestContext } from "node:test";
|
import type { TestContext } from "node:test";
|
||||||
import type { HydraAdmin } from "../auth/hydra-admin.ts";
|
import type { HydraAdmin } from "../auth/hydra-admin.ts";
|
||||||
|
|||||||
Reference in New Issue
Block a user