strapi-plugin-oidc 1.8.0 → 1.8.2

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.
@@ -2,10 +2,10 @@ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { useBlocker, Routes, Route } from "react-router-dom";
3
3
  import { useNotification, useFetchClient, Page, Layouts } from "@strapi/strapi/admin";
4
4
  import { useState, useRef, useId, useEffect, useCallback, useReducer, useMemo, memo } from "react";
5
- import { Typography, Flex, Box, MultiSelect, MultiSelectOption, Button, Dialog, Table, Pagination, PreviousLink, NextLink, PageLink, Field, Divider, Thead, Tr, Th, Tbody, Td, IconButton, Tooltip, Alert } from "@strapi/design-system";
5
+ import { Typography, Flex, Box, MultiSelect, MultiSelectOption, Button, Dialog, Table, Pagination, PreviousLink, NextLink, PageLink, Field, Divider, Thead, Tr, Th, Tbody, Td, IconButton, Loader, Tooltip, Alert } from "@strapi/design-system";
6
6
  import { Cross, WarningCircle, Plus, Download, Upload, Trash, Calendar, Mail, Information } from "@strapi/icons";
7
7
  import { useIntl } from "react-intl";
8
- import { g as getTrad } from "./index-B-K4X_N9.mjs";
8
+ import { g as getTrad } from "./index-Bb9-aYb4.mjs";
9
9
  import styled from "styled-components";
10
10
  import { Filter, ClipboardList, Server } from "lucide-react";
11
11
  function Role({ oidcRoles, roles, onChangeRole }) {
@@ -1014,7 +1014,7 @@ function Whitelist({
1014
1014
  /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("whitelist.table.created")) }),
1015
1015
  /* @__PURE__ */ jsx(Th, { style: { paddingRight: 0 }, children: " " })
1016
1016
  ] }) }),
