openvibers/openvibe.search Commits
Added a fixed JWKS failure warning in server/auth.js. It leaves the…
Changes
@@@ -102,8 +102,9 @@ function createAuth({ config, jwks, log = console }) {let keys;try {keys = await jwks.keysForKid(kid);-- } catch (err) {-- // The SDK's message names the internal JWKS URL and the fetch error: the client logs it, nobody is told.++ } catch {++ // The SDK's error can contain the internal URL or other sensitive details.++ log.warn('[auth] JWKS key lookup failed; signing key not loaded yet');return { ok: false, code: 'token.unavailable', reason: 'signing key not loaded yet' };}// The key the token names, else every key (a kid-less token, or a document without kids); first verdict that@@@ -4,6 +4,7 @@// verifies, the cached keys keep verifying through a stub outage (an unknown kid forces a refetch),// and /api/ready reports the client's state.const assert = require('assert');++const { createAuth } = require('../server/auth');const { boot, request, serviceToken, userToken, doc, suite, jwksDocument } = require('./helpers');const t = suite('jwks');@@@ -16,6 +17,21 @@ const jwksFetch = async () => {};const write = (token, d) => request(svc.base, 'PUT', `/api/v1/documents/wiki/page/${d.id}`, { token, body: d });++t('a failed service-token key lookup logs a safe diagnostic and keeps the unavailable result', async () => {++ const warnings = [];++ const token = serviceToken('wiki', ['search.document.write']);++ const auth = createAuth({++ config: {},++ jwks: { keysForKid: async () => { throw new Error(`secret-value ${token} https://network.internal/api/.well-known/jwks`); } },++ log: { warn: (message) => warnings.push(message) },++ });++ assert.deepStrictEqual(await auth.verifyService(token), {++ ok: false, code: 'token.unavailable', reason: 'signing key not loaded yet',++ });++ assert.deepStrictEqual(warnings, ['[auth] JWKS key lookup failed; signing key not loaded yet']);++ assert.ok(!warnings[0].includes(token) && !warnings[0].includes('secret-value') && !warnings[0].includes('network.internal'));++});++t('a token signed by a key from the stub JWKS verifies', async () => {svc = await boot({ jwksFetch });await svc.keyLoaded;
@@ -102,8 +102,9 @@ function createAuth({ config, jwks, log = console }) {
@@ -102,8 +102,9 @@ function createAuth({ config, jwks, log = console }) {
let keys;
let keys;
try {
try {
keys = await jwks.keysForKid(kid);
keys = await jwks.keysForKid(kid);
- } catch (err) {
- // The SDK's message names the internal JWKS URL and the fetch error: the client logs it, nobody is told.
+ } catch {
+ // The SDK's error can contain the internal URL or other sensitive details.
+ log.warn('[auth] JWKS key lookup failed; signing key not loaded yet');
return { ok: false, code: 'token.unavailable', reason: 'signing key not loaded yet' };
return { ok: false, code: 'token.unavailable', reason: 'signing key not loaded yet' };
}
}
// The key the token names, else every key (a kid-less token, or a document without kids); first verdict that
// The key the token names, else every key (a kid-less token, or a document without kids); first verdict that
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
// verifies, the cached keys keep verifying through a stub outage (an unknown kid forces a refetch),
// verifies, the cached keys keep verifying through a stub outage (an unknown kid forces a refetch),
// and /api/ready reports the client's state.
// and /api/ready reports the client's state.
const assert = require('assert');
const assert = require('assert');
+const { createAuth } = require('../server/auth');
const { boot, request, serviceToken, userToken, doc, suite, jwksDocument } = require('./helpers');
const { boot, request, serviceToken, userToken, doc, suite, jwksDocument } = require('./helpers');
const t = suite('jwks');
const t = suite('jwks');
@@ -16,6 +17,21 @@ const jwksFetch = async () => {
@@ -16,6 +17,21 @@ const jwksFetch = async () => {
};
};
const write = (token, d) => request(svc.base, 'PUT', `/api/v1/documents/wiki/page/${d.id}`, { token, body: d });
const write = (token, d) => request(svc.base, 'PUT', `/api/v1/documents/wiki/page/${d.id}`, { token, body: d });
+t('a failed service-token key lookup logs a safe diagnostic and keeps the unavailable result', async () => {
+ const warnings = [];
+ const token = serviceToken('wiki', ['search.document.write']);
+ const auth = createAuth({
+ config: {},
+ jwks: { keysForKid: async () => { throw new Error(`secret-value ${token} https://network.internal/api/.well-known/jwks`); } },
+ log: { warn: (message) => warnings.push(message) },
+ });
+ assert.deepStrictEqual(await auth.verifyService(token), {
+ ok: false, code: 'token.unavailable', reason: 'signing key not loaded yet',
+ });
+ assert.deepStrictEqual(warnings, ['[auth] JWKS key lookup failed; signing key not loaded yet']);
+ assert.ok(!warnings[0].includes(token) && !warnings[0].includes('secret-value') && !warnings[0].includes('network.internal'));
+});
+
t('a token signed by a key from the stub JWKS verifies', async () => {
t('a token signed by a key from the stub JWKS verifies', async () => {
svc = await boot({ jwksFetch });
svc = await boot({ jwksFetch });
await svc.keyLoaded;
await svc.keyLoaded;