strapi-plugin-oidc 1.7.6 → 1.8.1
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 +77 -47
- package/dist/admin/{index-DRJ6Ty2J.mjs → index-Bb9-aYb4.mjs} +54 -6
- package/dist/admin/{index-D2rlNx1-.js → index-Bmg4eTYb.js} +115 -88
- package/dist/admin/{index-pieFAsgM.mjs → index-BqWd-Iiq.mjs} +74 -47
- package/dist/admin/{index-CrnGXADu.js → index-Dk6TYtio.js} +58 -8
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.mjs +3 -1
- package/dist/server/index.js +266 -92
- package/dist/server/index.mjs +266 -92
- package/package.json +2 -1
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const reactRouterDom = require("react-router-dom");
|
|
5
5
|
const admin = require("@strapi/strapi/admin");
|
|
6
|
-
const
|
|
6
|
+
const React = require("react");
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const reactIntl = require("react-intl");
|
|
10
|
-
const index = require("./index-
|
|
10
|
+
const index = require("./index-Dk6TYtio.js");
|
|
11
11
|
const styled = require("styled-components");
|
|
12
12
|
const lucideReact = require("lucide-react");
|
|
13
13
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
@@ -125,8 +125,8 @@ function TagChip({ label, onRemove }) {
|
|
|
125
125
|
] });
|
|
126
126
|
}
|
|
127
127
|
function useTagState({ value, onChange }) {
|
|
128
|
-
const [inputValue, setInputValue] =
|
|
129
|
-
const inputRef =
|
|
128
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
129
|
+
const inputRef = React.useRef(null);
|
|
130
130
|
const addTag = (tag, predicate) => {
|
|
131
131
|
const trimmed = tag.trim();
|
|
132
132
|
if (trimmed && !value.includes(trimmed) && (!predicate || predicate(trimmed))) {
|
|
@@ -261,11 +261,11 @@ function ComboboxTagInput({ value, onChange, placeholder, startIcon, options })
|
|
|
261
261
|
value,
|
|
262
262
|
onChange
|
|
263
263
|
});
|
|
264
|
-
const [showDropdown, setShowDropdown] =
|
|
265
|
-
const [activeIndex, setActiveIndex] =
|
|
266
|
-
const wrapperRef =
|
|
267
|
-
const listboxId =
|
|
268
|
-
const optionIdPrefix =
|
|
264
|
+
const [showDropdown, setShowDropdown] = React.useState(false);
|
|
265
|
+
const [activeIndex, setActiveIndex] = React.useState(-1);
|
|
266
|
+
const wrapperRef = React.useRef(null);
|
|
267
|
+
const listboxId = React.useId();
|
|
268
|
+
const optionIdPrefix = React.useId();
|
|
269
269
|
const filteredOptions = options.filter(
|
|
270
270
|
(opt) => !value.includes(opt) && opt.toLowerCase().includes(inputValue.toLowerCase())
|
|
271
271
|
);
|
|
@@ -333,7 +333,7 @@ function ComboboxTagInput({ value, onChange, placeholder, startIcon, options })
|
|
|
333
333
|
setShowDropdown(true);
|
|
334
334
|
setActiveIndex(-1);
|
|
335
335
|
};
|
|
336
|
-
|
|
336
|
+
React.useEffect(() => {
|
|
337
337
|
const handleClickOutside = (e) => {
|
|
338
338
|
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
|
|
339
339
|
setShowDropdown(false);
|
|
@@ -546,13 +546,13 @@ const DAY_NAMES = Array.from(
|
|
|
546
546
|
);
|
|
547
547
|
function TagDateInput({ value = [], onChange, placeholder, startIcon }) {
|
|
548
548
|
const { formatMessage } = reactIntl.useIntl();
|
|
549
|
-
const [isOpen, setIsOpen] =
|
|
550
|
-
const [viewDate, setViewDate] =
|
|
551
|
-
const [pendingDates, setPendingDates] =
|
|
549
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
550
|
+
const [viewDate, setViewDate] = React.useState(() => /* @__PURE__ */ new Date());
|
|
551
|
+
const [pendingDates, setPendingDates] = React.useState([]);
|
|
552
552
|
const today = /* @__PURE__ */ new Date();
|
|
553
|
-
const wrapperRef =
|
|
554
|
-
const dialogId =
|
|
555
|
-
const dialogLabelId =
|
|
553
|
+
const wrapperRef = React.useRef(null);
|
|
554
|
+
const dialogId = React.useId();
|
|
555
|
+
const dialogLabelId = React.useId();
|
|
556
556
|
const year = viewDate.getFullYear();
|
|
557
557
|
const month = viewDate.getMonth();
|
|
558
558
|
const daysInMonth = getDaysInMonth(year, month);
|
|
@@ -594,7 +594,7 @@ function TagDateInput({ value = [], onChange, placeholder, startIcon }) {
|
|
|
594
594
|
const removeTag = (indexToRemove) => {
|
|
595
595
|
onChange(value.filter((_, i) => i !== indexToRemove));
|
|
596
596
|
};
|
|
597
|
-
|
|
597
|
+
React.useEffect(() => {
|
|
598
598
|
const handleClickOutside = (e) => {
|
|
599
599
|
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
|
|
600
600
|
setIsOpen(false);
|
|
@@ -863,14 +863,14 @@ function Whitelist({
|
|
|
863
863
|
onImport,
|
|
864
864
|
onExport
|
|
865
865
|
}) {
|
|
866
|
-
const [email, setEmail] =
|
|
867
|
-
const [page, setPage] =
|
|
866
|
+
const [email, setEmail] = React.useState("");
|
|
867
|
+
const [page, setPage] = React.useState(1);
|
|
868
868
|
const { formatMessage } = reactIntl.useIntl();
|
|
869
869
|
const { toggleNotification } = admin.useNotification();
|
|
870
|
-
const fileInputRef =
|
|
870
|
+
const fileInputRef = React.useRef(null);
|
|
871
871
|
const pageCount = Math.ceil(users.length / PAGE_SIZE$1) || 1;
|
|
872
872
|
const paginatedUsers = users.slice((page - 1) * PAGE_SIZE$1, page * PAGE_SIZE$1);
|
|
873
|
-
const onSaveEmail =
|
|
873
|
+
const onSaveEmail = React.useCallback(() => {
|
|
874
874
|
const emailText = email.trim();
|
|
875
875
|
if (users.some((user) => user.email === emailText)) {
|
|
876
876
|
toggleNotification({
|
|
@@ -882,7 +882,7 @@ function Whitelist({
|
|
|
882
882
|
setEmail("");
|
|
883
883
|
}
|
|
884
884
|
}, [email, users, onSave, formatMessage, toggleNotification]);
|
|
885
|
-
const handleImport =
|
|
885
|
+
const handleImport = React.useCallback(
|
|
886
886
|
async (e) => {
|
|
887
887
|
const file = e.target.files?.[0];
|
|
888
888
|
if (!fileInputRef.current || !file) return;
|
|
@@ -1018,7 +1018,7 @@ function Whitelist({
|
|
|
1018
1018
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("whitelist.table.created")) }),
|
|
1019
1019
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { paddingRight: 0 }, children: " " })
|
|
1020
1020
|
] }) }),
|
|
1021
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center",
|
|
1021
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "80px" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage(index.getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index$1) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
1022
1022
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: index$1 + 1 + (page - 1) * PAGE_SIZE$1 }),
|
|
1023
1023
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: user.email }),
|
|
1024
1024
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(LocalizedDate, { date: user.createdAt, options: { second: "2-digit" } }) }),
|
|
@@ -3615,11 +3615,14 @@ const AUDIT_ACTIONS = [
|
|
|
3615
3615
|
"nonce_mismatch",
|
|
3616
3616
|
"token_exchange_failed",
|
|
3617
3617
|
"whitelist_rejected",
|
|
3618
|
+
"email_not_verified",
|
|
3619
|
+
"id_token_invalid",
|
|
3618
3620
|
"logout",
|
|
3619
3621
|
"session_expired",
|
|
3620
3622
|
"user_created"
|
|
3621
3623
|
];
|
|
3622
3624
|
const PAGE_SIZE = 10;
|
|
3625
|
+
const MIN_SPINNER_MS = 400;
|
|
3623
3626
|
const DETAILS_TEXT_STYLE = {
|
|
3624
3627
|
display: "block",
|
|
3625
3628
|
overflow: "hidden",
|
|
@@ -3650,8 +3653,8 @@ function buildQueryString(params) {
|
|
|
3650
3653
|
);
|
|
3651
3654
|
}
|
|
3652
3655
|
function useDebounced(value, delay = 300) {
|
|
3653
|
-
const [debounced, setDebounced] =
|
|
3654
|
-
|
|
3656
|
+
const [debounced, setDebounced] = React.useState(value);
|
|
3657
|
+
React.useEffect(() => {
|
|
3655
3658
|
const id = setTimeout(() => setDebounced(value), delay);
|
|
3656
3659
|
return () => clearTimeout(id);
|
|
3657
3660
|
}, [value, delay]);
|
|
@@ -3661,40 +3664,47 @@ function AuditLog({ title } = {}) {
|
|
|
3661
3664
|
const { formatMessage } = reactIntl.useIntl();
|
|
3662
3665
|
const { get: get2, del } = admin.useFetchClient();
|
|
3663
3666
|
const { toggleNotification } = admin.useNotification();
|
|
3664
|
-
const [records, setRecords] =
|
|
3665
|
-
const [pagination, setPagination] =
|
|
3667
|
+
const [records, setRecords] = React.useState([]);
|
|
3668
|
+
const [pagination, setPagination] = React.useState({
|
|
3666
3669
|
page: 1,
|
|
3667
3670
|
pageSize: PAGE_SIZE,
|
|
3668
3671
|
total: 0,
|
|
3669
3672
|
pageCount: 1
|
|
3670
3673
|
});
|
|
3671
|
-
const [page, setPage] =
|
|
3672
|
-
const [loading, setLoading] =
|
|
3673
|
-
const [filters, setFilters] =
|
|
3674
|
+
const [page, setPage] = React.useState(1);
|
|
3675
|
+
const [loading, setLoading] = React.useState(true);
|
|
3676
|
+
const [filters, setFilters] = React.useState({});
|
|
3677
|
+
const fetchGenRef = React.useRef(0);
|
|
3674
3678
|
const debouncedFilters = useDebounced(filters);
|
|
3675
|
-
const fetchLogs =
|
|
3679
|
+
const fetchLogs = React.useCallback(
|
|
3676
3680
|
async (p, f) => {
|
|
3681
|
+
const gen = ++fetchGenRef.current;
|
|
3677
3682
|
setLoading(true);
|
|
3683
|
+
const startTime = Date.now();
|
|
3684
|
+
let newRecords = [];
|
|
3685
|
+
let newPagination = { page: p, pageSize: PAGE_SIZE, total: 0, pageCount: 1 };
|
|
3678
3686
|
try {
|
|
3679
|
-
const queryString = buildQueryString({
|
|
3680
|
-
filters: f,
|
|
3681
|
-
page: p,
|
|
3682
|
-
pageSize: PAGE_SIZE
|
|
3683
|
-
});
|
|
3687
|
+
const queryString = buildQueryString({ filters: f, page: p, pageSize: PAGE_SIZE });
|
|
3684
3688
|
const response = await get2(`/strapi-plugin-oidc/audit-logs?${queryString}`);
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
+
newRecords = response.data.results ?? [];
|
|
3690
|
+
newPagination = response.data.pagination ?? {
|
|
3691
|
+
page: p,
|
|
3692
|
+
pageSize: PAGE_SIZE,
|
|
3693
|
+
total: 0,
|
|
3694
|
+
pageCount: 1
|
|
3695
|
+
};
|
|
3689
3696
|
} catch {
|
|
3690
|
-
setRecords([]);
|
|
3691
|
-
} finally {
|
|
3692
|
-
setLoading(false);
|
|
3693
3697
|
}
|
|
3698
|
+
const remaining = MIN_SPINNER_MS - (Date.now() - startTime);
|
|
3699
|
+
if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
|
|
3700
|
+
if (gen !== fetchGenRef.current) return;
|
|
3701
|
+
setRecords(newRecords);
|
|
3702
|
+
setPagination(newPagination);
|
|
3703
|
+
setLoading(false);
|
|
3694
3704
|
},
|
|
3695
3705
|
[get2]
|
|
3696
3706
|
);
|
|
3697
|
-
|
|
3707
|
+
React.useEffect(() => {
|
|
3698
3708
|
fetchLogs(page, debouncedFilters);
|
|
3699
3709
|
}, [fetchLogs, page, debouncedFilters]);
|
|
3700
3710
|
const handleClearAll = async () => {
|
|
@@ -3867,37 +3877,54 @@ function AuditLog({ title } = {}) {
|
|
|
3867
3877
|
]
|
|
3868
3878
|
}
|
|
3869
3879
|
),
|
|
3870
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3871
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3872
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3880
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: "100%" }, children: [
|
|
3881
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CustomTable, { colCount: 5, rowCount: records.length, children: [
|
|
3882
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
3883
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.timestamp")) }),
|
|
3884
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.action")) }),
|
|
3885
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.email")) }),
|
|
3886
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.ip")) }),
|
|
3887
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.details")) })
|
|
3888
|
+
] }) }),
|
|
3889
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tbody, { children: [
|
|
3890
|
+
records.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: 5, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "80px" }, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: hasActiveFilters ? formatMessage(index.getTrad("auditlog.filters.empty")) : formatMessage(index.getTrad("auditlog.table.empty")) }) }) }) }),
|
|
3891
|
+
records.map((record) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3892
|
+
designSystem.Tr,
|
|
3893
|
+
{
|
|
3894
|
+
style: { opacity: loading ? 0.4 : 1, transition: "opacity 0.15s" },
|
|
3895
|
+
children: [
|
|
3896
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: /* @__PURE__ */ jsxRuntime.jsx(LocalizedDate, { date: record.createdAt, options: { second: "2-digit" } }) }) }),
|
|
3897
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
|
|
3898
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.action }),
|
|
3899
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: formatMessage(index.getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3900
|
+
icons.Information,
|
|
3901
|
+
{
|
|
3902
|
+
"aria-hidden": true,
|
|
3903
|
+
style: { cursor: "help" },
|
|
3904
|
+
width: "1.4rem",
|
|
3905
|
+
height: "1.4rem",
|
|
3906
|
+
fill: "primary600"
|
|
3907
|
+
}
|
|
3908
|
+
) })
|
|
3909
|
+
] }) }),
|
|
3910
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.email ?? "—" }) }),
|
|
3911
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.ip ?? "—" }) }),
|
|
3912
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { maxWidth: "200px" }, children: record.details ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: record.details, side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", style: DETAILS_TEXT_STYLE, children: record.details }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: "—" }) })
|
|
3913
|
+
]
|
|
3914
|
+
},
|
|
3915
|
+
record.id
|
|
3916
|
+
))
|
|
3917
|
+
] })
|
|
3918
|
+
] }),
|
|
3919
|
+
loading && records.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3920
|
+
designSystem.Flex,
|
|
3921
|
+
{
|
|
3922
|
+
justifyContent: "center",
|
|
3923
|
+
alignItems: "center",
|
|
3924
|
+
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
3925
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
|
3926
|
+
}
|
|
3927
|
+
)
|
|
3901
3928
|
] }),
|
|
3902
3929
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3903
3930
|
TablePagination,
|
|
@@ -4171,8 +4198,8 @@ function isDirtyArray(a, b) {
|
|
|
4171
4198
|
}
|
|
4172
4199
|
function useOidcSettings() {
|
|
4173
4200
|
const { get: get2, put, post } = admin.useFetchClient();
|
|
4174
|
-
const [state, dispatch] =
|
|
4175
|
-
|
|
4201
|
+
const [state, dispatch] = React.useReducer(reducer, initialState);
|
|
4202
|
+
React.useEffect(() => {
|
|
4176
4203
|
get2(`/strapi-plugin-oidc/oidc-roles`).then((response) => {
|
|
4177
4204
|
dispatch({ type: "hydrate/oidcRoles", oidcRoles: response.data });
|
|
4178
4205
|
});
|
|
@@ -4193,19 +4220,19 @@ function useOidcSettings() {
|
|
|
4193
4220
|
});
|
|
4194
4221
|
});
|
|
4195
4222
|
}, [get2]);
|
|
4196
|
-
const onChangeRole =
|
|
4223
|
+
const onChangeRole = React.useCallback((values, oidcId) => {
|
|
4197
4224
|
dispatch({ type: "patch/oidcRole", oidcId, values });
|
|
4198
4225
|
}, []);
|
|
4199
|
-
const onRegisterWhitelist =
|
|
4226
|
+
const onRegisterWhitelist = React.useCallback((email) => {
|
|
4200
4227
|
dispatch({ type: "user/add", email });
|
|
4201
4228
|
}, []);
|
|
4202
|
-
const onDeleteWhitelist =
|
|
4229
|
+
const onDeleteWhitelist = React.useCallback((email) => {
|
|
4203
4230
|
dispatch({ type: "user/delete", email });
|
|
4204
4231
|
}, []);
|
|
4205
|
-
const onDeleteAll =
|
|
4232
|
+
const onDeleteAll = React.useCallback(() => {
|
|
4206
4233
|
dispatch({ type: "users/clear" });
|
|
4207
4234
|
}, []);
|
|
4208
|
-
const onImport =
|
|
4235
|
+
const onImport = React.useCallback(
|
|
4209
4236
|
async (emails) => {
|
|
4210
4237
|
const response = await post("/strapi-plugin-oidc/whitelist/import", {
|
|
4211
4238
|
users: emails.map((e) => ({ email: e }))
|
|
@@ -4217,22 +4244,22 @@ function useOidcSettings() {
|
|
|
4217
4244
|
},
|
|
4218
4245
|
[post, get2]
|
|
4219
4246
|
);
|
|
4220
|
-
const onExport =
|
|
4247
|
+
const onExport = React.useCallback(async () => {
|
|
4221
4248
|
const response = await get2("/strapi-plugin-oidc/whitelist/export");
|
|
4222
4249
|
const data = response.data;
|
|
4223
4250
|
downloadJson("strapi-oidc-whitelist", data);
|
|
4224
4251
|
}, [get2]);
|
|
4225
|
-
const onToggleWhitelist =
|
|
4252
|
+
const onToggleWhitelist = React.useCallback((e) => {
|
|
4226
4253
|
dispatch({ type: "toggle/useWhitelist", value: e.target.checked });
|
|
4227
4254
|
}, []);
|
|
4228
|
-
const onToggleEnforce =
|
|
4255
|
+
const onToggleEnforce = React.useCallback((e) => {
|
|
4229
4256
|
dispatch({ type: "toggle/enforceOIDC", value: e.target.checked });
|
|
4230
4257
|
}, []);
|
|
4231
|
-
const isDirty =
|
|
4258
|
+
const isDirty = React.useMemo(
|
|
4232
4259
|
() => isDirtyPrimitive(state.current.useWhitelist, state.initial.useWhitelist) || isDirtyPrimitive(state.current.enforceOIDC, state.initial.enforceOIDC) || isDirtyArray(state.current.oidcRoles, state.initial.oidcRoles) || isDirtyArray(state.current.users, state.initial.users),
|
|
4233
4260
|
[state.current, state.initial]
|
|
4234
4261
|
);
|
|
4235
|
-
const onSaveAll =
|
|
4262
|
+
const onSaveAll = React.useCallback(async () => {
|
|
4236
4263
|
dispatch({ type: "loading", value: true });
|
|
4237
4264
|
try {
|
|
4238
4265
|
await Promise.all([
|
|
@@ -4407,7 +4434,7 @@ function HomePage$1() {
|
|
|
4407
4434
|
] }) })
|
|
4408
4435
|
] });
|
|
4409
4436
|
}
|
|
4410
|
-
const HomePage =
|
|
4437
|
+
const HomePage = React.memo(HomePage$1);
|
|
4411
4438
|
function App() {
|
|
4412
4439
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
|
|
4413
4440
|
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(HomePage, {}) }),
|
|
@@ -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-
|
|
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",
|
|
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" } }) }),
|
|
@@ -3611,11 +3611,14 @@ const AUDIT_ACTIONS = [
|
|
|
3611
3611
|
"nonce_mismatch",
|
|
3612
3612
|
"token_exchange_failed",
|
|
3613
3613
|
"whitelist_rejected",
|
|
3614
|
+
"email_not_verified",
|
|
3615
|
+
"id_token_invalid",
|
|
3614
3616
|
"logout",
|
|
3615
3617
|
"session_expired",
|
|
3616
3618
|
"user_created"
|
|
3617
3619
|
];
|
|
3618
3620
|
const PAGE_SIZE = 10;
|
|
3621
|
+
const MIN_SPINNER_MS = 400;
|
|
3619
3622
|
const DETAILS_TEXT_STYLE = {
|
|
3620
3623
|
display: "block",
|
|
3621
3624
|
overflow: "hidden",
|
|
@@ -3665,28 +3668,35 @@ function AuditLog({ title } = {}) {
|
|
|
3665
3668
|
pageCount: 1
|
|
3666
3669
|
});
|
|
3667
3670
|
const [page, setPage] = useState(1);
|
|
3668
|
-
const [loading, setLoading] = useState(
|
|
3671
|
+
const [loading, setLoading] = useState(true);
|
|
3669
3672
|
const [filters, setFilters] = useState({});
|
|
3673
|
+
const fetchGenRef = useRef(0);
|
|
3670
3674
|
const debouncedFilters = useDebounced(filters);
|
|
3671
3675
|
const fetchLogs = useCallback(
|
|
3672
3676
|
async (p, f) => {
|
|
3677
|
+
const gen = ++fetchGenRef.current;
|
|
3673
3678
|
setLoading(true);
|
|
3679
|
+
const startTime = Date.now();
|
|
3680
|
+
let newRecords = [];
|
|
3681
|
+
let newPagination = { page: p, pageSize: PAGE_SIZE, total: 0, pageCount: 1 };
|
|
3674
3682
|
try {
|
|
3675
|
-
const queryString = buildQueryString({
|
|
3676
|
-
filters: f,
|
|
3677
|
-
page: p,
|
|
3678
|
-
pageSize: PAGE_SIZE
|
|
3679
|
-
});
|
|
3683
|
+
const queryString = buildQueryString({ filters: f, page: p, pageSize: PAGE_SIZE });
|
|
3680
3684
|
const response = await get2(`/strapi-plugin-oidc/audit-logs?${queryString}`);
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
+
newRecords = response.data.results ?? [];
|
|
3686
|
+
newPagination = response.data.pagination ?? {
|
|
3687
|
+
page: p,
|
|
3688
|
+
pageSize: PAGE_SIZE,
|
|
3689
|
+
total: 0,
|
|
3690
|
+
pageCount: 1
|
|
3691
|
+
};
|
|
3685
3692
|
} catch {
|
|
3686
|
-
setRecords([]);
|
|
3687
|
-
} finally {
|
|
3688
|
-
setLoading(false);
|
|
3689
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);
|
|
3690
3700
|
},
|
|
3691
3701
|
[get2]
|
|
3692
3702
|
);
|
|
@@ -3863,37 +3873,54 @@ function AuditLog({ title } = {}) {
|
|
|
3863
3873
|
]
|
|
3864
3874
|
}
|
|
3865
3875
|
),
|
|
3866
|
-
/* @__PURE__ */ jsxs(
|
|
3867
|
-
/* @__PURE__ */
|
|
3868
|
-
/* @__PURE__ */ jsx(
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
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
|
+
)
|
|
3897
3924
|
] }),
|
|
3898
3925
|
/* @__PURE__ */ jsx(
|
|
3899
3926
|
TablePagination,
|