1017
- /* @__PURE__ */ jsx(Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 4, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage(getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index) => /* @__PURE__ */ jsxs(Tr, { children: [
1017
+ /* @__PURE__ */ jsx(Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 4, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "80px" }, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage(getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index) => /* @__PURE__ */ jsxs(Tr, { children: [
1018
1018
  /* @__PURE__ */ jsx(Td, { children: index + 1 + (page - 1) * PAGE_SIZE$1 }),
1019
1019
  /* @__PURE__ */ jsx(Td, { children: user.email }),
1020
1020
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(LocalizedDate, { date: user.createdAt, options: { second: "2-digit" } }) }),
@@ -3618,6 +3618,7 @@ const AUDIT_ACTIONS = [
3618
3618
  "user_created"
3619
3619
  ];
3620
3620
  const PAGE_SIZE = 10;
3621
+ const MIN_SPINNER_MS = 400;
3621
3622
  const DETAILS_TEXT_STYLE = {
3622
3623
  display: "block",
3623
3624
  overflow: "hidden",
@@ -3667,28 +3668,35 @@ function AuditLog({ title } = {}) {
3667
3668
  pageCount: 1
3668
3669
  });
3669
3670
  const [page, setPage] = useState(1);
3670
- const [loading, setLoading] = useState(false);
3671
+ const [loading, setLoading] = useState(true);
3671
3672
  const [filters, setFilters] = useState({});
3673
+ const fetchGenRef = useRef(0);
3672
3674
  const debouncedFilters = useDebounced(filters);
3673
3675
  const fetchLogs = useCallback(
3674
3676
  async (p, f) => {
3677
+ const gen = ++fetchGenRef.current;
3675
3678
  setLoading(true);
3679
+ const startTime = Date.now();
3680
+ let newRecords = [];
3681
+ let newPagination = { page: p, pageSize: PAGE_SIZE, total: 0, pageCount: 1 };
3676
3682
  try {
3677
- const queryString = buildQueryString({
3678
- filters: f,
3679
- page: p,
3680
- pageSize: PAGE_SIZE
3681
- });
3683
+ const queryString = buildQueryString({ filters: f, page: p, pageSize: PAGE_SIZE });
3682
3684
  const response = await get2(`/strapi-plugin-oidc/audit-logs?${queryString}`);
3683
- setRecords(response.data.results ?? []);
3684
- setPagination(
3685
- response.data.pagination ?? { page: p, pageSize: PAGE_SIZE, total: 0, pageCount: 1 }
3686
- );
3685
+ newRecords = response.data.results ?? [];
3686
+ newPagination = response.data.pagination ?? {
3687
+ page: p,
3688
+ pageSize: PAGE_SIZE,
3689
+ total: 0,
3690
+ pageCount: 1
3691
+ };
3687
3692
  } catch {
3688
- setRecords([]);
3689
- } finally {
3690
- setLoading(false);
3691
3693
  }
3694
+ const remaining = MIN_SPINNER_MS - (Date.now() - startTime);
3695
+ if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
3696
+ if (gen !== fetchGenRef.current) return;
3697
+ setRecords(newRecords);
3698
+ setPagination(newPagination);
3699
+ setLoading(false);
3692
3700
  },
3693
3701
  [get2]
3694
3702
  );
@@ -3865,37 +3873,54 @@ function AuditLog({ title } = {}) {
3865
3873
  ]
3866
3874
  }
3867
3875
  ),
3868
- /* @__PURE__ */ jsxs(CustomTable, { colCount: 5, rowCount: records.length, children: [
3869
- /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
3870
- /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.timestamp")) }),
3871
- /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.action")) }),
3872
- /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.email")) }),
3873
- /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.ip")) }),
3874
- /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.details")) })
3875
- ] }) }),
3876
- /* @__PURE__ */ jsxs(Tbody, { children: [
3877
- loading && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 5, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage(getTrad("auditlog.loading")) }) }) }) }),
3878
- !loading && records.length === 0 && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 5, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: hasActiveFilters ? formatMessage(getTrad("auditlog.filters.empty")) : formatMessage(getTrad("auditlog.table.empty")) }) }) }) }),
3879
- !loading && records.map((record) => /* @__PURE__ */ jsxs(Tr, { children: [
3880
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: /* @__PURE__ */ jsx(LocalizedDate, { date: record.createdAt, options: { second: "2-digit" } }) }) }),
3881
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
3882
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.action }),
3883
- /* @__PURE__ */ jsx(Tooltip, { label: formatMessage(getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsx(
3884
- Information,
3885
- {
3886
- "aria-hidden": true,
3887
- style: { cursor: "help" },
3888
- width: "1.4rem",
3889
- height: "1.4rem",
3890
- fill: "primary600"
3891
- }
3892
- ) })
3893
- ] }) }),
3894
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.email ?? "—" }) }),
3895
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.ip ?? "—" }) }),
3896
- /* @__PURE__ */ jsx(Td, { style: { maxWidth: "200px" }, children: record.details ? /* @__PURE__ */ jsx(Tooltip, { label: record.details, side: "top", children: /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: DETAILS_TEXT_STYLE, children: record.details }) }) : /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", children: "—" }) })
3897
- ] }, record.id))
3898
- ] })
3876
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: "100%" }, children: [
3877
+ /* @__PURE__ */ jsxs(CustomTable, { colCount: 5, rowCount: records.length, children: [
3878
+ /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
3879
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.timestamp")) }),
3880
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.action")) }),
3881
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.email")) }),
3882
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.ip")) }),
3883
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("auditlog.table.details")) })
3884
+ ] }) }),
3885
+ /* @__PURE__ */ jsxs(Tbody, { children: [
3886
+ records.length === 0 && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 5, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "80px" }, children: loading ? /* @__PURE__ */ jsx(Loader, { small: true }) : /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: hasActiveFilters ? formatMessage(getTrad("auditlog.filters.empty")) : formatMessage(getTrad("auditlog.table.empty")) }) }) }) }),
3887
+ records.map((record) => /* @__PURE__ */ jsxs(
3888
+ Tr,
3889
+ {
3890
+ style: { opacity: loading ? 0.4 : 1, transition: "opacity 0.15s" },
3891
+ children: [
3892
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: /* @__PURE__ */ jsx(LocalizedDate, { date: record.createdAt, options: { second: "2-digit" } }) }) }),
3893
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
3894
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.action }),
3895
+ /* @__PURE__ */ jsx(Tooltip, { label: formatMessage(getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsx(
3896
+ Information,
3897
+ {
3898
+ "aria-hidden": true,
3899
+ style: { cursor: "help" },
3900
+ width: "1.4rem",
3901
+ height: "1.4rem",
3902
+ fill: "primary600"
3903
+ }
3904
+ ) })
3905
+ ] }) }),
3906
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.email ?? "—" }) }),
3907
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.ip ?? "—" }) }),
3908
+ /* @__PURE__ */ jsx(Td, { style: { maxWidth: "200px" }, children: record.details ? /* @__PURE__ */ jsx(Tooltip, { label: record.details, side: "top", children: /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: DETAILS_TEXT_STYLE, children: record.details }) }) : /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", children: "—" }) })
3909
+ ]
3910
+ },
3911
+ record.id
3912
+ ))
3913
+ ] })
3914
+ ] }),
3915
+ loading && records.length > 0 && /* @__PURE__ */ jsx(
3916
+ Flex,
3917
+ {
3918
+ justifyContent: "center",
3919
+ alignItems: "center",
3920
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
3921
+ children: /* @__PURE__ */ jsx(Loader, { small: true })
3922
+ }
3923
+ )
3899
3924
  ] }),
