javascript-solid-server 0.0.157 → 0.0.158
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/config.js +23 -0
- package/test/config.test.js +95 -1
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -324,6 +324,29 @@ export async function loadConfig(cliOptions = {}, configFile = null) {
|
|
|
324
324
|
config.conneg = true;
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
// Single-user mode strongly implies the built-in IdP. Operators seeding
|
|
328
|
+
// a password for `me` on localhost almost always want the IdP enabled
|
|
329
|
+
// so clients can authenticate. Imply --idp unless the user explicitly
|
|
330
|
+
// disabled it from any config source — CLI, env, or config file (see #331).
|
|
331
|
+
if (config.singleUser && !config.idp) {
|
|
332
|
+
const idpExplicitlyDisabled =
|
|
333
|
+
cliOptions.idp === false ||
|
|
334
|
+
envConfig.idp === false ||
|
|
335
|
+
fileConfig.idp === false;
|
|
336
|
+
if (idpExplicitlyDisabled) {
|
|
337
|
+
// Respect the explicit disable. Warn only when there is no external
|
|
338
|
+
// --idp-issuer either: without the built-in IdP and without an
|
|
339
|
+
// external issuer, /.well-known/openid-configuration returns 404
|
|
340
|
+
// and clients fail with confusing OIDC discovery errors. If the
|
|
341
|
+
// operator pointed JSS at an external issuer, no footgun applies.
|
|
342
|
+
if (!config.idpIssuer) {
|
|
343
|
+
console.warn('⚠️ --single-user is enabled but --idp is disabled and no --idp-issuer is set. Clients won\'t be able to authenticate. Use --idp, or pass an external --idp-issuer.');
|
|
344
|
+
}
|
|
345
|
+
} else {
|
|
346
|
+
config.idp = true;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
327
350
|
// Validate SSL config
|
|
328
351
|
if ((config.sslKey && !config.sslCert) || (!config.sslKey && config.sslCert)) {
|
|
329
352
|
throw new Error('Both --ssl-key and --ssl-cert must be provided together');
|
package/test/config.test.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* become a real boolean and break downstream code (bcrypt, etc.).
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { describe, it, before, after } from 'node:test';
|
|
10
|
+
import { describe, it, before, after, beforeEach } from 'node:test';
|
|
11
11
|
import assert from 'node:assert';
|
|
12
12
|
import { loadConfig } from '../src/config.js';
|
|
13
13
|
|
|
@@ -64,3 +64,97 @@ describe('config — env var boolean coercion', () => {
|
|
|
64
64
|
assert.strictEqual(cfg2.multiuser, true);
|
|
65
65
|
});
|
|
66
66
|
});
|
|
67
|
+
|
|
68
|
+
// Regression coverage for #331: --single-user without --idp boots a server
|
|
69
|
+
// that returns 404 for /.well-known/openid-configuration, which is a
|
|
70
|
+
// footgun. loadConfig() now implies --idp when --single-user is set,
|
|
71
|
+
// unless the user explicitly disables IdP via --no-idp / JSS_IDP=false /
|
|
72
|
+
// idp:false in config file.
|
|
73
|
+
describe('config — --single-user implies --idp (#331)', () => {
|
|
74
|
+
// Hermetic env-var handling so the runner's environment doesn't leak.
|
|
75
|
+
// JSS_LOG_LEVEL is included because loadConfig() can emit a warning
|
|
76
|
+
// for invalid log levels and we don't want that to pollute assertions
|
|
77
|
+
// about the #331-specific warning.
|
|
78
|
+
const KEYS = ['JSS_IDP', 'JSS_SINGLE_USER', 'JSS_IDP_ISSUER', 'JSS_LOG_LEVEL'];
|
|
79
|
+
const original = {};
|
|
80
|
+
let originalWarn;
|
|
81
|
+
let warnings;
|
|
82
|
+
|
|
83
|
+
before(() => {
|
|
84
|
+
for (const k of KEYS) original[k] = process.env[k];
|
|
85
|
+
originalWarn = console.warn;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
after(() => {
|
|
89
|
+
for (const k of KEYS) {
|
|
90
|
+
if (original[k] === undefined) delete process.env[k];
|
|
91
|
+
else process.env[k] = original[k];
|
|
92
|
+
}
|
|
93
|
+
console.warn = originalWarn;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Capture warnings so we can assert on them without polluting test output.
|
|
97
|
+
// We filter to the #331-specific warning so unrelated warnings (e.g. from
|
|
98
|
+
// a noisy runner env) don't break the assertions.
|
|
99
|
+
const isIdpFootgunWarning = (msg) =>
|
|
100
|
+
msg.includes('--single-user') && msg.includes('--idp');
|
|
101
|
+
|
|
102
|
+
beforeEach(() => {
|
|
103
|
+
for (const k of KEYS) delete process.env[k];
|
|
104
|
+
warnings = [];
|
|
105
|
+
console.warn = (msg) => warnings.push(String(msg));
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('implies --idp when --single-user is set and --idp is not specified', async () => {
|
|
109
|
+
const cfg = await loadConfig({ singleUser: true }, null);
|
|
110
|
+
assert.strictEqual(cfg.idp, true,
|
|
111
|
+
'--single-user should imply --idp by default');
|
|
112
|
+
assert.ok(!warnings.some(isIdpFootgunWarning),
|
|
113
|
+
'no #331 warning when implying (this is the happy path)');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('does not imply --idp when --single-user is not set', async () => {
|
|
117
|
+
const cfg = await loadConfig({}, null);
|
|
118
|
+
assert.notStrictEqual(cfg.idp, true,
|
|
119
|
+
'--idp should not be implied without --single-user');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('respects explicit --idp=true with --single-user', async () => {
|
|
123
|
+
const cfg = await loadConfig({ singleUser: true, idp: true }, null);
|
|
124
|
+
assert.strictEqual(cfg.idp, true);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('respects explicit --no-idp with --single-user (warns but does not flip)', async () => {
|
|
128
|
+
const cfg = await loadConfig({ singleUser: true, idp: false }, null);
|
|
129
|
+
assert.strictEqual(cfg.idp, false,
|
|
130
|
+
'explicit --no-idp should override the implication');
|
|
131
|
+
assert.ok(warnings.some(isIdpFootgunWarning),
|
|
132
|
+
'should warn about the footgun when --single-user + --no-idp + no --idp-issuer');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('respects explicit JSS_IDP=false with --single-user (warns but does not flip)', async () => {
|
|
136
|
+
process.env.JSS_IDP = 'false';
|
|
137
|
+
const cfg = await loadConfig({ singleUser: true }, null);
|
|
138
|
+
assert.strictEqual(cfg.idp, false,
|
|
139
|
+
'explicit JSS_IDP=false should override the implication');
|
|
140
|
+
assert.ok(warnings.some(isIdpFootgunWarning),
|
|
141
|
+
'should warn when JSS_IDP=false + --single-user + no --idp-issuer');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('does not warn when --no-idp + --single-user but --idp-issuer is set', async () => {
|
|
145
|
+
const cfg = await loadConfig({
|
|
146
|
+
singleUser: true,
|
|
147
|
+
idp: false,
|
|
148
|
+
idpIssuer: 'https://external-issuer.example/'
|
|
149
|
+
}, null);
|
|
150
|
+
assert.strictEqual(cfg.idp, false);
|
|
151
|
+
assert.ok(!warnings.some(isIdpFootgunWarning),
|
|
152
|
+
'no footgun if an external --idp-issuer is configured');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('does not warn when --single-user is unset', async () => {
|
|
156
|
+
await loadConfig({ idp: false }, null);
|
|
157
|
+
assert.ok(!warnings.some(isIdpFootgunWarning),
|
|
158
|
+
'--no-idp without --single-user should not trigger the #331 warning');
|
|
159
|
+
});
|
|
160
|
+
});
|