strapi-plugin-oidc 1.8.4 → 1.8.5

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.
@@ -1,4 +1,4 @@
1
- import { randomUUID, randomBytes, createHash } from "node:crypto";
1
+ import { randomBytes, randomUUID, createHash } from "node:crypto";
2
2
  import pkceChallenge from "pkce-challenge";
3
3
  import { jwtVerify, errors, createRemoteJWKSet } from "jose";
4
4
  import { Readable } from "node:stream";
@@ -339,9 +339,149 @@ function clearAuthCookies(strapi2, ctx) {
339
339
  ctx.cookies.set(name, "", rootPathOptions);
340
340
  }
341
341
  }
342
- const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
343
- function isValidEmail(email) {
344
- return EMAIL_REGEX.test(email);
342
+ class OidcError extends Error {
343
+ kind;
344
+ cause;
345
+ constructor(kind, message, cause) {
346
+ super(message);
347
+ this.name = "OidcError";
348
+ this.kind = kind;
349
+ this.cause = cause;
350
+ }
351
+ }
352
+ const OIDC_ERROR_DISPATCH = {
353
+ nonce_mismatch: { action: "nonce_mismatch", code: errorCodes.NONCE_MISMATCH },
354
+ token_exchange_failed: {
355
+ action: "token_exchange_failed",
356
+ code: errorCodes.TOKEN_EXCHANGE_FAILED
357
+ },
358
+ id_token_parse_failed: {
359
+ action: "login_failure",
360
+ code: errorCodes.ID_TOKEN_PARSE_FAILED,
361
+ key: "id_token_parse_failed"
362
+ },
363
+ userinfo_fetch_failed: {
364
+ action: "login_failure",
365
+ code: errorCodes.USERINFO_FETCH_FAILED,
366
+ key: "userinfo_fetch_failed"
367
+ },
368
+ user_creation_failed: {
369
+ action: "login_failure",
370
+ code: errorCodes.USER_CREATION_FAILED,
371
+ key: "user_creation_failed"
372
+ },
373
+ whitelist_rejected: {
374
+ action: "whitelist_rejected",
375
+ code: errorCodes.WHITELIST_CHECK_FAILED,
376
+ key: "whitelist_rejected"
377
+ },
378
+ invalid_email: {
379
+ action: "login_failure",
380
+ code: errorCodes.TOKEN_EXCHANGE_FAILED,
381
+ key: "sign_in_unknown"
382
+ },
383
+ email_not_verified: {
384
+ action: "email_not_verified",
385
+ code: errorCodes.EMAIL_NOT_VERIFIED,
386
+ key: "email_not_verified"
387
+ },
388
+ id_token_invalid: {
389
+ action: "id_token_invalid",
390
+ code: errorCodes.ID_TOKEN_INVALID,
391
+ key: "id_token_invalid"
392
+ },
393
+ unknown: {
394
+ action: "login_failure",
395
+ code: errorCodes.TOKEN_EXCHANGE_FAILED,
396
+ key: "sign_in_unknown"
397
+ }
398
+ };
399
+ function toMessage(e) {
400
+ return e instanceof Error ? e.message : String(e);
401
+ }
402
+ const REQUIRED_CONFIG_KEYS = [
403
+ "OIDC_DISCOVERY_URL",
404
+ "OIDC_CLIENT_ID",
405
+ "OIDC_CLIENT_SECRET",
406
+ "OIDC_REDIRECT_URI",
407
+ "OIDC_SCOPE",
408
+ "OIDC_FAMILY_NAME_FIELD",
409
+ "OIDC_GIVEN_NAME_FIELD",
410
+ // Populated at bootstrap from OIDC_DISCOVERY_URL — checked here as a runtime safety net
411
+ "OIDC_TOKEN_ENDPOINT",
412
+ "OIDC_USERINFO_ENDPOINT",
413
+ "OIDC_AUTHORIZATION_ENDPOINT"
414
+ ];
415
+ const jwksCache = /* @__PURE__ */ new Map();
416
+ let jwksDisabledWarned = false;
417
+ function getJwks(uri) {
418
+ let jwks = jwksCache.get(uri);
419
+ if (!jwks) {
420
+ jwks = createRemoteJWKSet(new URL(uri));
421
+ jwksCache.set(uri, jwks);
422
+ }
423
+ return jwks;
424
+ }
425
+ async function verifyIdToken(idToken, config2) {
426
+ const jwksUri = config2.OIDC_JWKS_URI;
427
+ const issuer = config2.OIDC_ISSUER;
428
+ if (!jwksUri) {
429
+ if (!jwksDisabledWarned) {
430
+ jwksDisabledWarned = true;
431
+ strapi.log.warn(errorMessages.JWKS_URI_NOT_CONFIGURED);
432
+ }
433
+ return null;
434
+ }
435
+ try {
436
+ const jwks = getJwks(jwksUri);
437
+ const { payload } = await jwtVerify(idToken, jwks, {
438
+ issuer: issuer || void 0,
439
+ audience: config2.OIDC_CLIENT_ID
440
+ });
441
+ return payload;
442
+ } catch (e) {
443
+ if (e instanceof errors.JWTClaimValidationFailed || e instanceof errors.JWSSignatureVerificationFailed || e instanceof errors.JWTExpired || e instanceof errors.JWTInvalid || e instanceof errors.JWSInvalid) {
444
+ const msg = toMessage(e);
445
+ throw new OidcError("id_token_invalid", msg, e);
446
+ }
447
+ throw e;
448
+ }
449
+ }
450
+ function configValidation() {
451
+ const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
452
+ const missing = REQUIRED_CONFIG_KEYS.filter((key) => !config2[key]);
453
+ if (missing.length === 0) {
454
+ return config2;
455
+ }
456
+ throw new Error(errorMessages.MISSING_CONFIG(missing.join(", ")));
457
+ }
458
+ async function oidcSignIn(ctx) {
459
+ const { OIDC_CLIENT_ID, OIDC_REDIRECT_URI, OIDC_SCOPE, OIDC_AUTHORIZATION_ENDPOINT } = configValidation();
460
+ const { code_verifier: codeVerifier, code_challenge: codeChallenge } = await pkceChallenge();
461
+ const state = randomBytes(32).toString("base64url");
462
+ const nonce = randomBytes(32).toString("base64url");
463
+ const cookieOptions = {
464
+ httpOnly: true,
465
+ maxAge: 6e5,
466
+ secure: shouldMarkSecure(strapi, ctx),
467
+ sameSite: "lax"
468
+ };
469
+ ctx.cookies.set("oidc_code_verifier", codeVerifier, cookieOptions);
470
+ ctx.cookies.set("oidc_state", state, cookieOptions);
471
+ ctx.cookies.set("oidc_nonce", nonce, cookieOptions);
472
+ const params = new URLSearchParams({
473
+ response_type: "code",
474
+ client_id: OIDC_CLIENT_ID,
475
+ redirect_uri: OIDC_REDIRECT_URI,
476
+ scope: OIDC_SCOPE,
477
+ code_challenge: codeChallenge,
478
+ code_challenge_method: "S256",
479
+ state,
480
+ nonce
481
+ });
482
+ const authorizationUrl = `${OIDC_AUTHORIZATION_ENDPOINT}?${params.toString()}`;
483
+ ctx.set("Location", authorizationUrl);
484
+ return ctx.send({}, 302);
345
485
  }
346
486
  const en = {
347
487
  "global.plugins.strapi-plugin-oidc": "OIDC Plugin",
@@ -504,63 +644,6 @@ const authPageMessages = (locale) => ({
504
644
  errorTitle: t(locale, "auth.page.error.title", "Authentication Failed"),
505
645
  returnToLogin: t(locale, "auth.page.error.returnToLogin", "Return to Login")
506
646
  });
507
- class OidcError extends Error {
508
- kind;
509
- cause;
510
- constructor(kind, message, cause) {
511
- super(message);
512
- this.name = "OidcError";
513
- this.kind = kind;
514
- this.cause = cause;
515
- }
516
- }
517
- const OIDC_ERROR_DISPATCH = {
518
- nonce_mismatch: { action: "nonce_mismatch", code: errorCodes.NONCE_MISMATCH },
519
- token_exchange_failed: {
520
- action: "token_exchange_failed",
521
- code: errorCodes.TOKEN_EXCHANGE_FAILED
522
- },
523
- id_token_parse_failed: {
524
- action: "login_failure",
525
- code: errorCodes.ID_TOKEN_PARSE_FAILED,
526
- key: "id_token_parse_failed"
527
- },
528
- userinfo_fetch_failed: {
529
- action: "login_failure",
530
- code: errorCodes.USERINFO_FETCH_FAILED,
531
- key: "userinfo_fetch_failed"
532
- },
533
- user_creation_failed: {
534
- action: "login_failure",
535
- code: errorCodes.USER_CREATION_FAILED,
536
- key: "user_creation_failed"
537
- },
538
- whitelist_rejected: {
539
- action: "whitelist_rejected",
540
- code: errorCodes.WHITELIST_CHECK_FAILED,
541
- key: "whitelist_rejected"
542
- },
543
- invalid_email: {
544
- action: "login_failure",
545
- code: errorCodes.TOKEN_EXCHANGE_FAILED,
546
- key: "sign_in_unknown"
547
- },
548
- email_not_verified: {
549
- action: "email_not_verified",
550
- code: errorCodes.EMAIL_NOT_VERIFIED,
551
- key: "email_not_verified"
552
- },
553
- id_token_invalid: {
554
- action: "id_token_invalid",
555
- code: errorCodes.ID_TOKEN_INVALID,
556
- key: "id_token_invalid"
557
- },
558
- unknown: {
559
- action: "login_failure",
560
- code: errorCodes.TOKEN_EXCHANGE_FAILED,
561
- key: "sign_in_unknown"
562
- }
563
- };
564
647
  const TRUSTED_IP_HEADERS = /* @__PURE__ */ new Set([
565
648
  "cf-connecting-ip",
566
649
  "true-client-ip",
@@ -591,128 +674,9 @@ function getClientIp(ctx) {
591
674
  }
592
675
  return ctx.ip;
593
676
  }
594
- function toMessage(e) {
595
- return e instanceof Error ? e.message : String(e);
596
- }
597
- const REQUIRED_CONFIG_KEYS = [
598
- "OIDC_DISCOVERY_URL",
599
- "OIDC_CLIENT_ID",
600
- "OIDC_CLIENT_SECRET",
601
- "OIDC_REDIRECT_URI",
602
- "OIDC_SCOPE",
603
- "OIDC_FAMILY_NAME_FIELD",
604
- "OIDC_GIVEN_NAME_FIELD",
605
- // Populated at bootstrap from OIDC_DISCOVERY_URL — checked here as a runtime safety net
606
- "OIDC_TOKEN_ENDPOINT",
607
- "OIDC_USERINFO_ENDPOINT",
608
- "OIDC_AUTHORIZATION_ENDPOINT"
609
- ];
610
- const LOGOUT_USERINFO_TIMEOUT_MS = 1500;
611
- const jwksCache = /* @__PURE__ */ new Map();
612
- let jwksDisabledWarned = false;
613
- function getJwks(uri) {
614
- let jwks = jwksCache.get(uri);
615
- if (!jwks) {
616
- jwks = createRemoteJWKSet(new URL(uri));
617
- jwksCache.set(uri, jwks);
618
- }
619
- return jwks;
620
- }
621
- async function verifyIdToken(idToken, config2) {
622
- const jwksUri = config2.OIDC_JWKS_URI;
623
- const issuer = config2.OIDC_ISSUER;
624
- if (!jwksUri) {
625
- if (!jwksDisabledWarned) {
626
- jwksDisabledWarned = true;
627
- strapi.log.warn(errorMessages.JWKS_URI_NOT_CONFIGURED);
628
- }
629
- return null;
630
- }
631
- try {
632
- const jwks = getJwks(jwksUri);
633
- const { payload } = await jwtVerify(idToken, jwks, {
634
- issuer: issuer || void 0,
635
- audience: config2.OIDC_CLIENT_ID
636
- });
637
- return payload;
638
- } catch (e) {
639
- if (e instanceof errors.JWTClaimValidationFailed || e instanceof errors.JWSSignatureVerificationFailed || e instanceof errors.JWTExpired || e instanceof errors.JWTInvalid || e instanceof errors.JWSInvalid) {
640
- const msg = toMessage(e);
641
- throw new OidcError("id_token_invalid", msg, e);
642
- }
643
- throw e;
644
- }
645
- }
646
- function configValidation() {
647
- const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
648
- const missing = REQUIRED_CONFIG_KEYS.filter((key) => !config2[key]);
649
- if (missing.length === 0) {
650
- return config2;
651
- }
652
- throw new Error(errorMessages.MISSING_CONFIG(missing.join(", ")));
653
- }
654
- async function oidcSignIn(ctx) {
655
- const { OIDC_CLIENT_ID, OIDC_REDIRECT_URI, OIDC_SCOPE, OIDC_AUTHORIZATION_ENDPOINT } = configValidation();
656
- const { code_verifier: codeVerifier, code_challenge: codeChallenge } = await pkceChallenge();
657
- const state = randomBytes(32).toString("base64url");
658
- const nonce = randomBytes(32).toString("base64url");
659
- const cookieOptions = {
660
- httpOnly: true,
661
- maxAge: 6e5,
662
- secure: shouldMarkSecure(strapi, ctx),
663
- sameSite: "lax"
664
- };
665
- ctx.cookies.set("oidc_code_verifier", codeVerifier, cookieOptions);
666
- ctx.cookies.set("oidc_state", state, cookieOptions);
667
- ctx.cookies.set("oidc_nonce", nonce, cookieOptions);
668
- const params = new URLSearchParams({
669
- response_type: "code",
670
- client_id: OIDC_CLIENT_ID,
671
- redirect_uri: OIDC_REDIRECT_URI,
672
- scope: OIDC_SCOPE,
673
- code_challenge: codeChallenge,
674
- code_challenge_method: "S256",
675
- state,
676
- nonce
677
- });
678
- const authorizationUrl = `${OIDC_AUTHORIZATION_ENDPOINT}?${params.toString()}`;
679
- ctx.set("Location", authorizationUrl);
680
- return ctx.send({}, 302);
681
- }
682
- async function exchangeTokenAndFetchUserInfo(config2, params, expectedNonce) {
683
- const response = await fetch(config2.OIDC_TOKEN_ENDPOINT, {
684
- method: "POST",
685
- body: params,
686
- headers: {
687
- "Content-Type": "application/x-www-form-urlencoded"
688
- }
689
- });
690
- if (!response.ok) {
691
- throw new OidcError("token_exchange_failed", errorMessages.TOKEN_EXCHANGE_FAILED);
692
- }
693
- const tokenData = await response.json();
694
- if (tokenData.id_token) {
695
- const verifiedPayload = await verifyIdToken(tokenData.id_token, config2);
696
- try {
697
- const idTokenPayload = verifiedPayload ?? JSON.parse(
698
- Buffer.from(tokenData.id_token.split(".")[1], "base64url").toString("utf8")
699
- );
700
- if (idTokenPayload.nonce !== expectedNonce) {
701
- throw new OidcError("nonce_mismatch", errorMessages.NONCE_MISMATCH);
702
- }
703
- } catch (e) {
704
- if (e instanceof OidcError) throw e;
705
- throw new OidcError("id_token_parse_failed", errorMessages.ID_TOKEN_PARSE_FAILED, e);
706
- }
707
- }
708
- const userResponse = await fetch(config2.OIDC_USERINFO_ENDPOINT, {
709
- headers: { Authorization: `Bearer ${tokenData.access_token}` }
710
- });
711
- if (!userResponse.ok) {
712
- throw new OidcError("userinfo_fetch_failed", errorMessages.USERINFO_FETCH_FAILED);
713
- }
714
- const userInfo = await userResponse.json();
715
- return { userInfo, accessToken: tokenData.access_token };
677
+ const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
678
+ function isValidEmail(email) {
679
+ return EMAIL_REGEX.test(email);
716
680
  }
717
681
  function collectGroupMapRoleNames(userInfo, config2) {
718
682
  const rawGroups = userInfo[config2.OIDC_GROUP_FIELD];
@@ -892,6 +856,61 @@ function classifyOidcError(e, userInfo) {
892
856
  params
893
857
  };
894
858
  }
859
+ async function handleCallbackError(e, userInfo, auditLog2, oauthService2, ctx) {
860
+ const errorInfo = classifyOidcError(e, userInfo);
861
+ const message = toMessage(e);
862
+ await auditLog2.log({
863
+ action: errorInfo.action,
864
+ email: userInfo?.email,
865
+ ip: getClientIp(ctx),
866
+ detailsKey: errorInfo.action,
867
+ detailsParams: errorInfo.action === "login_failure" ? { message } : void 0
868
+ });
869
+ strapi.log.error({
870
+ code: errorInfo.code,
871
+ phase: "oidc_callback",
872
+ message: e instanceof Error ? e.message : "Unknown sign-in error",
873
+ detail: errorInfo.key ? getErrorDetail(errorInfo.key, errorInfo.params) : void 0,
874
+ email: userInfo?.email
875
+ });
876
+ const locale = negotiateLocale(ctx.request.headers["accept-language"]);
877
+ ctx.send(oauthService2.renderSignUpError(userFacingMessages(locale).signInError, locale));
878
+ }
879
+ async function exchangeTokenAndFetchUserInfo(config2, params, expectedNonce) {
880
+ const response = await fetch(config2.OIDC_TOKEN_ENDPOINT, {
881
+ method: "POST",
882
+ body: params,
883
+ headers: {
884
+ "Content-Type": "application/x-www-form-urlencoded"
885
+ }
886
+ });
887
+ if (!response.ok) {
888
+ throw new OidcError("token_exchange_failed", errorMessages.TOKEN_EXCHANGE_FAILED);
889
+ }
890
+ const tokenData = await response.json();
891
+ if (tokenData.id_token) {
892
+ const verifiedPayload = await verifyIdToken(tokenData.id_token, config2);
893
+ try {
894
+ const idTokenPayload = verifiedPayload ?? JSON.parse(
895
+ Buffer.from(tokenData.id_token.split(".")[1], "base64url").toString("utf8")
896
+ );
897
+ if (idTokenPayload.nonce !== expectedNonce) {
898
+ throw new OidcError("nonce_mismatch", errorMessages.NONCE_MISMATCH);
899
+ }
900
+ } catch (e) {
901
+ if (e instanceof OidcError) throw e;
902
+ throw new OidcError("id_token_parse_failed", errorMessages.ID_TOKEN_PARSE_FAILED, e);
903
+ }
904
+ }
905
+ const userResponse = await fetch(config2.OIDC_USERINFO_ENDPOINT, {
906
+ headers: { Authorization: `Bearer ${tokenData.access_token}` }
907
+ });
908
+ if (!userResponse.ok) {
909
+ throw new OidcError("userinfo_fetch_failed", errorMessages.USERINFO_FETCH_FAILED);
910
+ }
911
+ const userInfo = await userResponse.json();
912
+ return { userInfo, accessToken: tokenData.access_token };
913
+ }
895
914
  function readAndClearPkceCookies(ctx) {
896
915
  const oidcState = ctx.cookies.get("oidc_state");
897
916
  const codeVerifier = ctx.cookies.get("oidc_code_verifier");
@@ -925,26 +944,6 @@ async function logSuccessfulAuth(auditLog2, ctx, user, userCreated, rolesUpdated
925
944
  }
926
945
  await Promise.all(entries);
927
946
  }
928
- async function handleCallbackError(e, userInfo, auditLog2, oauthService2, ctx) {
929
- const errorInfo = classifyOidcError(e, userInfo);
930
- const message = toMessage(e);
931
- await auditLog2.log({
932
- action: errorInfo.action,
933
- email: userInfo?.email,
934
- ip: getClientIp(ctx),
935
- detailsKey: errorInfo.action,
936
- detailsParams: errorInfo.action === "login_failure" ? { message } : void 0
937
- });
938
- strapi.log.error({
939
- code: errorInfo.code,
940
- phase: "oidc_callback",
941
- message: e instanceof Error ? e.message : "Unknown sign-in error",
942
- detail: errorInfo.key ? getErrorDetail(errorInfo.key, errorInfo.params) : void 0,
943
- email: userInfo?.email
944
- });
945
- const locale = negotiateLocale(ctx.request.headers["accept-language"]);
946
- ctx.send(oauthService2.renderSignUpError(userFacingMessages(locale).signInError, locale));
947
- }
948
947
  async function oidcSignInCallback(ctx) {
949
948
  const config2 = configValidation();
950
949
  const oauthService2 = getOauthService();
@@ -1012,6 +1011,7 @@ async function oidcSignInCallback(ctx) {
1012
1011
  await handleCallbackError(e, userInfo, auditLog2, oauthService2, ctx);
1013
1012
  }
1014
1013
  }
1014
+ const LOGOUT_USERINFO_TIMEOUT_MS = 1500;
1015
1015
  async function isProviderSessionExpired(userinfoEndpoint, accessToken) {
1016
1016
  try {
1017
1017
  const response = await fetch(userinfoEndpoint, {
@@ -2055,6 +2055,7 @@ function translateDetails(key, params) {
2055
2055
  if (!translation) return null;
2056
2056
  return interpolate(translation, params);
2057
2057
  }
2058
+ const DAY_MS = 864e5;
2058
2059
  const STRING_OP_MAP = {
2059
2060
  $eq: (v) => v,
2060
2061
  $contains: (v) => ({ $containsi: v }),
@@ -2067,9 +2068,11 @@ const DATE_OP_MAP = {
2067
2068
  $lt: (v) => ({ $lt: v }),
2068
2069
  $lte: (v) => ({ $lte: v }),
2069
2070
  $between: (v) => ({ $between: v })
2070
- // $in is handled separately: each ISO day-start is expanded to a [day, day+1) range.
2071
2071
  };
2072
- const DAY_MS = 864e5;
2072
+ const ACTION_OP_MAP = {
2073
+ $eq: (v) => v,
2074
+ $in: (v) => ({ $in: v })
2075
+ };
2073
2076
  function nextDayIso(iso) {
2074
2077
  return new Date(new Date(iso).getTime() + DAY_MS).toISOString();
2075
2078
  }
@@ -2077,10 +2080,6 @@ function expandCreatedAtInToDayRanges(days) {
2077
2080
  const ranges = days.map((d) => ({ createdAt: { $gte: d, $lt: nextDayIso(d) } }));
2078
2081
  return ranges.length === 1 ? ranges[0] : { $or: ranges };
2079
2082
  }
2080
- const ACTION_OP_MAP = {
2081
- $eq: (v) => v,
2082
- $in: (v) => ({ $in: v })
2083
- };
2084
2083
  function mapFieldFilter(conditions, field, filter, opMap) {
2085
2084
  for (const [op, value] of Object.entries(filter)) {
2086
2085
  const transform = opMap[op];
@@ -2089,20 +2088,26 @@ function mapFieldFilter(conditions, field, filter, opMap) {
2089
2088
  if (result !== void 0) conditions.push({ [field]: result });
2090
2089
  }
2091
2090
  }
2091
+ function buildDateConditions(conditions, createdAt) {
2092
+ if (!createdAt) return;
2093
+ const { $in: inDays, ...rest } = createdAt;
2094
+ if (Array.isArray(inDays) && inDays.length > 0) {
2095
+ conditions.push(expandCreatedAtInToDayRanges(inDays));
2096
+ }
2097
+ for (const [op, value] of Object.entries(rest)) {
2098
+ const transform = DATE_OP_MAP[op];
2099
+ if (transform) {
2100
+ const result = transform(value);
2101
+ if (result !== void 0) conditions.push({ createdAt: result });
2102
+ }
2103
+ }
2104
+ }
2092
2105
  function buildWhereClause(filters) {
2093
2106
  const conditions = [];
2094
2107
  if (filters.action) mapFieldFilter(conditions, "action", filters.action, ACTION_OP_MAP);
2095
2108
  if (filters.email) mapFieldFilter(conditions, "email", filters.email, STRING_OP_MAP);
2096
2109
  if (filters.ip) mapFieldFilter(conditions, "ip", filters.ip, STRING_OP_MAP);
2097
- if (filters.createdAt) {
2098
- const { $in: inDays, ...rest } = filters.createdAt;
2099
- if (Array.isArray(inDays) && inDays.length > 0) {
2100
- conditions.push(expandCreatedAtInToDayRanges(inDays));
2101
- }
2102
- if (Object.keys(rest).length > 0) {
2103
- mapFieldFilter(conditions, "createdAt", rest, DATE_OP_MAP);
2104
- }
2105
- }
2110
+ if (filters.createdAt) buildDateConditions(conditions, filters.createdAt);
2106
2111
  if (conditions.length === 0) return {};
2107
2112
  if (conditions.length === 1) return conditions[0];
2108
2113
  return { $and: conditions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-oidc",
3
- "version": "1.8.4",
3
+ "version": "1.8.5",
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",