strapi-plugin-oidc 1.9.3 → 1.9.4

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/README.md CHANGED
@@ -32,7 +32,7 @@ module.exports = ({ env }) => ({
32
32
  enabled: true,
33
33
  config: {
34
34
  // Required
35
- OIDC_DISCOVERY_URL: env('OIDC_DISCOVERY_URL'), // https://your-provider/.well-known/openid-configuration
35
+ OIDC_ISSUER: env('OIDC_ISSUER'), // https://your-provider or https://your-provider/realms/your-realm
36
36
  OIDC_CLIENT_ID: env('OIDC_CLIENT_ID'),
37
37
  OIDC_CLIENT_SECRET: env('OIDC_CLIENT_SECRET'),
38
38
  OIDC_REDIRECT_URI: env('OIDC_REDIRECT_URI'), // https://your-strapi.com/strapi-plugin-oidc/oidc/callback
@@ -55,7 +55,7 @@ module.exports = ({ env }) => ({
55
55
  });
56
56
  ```
57
57
 
58
- `OIDC_DISCOVERY_URL` is the URL of your provider's OpenID Connect discovery document (`/.well-known/openid-configuration`). The plugin fetches it at startup and automatically configures all endpoints, JWKS URI, and issuer.
58
+ `OIDC_ISSUER` is your provider's issuer URL (e.g. `https://auth.example.com` or `https://auth.example.com/realms/myrealm`). The plugin appends `/.well-known/openid-configuration` automatically if not present, and fetches the discovery document at startup to configure all endpoints, JWKS URI, and canonical issuer.
59
59
 
60
60
  ### Security features
61
61
 
@@ -102,7 +102,6 @@ const coerceBoolNullable = zod.z.preprocess(
102
102
  );
103
103
  const pluginConfigSchema = zod.z.object({
104
104
  REMEMBER_ME: coerceBool(false),
105
- OIDC_DISCOVERY_URL: zod.z.string().default(""),
106
105
  OIDC_REDIRECT_URI: zod.z.string().default(""),
107
106
  OIDC_CLIENT_ID: zod.z.string().default(""),
108
107
  OIDC_CLIENT_SECRET: zod.z.string().default(""),
@@ -172,6 +171,7 @@ const CACHE_TTL = {
172
171
  const DEFAULT_RETENTION_DAYS = 90;
173
172
  const DAY_MS = 864e5;
174
173
  const DISCOVERY_TIMEOUT_MS = 5e3;
174
+ const OIDC_DISCOVERY_PATH = "/.well-known/openid-configuration";
175
175
  const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
176
176
  function getPluginConfig() {
177
177
  return pluginConfigSchema.parse(strapi.config.get("plugin::strapi-plugin-oidc") ?? {});
@@ -198,7 +198,6 @@ const discoveryDocumentSchema = zod.z.object({
198
198
  jwks_uri: zod.z.string().optional()
199
199
  }).passthrough();
200
200
  const FIELD_MAP = [
201
- ["issuer", "OIDC_ISSUER"],
202
201
  ["authorization_endpoint", "OIDC_AUTHORIZATION_ENDPOINT"],
203
202
  ["token_endpoint", "OIDC_TOKEN_ENDPOINT"],
204
203
  ["userinfo_endpoint", "OIDC_USERINFO_ENDPOINT"],
@@ -207,8 +206,17 @@ const FIELD_MAP = [
207
206
  ];
208
207
  async function applyDiscovery(strapi2) {
209
208
  const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
210
- const discoveryUrl = config2.OIDC_DISCOVERY_URL;
211
- if (!discoveryUrl) return;
209
+ const issuer = config2.OIDC_ISSUER;
210
+ if (!issuer) return;
211
+ let discoveryUrl;
212
+ let canonicalIssuer;
213
+ if (issuer.includes(OIDC_DISCOVERY_PATH)) {
214
+ discoveryUrl = issuer;
215
+ canonicalIssuer = issuer.replace(OIDC_DISCOVERY_PATH, "");
216
+ } else {
217
+ discoveryUrl = issuer.replace(/\/$/, "") + OIDC_DISCOVERY_PATH;
218
+ canonicalIssuer = issuer.replace(/\/$/, "");
219
+ }
212
220
  let doc;
213
221
  try {
214
222
  const res = await fetch(discoveryUrl, { signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS) });
@@ -222,13 +230,13 @@ async function applyDiscovery(strapi2) {
222
230
  );
223
231
  return;
224
232
  }
225
- const updates = {};
233
+ const updates = { OIDC_ISSUER: canonicalIssuer };
226
234
  for (const [docField, configKey] of FIELD_MAP) {
227
235
  if (doc[docField]) {
228
236
  updates[configKey] = doc[docField];
229
237
  }
230
238
  }
231
- if (Object.keys(updates).length > 0) {
239
+ if (Object.keys(updates).length > 1) {
232
240
  strapi2.config.set("plugin::strapi-plugin-oidc", { ...config2, ...updates });
233
241
  strapi2.log.info(`[strapi-plugin-oidc] Discovery applied: ${Object.keys(updates).join(", ")}`);
234
242
  }
@@ -385,7 +393,6 @@ function destroy() {
385
393
  const config = {
386
394
  default: {
387
395
  REMEMBER_ME: false,
388
- OIDC_DISCOVERY_URL: "",
389
396
  OIDC_REDIRECT_URI: "http://localhost:1337/strapi-plugin-oidc/oidc/callback",
390
397
  OIDC_CLIENT_ID: "",
391
398
  OIDC_CLIENT_SECRET: "",
@@ -401,7 +408,7 @@ const config = {
401
408
  OIDC_REQUIRE_EMAIL_VERIFIED: true,
402
409
  OIDC_TRUSTED_IP_HEADER: "",
403
410
  OIDC_FORCE_SECURE_COOKIES: false,
404
- // Populated at bootstrap from OIDC_DISCOVERY_URL — not user-configurable directly
411
+ // Populated at bootstrap from OIDC_ISSUER — not user-configurable directly
405
412
  OIDC_AUTHORIZATION_ENDPOINT: "",
406
413
  OIDC_TOKEN_ENDPOINT: "",
407
414
  OIDC_USERINFO_ENDPOINT: "",
@@ -522,14 +529,14 @@ function toMessage(e) {
522
529
  return e instanceof Error ? e.message : String(e);
523
530
  }
524
531
  const REQUIRED_CONFIG_KEYS = [
525
- "OIDC_DISCOVERY_URL",
532
+ "OIDC_ISSUER",
526
533
  "OIDC_CLIENT_ID",
527
534
  "OIDC_CLIENT_SECRET",
528
535
  "OIDC_REDIRECT_URI",
529
536
  "OIDC_SCOPE",
530
537
  "OIDC_FAMILY_NAME_FIELD",
531
538
  "OIDC_GIVEN_NAME_FIELD",
532
- // Populated at bootstrap from OIDC_DISCOVERY_URL — checked here as a runtime safety net
539
+ // Populated at bootstrap from OIDC_ISSUER — checked here as a runtime safety net
533
540
  "OIDC_TOKEN_ENDPOINT",
534
541
  "OIDC_USERINFO_ENDPOINT",
535
542
  "OIDC_AUTHORIZATION_ENDPOINT"
@@ -96,7 +96,6 @@ const coerceBoolNullable = z.preprocess(
96
96
  );
97
97
  const pluginConfigSchema = z.object({
98
98
  REMEMBER_ME: coerceBool(false),
99
- OIDC_DISCOVERY_URL: z.string().default(""),
100
99
  OIDC_REDIRECT_URI: z.string().default(""),
101
100
  OIDC_CLIENT_ID: z.string().default(""),
102
101
  OIDC_CLIENT_SECRET: z.string().default(""),
@@ -166,6 +165,7 @@ const CACHE_TTL = {
166
165
  const DEFAULT_RETENTION_DAYS = 90;
167
166
  const DAY_MS = 864e5;
168
167
  const DISCOVERY_TIMEOUT_MS = 5e3;
168
+ const OIDC_DISCOVERY_PATH = "/.well-known/openid-configuration";
169
169
  const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
170
170
  function getPluginConfig() {
171
171
  return pluginConfigSchema.parse(strapi.config.get("plugin::strapi-plugin-oidc") ?? {});
@@ -192,7 +192,6 @@ const discoveryDocumentSchema = z.object({
192
192
  jwks_uri: z.string().optional()
193
193
  }).passthrough();
194
194
  const FIELD_MAP = [
195
- ["issuer", "OIDC_ISSUER"],
196
195
  ["authorization_endpoint", "OIDC_AUTHORIZATION_ENDPOINT"],
197
196
  ["token_endpoint", "OIDC_TOKEN_ENDPOINT"],
198
197
  ["userinfo_endpoint", "OIDC_USERINFO_ENDPOINT"],
@@ -201,8 +200,17 @@ const FIELD_MAP = [
201
200
  ];
202
201
  async function applyDiscovery(strapi2) {
203
202
  const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
204
- const discoveryUrl = config2.OIDC_DISCOVERY_URL;
205
- if (!discoveryUrl) return;
203
+ const issuer = config2.OIDC_ISSUER;
204
+ if (!issuer) return;
205
+ let discoveryUrl;
206
+ let canonicalIssuer;
207
+ if (issuer.includes(OIDC_DISCOVERY_PATH)) {
208
+ discoveryUrl = issuer;
209
+ canonicalIssuer = issuer.replace(OIDC_DISCOVERY_PATH, "");
210
+ } else {
211
+ discoveryUrl = issuer.replace(/\/$/, "") + OIDC_DISCOVERY_PATH;
212
+ canonicalIssuer = issuer.replace(/\/$/, "");
213
+ }
206
214
  let doc;
207
215
  try {
208
216
  const res = await fetch(discoveryUrl, { signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS) });
@@ -216,13 +224,13 @@ async function applyDiscovery(strapi2) {
216
224
  );
217
225
  return;
218
226
  }
219
- const updates = {};
227
+ const updates = { OIDC_ISSUER: canonicalIssuer };
220
228
  for (const [docField, configKey] of FIELD_MAP) {
221
229
  if (doc[docField]) {
222
230
  updates[configKey] = doc[docField];
223
231
  }
224
232
  }
225
- if (Object.keys(updates).length > 0) {
233
+ if (Object.keys(updates).length > 1) {
226
234
  strapi2.config.set("plugin::strapi-plugin-oidc", { ...config2, ...updates });
227
235
  strapi2.log.info(`[strapi-plugin-oidc] Discovery applied: ${Object.keys(updates).join(", ")}`);
228
236
  }
@@ -379,7 +387,6 @@ function destroy() {
379
387
  const config = {
380
388
  default: {
381
389
  REMEMBER_ME: false,
382
- OIDC_DISCOVERY_URL: "",
383
390
  OIDC_REDIRECT_URI: "http://localhost:1337/strapi-plugin-oidc/oidc/callback",
384
391
  OIDC_CLIENT_ID: "",
385
392
  OIDC_CLIENT_SECRET: "",
@@ -395,7 +402,7 @@ const config = {
395
402
  OIDC_REQUIRE_EMAIL_VERIFIED: true,
396
403
  OIDC_TRUSTED_IP_HEADER: "",
397
404
  OIDC_FORCE_SECURE_COOKIES: false,
398
- // Populated at bootstrap from OIDC_DISCOVERY_URL — not user-configurable directly
405
+ // Populated at bootstrap from OIDC_ISSUER — not user-configurable directly
399
406
  OIDC_AUTHORIZATION_ENDPOINT: "",
400
407
  OIDC_TOKEN_ENDPOINT: "",
401
408
  OIDC_USERINFO_ENDPOINT: "",
@@ -516,14 +523,14 @@ function toMessage(e) {
516
523
  return e instanceof Error ? e.message : String(e);
517
524
  }
518
525
  const REQUIRED_CONFIG_KEYS = [
519
- "OIDC_DISCOVERY_URL",
526
+ "OIDC_ISSUER",
520
527
  "OIDC_CLIENT_ID",
521
528
  "OIDC_CLIENT_SECRET",
522
529
  "OIDC_REDIRECT_URI",
523
530
  "OIDC_SCOPE",
524
531
  "OIDC_FAMILY_NAME_FIELD",
525
532
  "OIDC_GIVEN_NAME_FIELD",
526
- // Populated at bootstrap from OIDC_DISCOVERY_URL — checked here as a runtime safety net
533
+ // Populated at bootstrap from OIDC_ISSUER — checked here as a runtime safety net
527
534
  "OIDC_TOKEN_ENDPOINT",
528
535
  "OIDC_USERINFO_ENDPOINT",
529
536
  "OIDC_AUTHORIZATION_ENDPOINT"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-oidc",
3
- "version": "1.9.3",
3
+ "version": "1.9.4",
4
4
  "description": "A Strapi plugin that provides OpenID Connect (OIDC) authentication functionality for the Strapi Admin Panel.",
5
5
  "strapi": {
6
6
  "displayName": "OIDC Plugin",