3900
3925
  /* @__PURE__ */ jsx(
3901
3926
  TablePagination,
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
- const react = require("react");
2
+ const React = require("react");
3
+ const client = require("react-dom/client");
4
+ const jsxRuntime = require("react/jsx-runtime");
5
+ const designSystem = require("@strapi/design-system");
6
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
7
+ const React__default = /* @__PURE__ */ _interopDefault(React);
3
8
  const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
4
9
  const v = glob[path];
5
10
  if (v) {
@@ -24,15 +29,51 @@ const pluginPkg = {
24
29
  };
25
30
  const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, "");
26
31
  function Initializer({ setPlugin }) {
27
- const ref = react.useRef();
32
+ const ref = React.useRef();
28
33
  ref.current = setPlugin;
29
- react.useEffect(() => {
34
+ React.useEffect(() => {
30
35
  if (ref.current) {
31
36
  ref.current(pluginId);
32
37
  }
33
38
  }, []);
34
39
  return null;
35
40
  }
41
+ const LOGOUT_EVENT = "strapi-oidc:logout";
42
+ function Overlay({ bg }) {
43
+ const [active, setActive] = React.useState(false);
44
+ React.useEffect(() => {
45
+ const handler = () => setActive(true);
46
+ window.addEventListener(LOGOUT_EVENT, handler);
47
+ return () => window.removeEventListener(LOGOUT_EVENT, handler);
48
+ }, []);
49
+ if (!active) return null;
50
+ return /* @__PURE__ */ jsxRuntime.jsx(
51
+ "div",
52
+ {
53
+ style: {
54
+ position: "fixed",
55
+ inset: 0,
56
+ zIndex: 1e4,
57
+ display: "flex",
58
+ alignItems: "center",
59
+ justifyContent: "center",
60
+ background: bg,
61
+ backdropFilter: "blur(2px)"
62
+ },
63
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, {})
64
+ }
65
+ );
66
+ }
67
+ function resolveTheme() {
68
+ const stored = window.localStorage.getItem("STRAPI_THEME") ?? "system";
69
+ const isDark = stored === "dark" || stored === "system" && (window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false);
70
+ return isDark ? designSystem.darkTheme : designSystem.lightTheme;
71
+ }
72
+ function LogoutOverlay() {
73
+ const theme = resolveTheme();
74
+ const bg = theme === designSystem.darkTheme ? "rgba(24, 24, 38, 0.85)" : "rgba(255, 255, 255, 0.85)";
75
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.DesignSystemProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(Overlay, { bg }) });
76
+ }
36
77
  const en = {
37
78
  "global.plugins.strapi-plugin-oidc": "OIDC Plugin",
38
79
  "page.title": "Configure OIDC default role(s) and access controls.",
@@ -95,7 +136,6 @@ const en = {
95
136
  "auditlog.table.ip": "IP",
96
137
  "auditlog.table.details": "Details",
97
138
  "auditlog.table.empty": "No audit log entries",
98
- "auditlog.loading": "Loading…",
99
139
  "auditlog.clear": "Clear Logs",
100
140
  "auditlog.clear.title": "Clear All Logs",
101
141
  "auditlog.clear.description": "This will permanently delete all {count, plural, one {# audit log entry} other {# audit log entries}}. This action cannot be undone.",
@@ -168,7 +208,7 @@ const index = {
168
208
  defaultMessage: "Configuration"
169
209
  },
170
210
  Component: async () => {
171
- return await Promise.resolve().then(() => require("./index-CgG_mHzZ.js"));
211
+ return await Promise.resolve().then(() => require("./index-Bmg4eTYb.js"));
172
212
  },
173
213
  permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
174
214
  }
@@ -180,6 +220,9 @@ const index = {
180
220
  });
181
221
  },
182
222
  bootstrap() {
223
+ const overlayContainer = document.createElement("div");
224
+ document.body.appendChild(overlayContainer);
225
+ client.createRoot(overlayContainer).render(React__default.default.createElement(LogoutOverlay));
183
226
  const defaultButtonText = t("login.sso");
184
227
  const isAuthRoute = (path) => /\/auth\/(login|register|forgot-password|reset-password)/.test(path);
185
228
  let ssoButtonInjected = false;
@@ -239,6 +282,7 @@ const index = {
239
282
  if (!isAuthRoute(window.location.pathname)) return;
240
283
  injectSSOButton(buttonText);
241
284
  if (enforced) removeEnforcedElements();
285
+ if (ssoButtonInjected && !enforced) loginObserver?.disconnect();
242
286
  };
243
287
  tick();
244
288
  loginObserver = new MutationObserver(tick);
@@ -259,27 +303,27 @@ const index = {
259
303
  }
260
304
  };
261
305
  applySettings();
306
+ if (window.__strapiOidcFetchPatched) return;
307
+ window.__strapiOidcFetchPatched = true;
262
308
  const originalFetch = window.fetch;
263
309
  window.fetch = async (...args) => {
264
310
  const url = typeof args[0] === "string" ? args[0] : args[0].url;
265
311
  const isLogout = url?.endsWith("/admin/logout") && args[1]?.method?.toUpperCase() === "POST";
266
- const response = await originalFetch(...args);
267
- if (isLogout && response.ok) {
312
+ if (isLogout) {
313
+ window.dispatchEvent(new CustomEvent(LOGOUT_EVENT));
268
314
  window.localStorage.removeItem("jwtToken");
269
315
  window.localStorage.removeItem("isLoggedIn");
270
316
  window.sessionStorage.removeItem("jwtToken");
271
317
  window.sessionStorage.removeItem("isLoggedIn");
272
318
  document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
273
319
  document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
274
- const form = document.createElement("form");
275
- form.method = "POST";
276
- form.action = "/strapi-plugin-oidc/logout";
277
- document.body.appendChild(form);
278
- form.submit();
320
+ originalFetch(...args).catch(() => {
321
+ });
322
+ window.location.href = "/strapi-plugin-oidc/logout";
279
323
  return new Promise(() => {
280
324
  });
281
325
  }
282
- return response;
326
+ return originalFetch(...args);
283
327
  };
284
328
  },
285
329
  async registerTrads({ locales }) {
@@ -1,4 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const index = require("./index-BSgVStns.js");
3
+ const index = require("./index-Dk6TYtio.js");
4
+ require("react");
5
+ require("react-dom/client");
4
6
  exports.default = index.index;
@@ -1,4 +1,6 @@
1
- import { i } from "./index-B-K4X_N9.mjs";
1
+ import { i } from "./index-Bb9-aYb4.mjs";
2
+ import "react";
3
+ import "react-dom/client";
2
4
  export {
3
5
  i as default
4
6
  };