strapi-plugin-oidc 1.8.4 → 1.9.0
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 +11 -3
- package/dist/admin/{index-Bmg4eTYb.js → index-BbgFpvmz.js} +218 -194
- package/dist/admin/{index-Dk6TYtio.js → index-BqKuUY5d.js} +31 -13
- package/dist/admin/{index-BqWd-Iiq.mjs → index-Dq99roxb.mjs} +215 -191
- package/dist/admin/{index-Bb9-aYb4.mjs → index-LcYvW0bR.mjs} +31 -13
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +3657 -669
- package/dist/server/index.mjs +3658 -670
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ module.exports = ({ env }) => ({
|
|
|
48
48
|
OIDC_GROUP_FIELD: 'groups', // OIDC claim field containing group membership
|
|
49
49
|
OIDC_GROUP_ROLE_MAP: '{}', // JSON map of group names to Strapi role names
|
|
50
50
|
OIDC_REQUIRE_EMAIL_VERIFIED: true, // Reject logins when provider does not report email_verified=true (set false to disable)
|
|
51
|
-
OIDC_TRUSTED_IP_HEADER: '', // Optional: header set by your CDN/proxy containing the real client IP (see note below); only honoured when
|
|
51
|
+
OIDC_TRUSTED_IP_HEADER: '', // Optional: header set by your CDN/proxy containing the real client IP (see note below); only honoured when Koa proxy mode is enabled (see below)
|
|
52
52
|
OIDC_FORCE_SECURE_COOKIES: false, // Set true when behind a trusted HTTPS proxy that Strapi can't auto-detect
|
|
53
53
|
},
|
|
54
54
|
},
|
|
@@ -67,9 +67,17 @@ module.exports = ({ env }) => ({
|
|
|
67
67
|
|
|
68
68
|
### Client IP attribution and reverse proxies
|
|
69
69
|
|
|
70
|
-
The plugin logs client IPs for rate-limit buckets and audit logs. When Strapi runs behind a reverse proxy,
|
|
70
|
+
The plugin logs client IPs for rate-limit buckets and audit logs. When Strapi runs behind a reverse proxy, enable Koa proxy mode so Strapi trusts `X-Forwarded-For`; otherwise all IPs will be the proxy's internal address.
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
In `config/server.ts`:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
proxy: {
|
|
76
|
+
koa: true,
|
|
77
|
+
},
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Set `OIDC_TRUSTED_IP_HEADER` to the header your CDN or proxy uses to forward the real client IP. The header is only honoured when Koa proxy mode is enabled. Accepted values (all others are silently ignored):
|
|
73
81
|
|
|
74
82
|
| Header | Provider |
|
|
75
83
|
| --------------------------- | ------------------------------------------------- |
|
|
@@ -7,7 +7,7 @@ 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-BqKuUY5d.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 };
|
|
@@ -426,7 +426,14 @@ const DayButton = styled__default.default.button`
|
|
|
426
426
|
aspect-ratio: 1;
|
|
427
427
|
border: none;
|
|
428
428
|
background: ${({ $selected, $inRange, $pending, theme }) => $pending ? theme.colors.warning200 : $selected ? theme.colors.primary600 : $inRange ? theme.colors.primary100 : "transparent"};
|
|
429
|
-
color: ${({
|
|
429
|
+
color: ${({
|
|
430
|
+
$selected,
|
|
431
|
+
$inRange,
|
|
432
|
+
$pending,
|
|
433
|
+
$future: _future,
|
|
434
|
+
$alreadySelected: _alreadySelected,
|
|
435
|
+
theme
|
|
436
|
+
}) => $pending ? theme.colors.warning600 : $selected ? theme.colors.neutral0 : $inRange ? theme.colors.primary600 : theme.colors.neutral800};
|
|
430
437
|
opacity: ${({ $future, $alreadySelected }) => $future || $alreadySelected ? 0.4 : 1};
|
|
431
438
|
border-radius: 4px;
|
|
432
439
|
cursor: pointer;
|
|
@@ -852,7 +859,6 @@ function TablePagination({ page, pageCount, onPageChange, total }) {
|
|
|
852
859
|
] }) });
|
|
853
860
|
}
|
|
854
861
|
const PAGE_SIZE$1 = 10;
|
|
855
|
-
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
856
862
|
function Whitelist({
|
|
857
863
|
users,
|
|
858
864
|
useWhitelist,
|
|
@@ -893,7 +899,7 @@ function Whitelist({
|
|
|
893
899
|
if (!Array.isArray(parsed)) throw new Error();
|
|
894
900
|
const emails = parsed.filter((item) => item?.email).map(
|
|
895
901
|
(item) => String(item.email).trim().toLowerCase()
|
|
896
|
-
).filter((email2) => EMAIL_REGEX.test(email2));
|
|
902
|
+
).filter((email2) => index.EMAIL_REGEX.test(email2));
|
|
897
903
|
const count = await onImport(emails);
|
|
898
904
|
if (count === 0) {
|
|
899
905
|
toggleNotification({
|
|
@@ -935,7 +941,7 @@ function Whitelist({
|
|
|
935
941
|
type: "text",
|
|
936
942
|
disabled: loading,
|
|
937
943
|
value: email,
|
|
938
|
-
hasError: Boolean(email && !EMAIL_REGEX.test(email)),
|
|
944
|
+
hasError: Boolean(email && !index.EMAIL_REGEX.test(email)),
|
|
939
945
|
onChange: (e) => setEmail(e.currentTarget.value),
|
|
940
946
|
placeholder: formatMessage(index.getTrad("whitelist.email.placeholder")),
|
|
941
947
|
style: { fontSize: "1.4rem", lineHeight: "2.2rem" }
|
|
@@ -946,7 +952,7 @@ function Whitelist({
|
|
|
946
952
|
{
|
|
947
953
|
size: "S",
|
|
948
954
|
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
|
|
949
|
-
disabled: loading || email.trim() === "" || !EMAIL_REGEX.test(email),
|
|
955
|
+
disabled: loading || email.trim() === "" || !index.EMAIL_REGEX.test(email),
|
|
950
956
|
loading,
|
|
951
957
|
onClick: onSaveEmail,
|
|
952
958
|
children: formatMessage(index.getTrad("page.add"))
|
|
@@ -1066,6 +1072,163 @@ function Whitelist({
|
|
|
1066
1072
|
] })
|
|
1067
1073
|
] });
|
|
1068
1074
|
}
|
|
1075
|
+
const AUDIT_ACTIONS = [
|
|
1076
|
+
"login_success",
|
|
1077
|
+
"login_failure",
|
|
1078
|
+
"missing_code",
|
|
1079
|
+
"state_mismatch",
|
|
1080
|
+
"nonce_mismatch",
|
|
1081
|
+
"token_exchange_failed",
|
|
1082
|
+
"whitelist_rejected",
|
|
1083
|
+
"email_not_verified",
|
|
1084
|
+
"id_token_invalid",
|
|
1085
|
+
"logout",
|
|
1086
|
+
"session_expired",
|
|
1087
|
+
"user_created"
|
|
1088
|
+
];
|
|
1089
|
+
const IP_REGEX = /^(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|::))$/;
|
|
1090
|
+
function FilterBar({
|
|
1091
|
+
filters,
|
|
1092
|
+
hasActiveFilters,
|
|
1093
|
+
onFiltersChange,
|
|
1094
|
+
onResetPage,
|
|
1095
|
+
onClear
|
|
1096
|
+
}) {
|
|
1097
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
1098
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1099
|
+
designSystem.Box,
|
|
1100
|
+
{
|
|
1101
|
+
background: "neutral100",
|
|
1102
|
+
hasRadius: true,
|
|
1103
|
+
padding: 4,
|
|
1104
|
+
marginBottom: 4,
|
|
1105
|
+
borderColor: "neutral200",
|
|
1106
|
+
borderWidth: "1px",
|
|
1107
|
+
borderStyle: "solid",
|
|
1108
|
+
children: [
|
|
1109
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", marginBottom: 3, children: [
|
|
1110
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { size: "1.6rem" }) }),
|
|
1111
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h3", children: formatMessage(index.getTrad("auditlog.filters")) })
|
|
1112
|
+
] }),
|
|
1113
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, wrap: "wrap", children: [
|
|
1114
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1115
|
+
TagDateInput,
|
|
1116
|
+
{
|
|
1117
|
+
placeholder: formatMessage(index.getTrad("auditlog.filters.createdAt")),
|
|
1118
|
+
value: filters.createdAt ?? [],
|
|
1119
|
+
onChange: (selections) => {
|
|
1120
|
+
onFiltersChange((prev) => {
|
|
1121
|
+
if (selections.length === 0) {
|
|
1122
|
+
const { createdAt: _createdAt, ...rest } = prev;
|
|
1123
|
+
return rest;
|
|
1124
|
+
}
|
|
1125
|
+
return { ...prev, createdAt: selections };
|
|
1126
|
+
});
|
|
1127
|
+
onResetPage();
|
|
1128
|
+
},
|
|
1129
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Calendar, { width: "1.4rem", height: "1.4rem" }) })
|
|
1130
|
+
}
|
|
1131
|
+
),
|
|
1132
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1133
|
+
TagInput,
|
|
1134
|
+
{
|
|
1135
|
+
value: filters.action ?? [],
|
|
1136
|
+
onChange: (value) => onFiltersChange((prev) => ({ ...prev, action: value })),
|
|
1137
|
+
options: AUDIT_ACTIONS,
|
|
1138
|
+
placeholder: formatMessage(index.getTrad("auditlog.filters.action")),
|
|
1139
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClipboardList, { size: "1.4rem" }) })
|
|
1140
|
+
}
|
|
1141
|
+
),
|
|
1142
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1143
|
+
TagInput,
|
|
1144
|
+
{
|
|
1145
|
+
value: filters.email ?? [],
|
|
1146
|
+
onChange: (value) => onFiltersChange((prev) => ({ ...prev, email: value })),
|
|
1147
|
+
placeholder: formatMessage(index.getTrad("auditlog.filters.email")),
|
|
1148
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Mail, { width: "1.4rem", height: "1.4rem" }) }),
|
|
1149
|
+
validate: (v) => index.EMAIL_REGEX.test(v)
|
|
1150
|
+
}
|
|
1151
|
+
),
|
|
1152
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1153
|
+
TagInput,
|
|
1154
|
+
{
|
|
1155
|
+
value: filters.ip ?? [],
|
|
1156
|
+
onChange: (value) => onFiltersChange((prev) => ({ ...prev, ip: value })),
|
|
1157
|
+
placeholder: formatMessage(index.getTrad("auditlog.filters.ip")),
|
|
1158
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Server, { size: "1.4rem" }) }),
|
|
1159
|
+
validate: (v) => IP_REGEX.test(v)
|
|
1160
|
+
}
|
|
1161
|
+
),
|
|
1162
|
+
hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsx(SizedButton, { size: "S", variant: "danger-light", startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}), onClick: onClear, children: formatMessage(index.getTrad("auditlog.filters.clear")) })
|
|
1163
|
+
] })
|
|
1164
|
+
]
|
|
1165
|
+
}
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
const DETAILS_TEXT_STYLE = {
|
|
1169
|
+
display: "block",
|
|
1170
|
+
overflow: "hidden",
|
|
1171
|
+
textOverflow: "ellipsis",
|
|
1172
|
+
whiteSpace: "nowrap",
|
|
1173
|
+
maxWidth: "180px",
|
|
1174
|
+
cursor: "help"
|
|
1175
|
+
};
|
|
1176
|
+
function LogTable({ records, loading, hasActiveFilters }) {
|
|
1177
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
1178
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: "100%" }, children: [
|
|
1179
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CustomTable, { colCount: 5, rowCount: records.length, children: [
|
|
1180
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
1181
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.timestamp")) }),
|
|
1182
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.action")) }),
|
|
1183
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.email")) }),
|
|
1184
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.ip")) }),
|
|
1185
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("auditlog.table.details")) })
|
|
1186
|
+
] }) }),
|
|
1187
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tbody, { children: [
|
|
1188
|
+
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")) }) }) }) }),
|
|
1189
|
+
records.map((record) => {
|
|
1190
|
+
const detailKey = record.detailsKey ? `audit.${record.detailsKey}` : null;
|
|
1191
|
+
const detail = detailKey && index.en[detailKey] ? formatMessage(index.getTrad(detailKey), record.detailsParams ?? {}) : null;
|
|
1192
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1193
|
+
designSystem.Tr,
|
|
1194
|
+
{
|
|
1195
|
+
style: { opacity: loading ? 0.4 : 1, transition: "opacity 0.15s" },
|
|
1196
|
+
children: [
|
|
1197
|
+
/* @__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" } }) }) }),
|
|
1198
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
|
|
1199
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.action }),
|
|
1200
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: formatMessage(index.getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1201
|
+
icons.Information,
|
|
1202
|
+
{
|
|
1203
|
+
"aria-hidden": true,
|
|
1204
|
+
style: { cursor: "help" },
|
|
1205
|
+
width: "1.4rem",
|
|
1206
|
+
height: "1.4rem",
|
|
1207
|
+
fill: "primary600"
|
|
1208
|
+
}
|
|
1209
|
+
) })
|
|
1210
|
+
] }) }),
|
|
1211
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.email ?? "—" }) }),
|
|
1212
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.ip ?? "—" }) }),
|
|
1213
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { maxWidth: "200px" }, children: detail ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: detail, side: "top", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", style: DETAILS_TEXT_STYLE, children: detail }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: "—" }) })
|
|
1214
|
+
]
|
|
1215
|
+
},
|
|
1216
|
+
record.id
|
|
1217
|
+
);
|
|
1218
|
+
})
|
|
1219
|
+
] })
|
|
1220
|
+
] }),
|
|
1221
|
+
loading && records.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1222
|
+
designSystem.Flex,
|
|
1223
|
+
{
|
|
1224
|
+
justifyContent: "center",
|
|
1225
|
+
alignItems: "center",
|
|
1226
|
+
style: { position: "absolute", inset: 0, pointerEvents: "none" },
|
|
1227
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true })
|
|
1228
|
+
}
|
|
1229
|
+
)
|
|
1230
|
+
] });
|
|
1231
|
+
}
|
|
1069
1232
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
1070
1233
|
function getDefaultExportFromCjs(x) {
|
|
1071
1234
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
@@ -3607,30 +3770,6 @@ function requireLib() {
|
|
|
3607
3770
|
}
|
|
3608
3771
|
var libExports = /* @__PURE__ */ requireLib();
|
|
3609
3772
|
const qs = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
|
|
3610
|
-
const AUDIT_ACTIONS = [
|
|
3611
|
-
"login_success",
|
|
3612
|
-
"login_failure",
|
|
3613
|
-
"missing_code",
|
|
3614
|
-
"state_mismatch",
|
|
3615
|
-
"nonce_mismatch",
|
|
3616
|
-
"token_exchange_failed",
|
|
3617
|
-
"whitelist_rejected",
|
|
3618
|
-
"email_not_verified",
|
|
3619
|
-
"id_token_invalid",
|
|
3620
|
-
"logout",
|
|
3621
|
-
"session_expired",
|
|
3622
|
-
"user_created"
|
|
3623
|
-
];
|
|
3624
|
-
const PAGE_SIZE = 10;
|
|
3625
|
-
const MIN_SPINNER_MS = 400;
|
|
3626
|
-
const DETAILS_TEXT_STYLE = {
|
|
3627
|
-
display: "block",
|
|
3628
|
-
overflow: "hidden",
|
|
3629
|
-
textOverflow: "ellipsis",
|
|
3630
|
-
whiteSpace: "nowrap",
|
|
3631
|
-
maxWidth: "180px",
|
|
3632
|
-
cursor: "help"
|
|
3633
|
-
};
|
|
3634
3773
|
function toWireFilters(f) {
|
|
3635
3774
|
const out = {};
|
|
3636
3775
|
if (f.action?.length) out.action = { $or: f.action.map((v) => ({ $eq: v })) };
|
|
@@ -3647,11 +3786,10 @@ function buildQueryString(params) {
|
|
|
3647
3786
|
const { filters, ...rest } = params;
|
|
3648
3787
|
return qs.stringify(
|
|
3649
3788
|
{ ...rest, filters: filters ? toWireFilters(filters) : void 0 },
|
|
3650
|
-
{
|
|
3651
|
-
encodeValuesOnly: true
|
|
3652
|
-
}
|
|
3789
|
+
{ encodeValuesOnly: true }
|
|
3653
3790
|
);
|
|
3654
3791
|
}
|
|
3792
|
+
const PAGE_SIZE = index.AUDIT_LOG_DEFAULTS.ADMIN_PAGE_SIZE;
|
|
3655
3793
|
function useDebounced(value, delay = 300) {
|
|
3656
3794
|
const [debounced, setDebounced] = React.useState(value);
|
|
3657
3795
|
React.useEffect(() => {
|
|
@@ -3660,10 +3798,8 @@ function useDebounced(value, delay = 300) {
|
|
|
3660
3798
|
}, [value, delay]);
|
|
3661
3799
|
return debounced;
|
|
3662
3800
|
}
|
|
3663
|
-
function
|
|
3664
|
-
const {
|
|
3665
|
-
const { get: get2, del } = admin.useFetchClient();
|
|
3666
|
-
const { toggleNotification } = admin.useNotification();
|
|
3801
|
+
function useAuditLogs(page, filters) {
|
|
3802
|
+
const { get: get2 } = admin.useFetchClient();
|
|
3667
3803
|
const [records, setRecords] = React.useState([]);
|
|
3668
3804
|
const [pagination, setPagination] = React.useState({
|
|
3669
3805
|
page: 1,
|
|
@@ -3671,9 +3807,7 @@ function AuditLog({ title } = {}) {
|
|
|
3671
3807
|
total: 0,
|
|
3672
3808
|
pageCount: 1
|
|
3673
3809
|
});
|
|
3674
|
-
const [page, setPage] = React.useState(1);
|
|
3675
3810
|
const [loading, setLoading] = React.useState(true);
|
|
3676
|
-
const [filters, setFilters] = React.useState({});
|
|
3677
3811
|
const fetchGenRef = React.useRef(0);
|
|
3678
3812
|
const debouncedFilters = useDebounced(filters);
|
|
3679
3813
|
const fetchLogs = React.useCallback(
|
|
@@ -3695,7 +3829,7 @@ function AuditLog({ title } = {}) {
|
|
|
3695
3829
|
};
|
|
3696
3830
|
} catch {
|
|
3697
3831
|
}
|
|
3698
|
-
const remaining = MIN_SPINNER_MS - (Date.now() - startTime);
|
|
3832
|
+
const remaining = index.UI_DEFAULTS.MIN_SPINNER_MS - (Date.now() - startTime);
|
|
3699
3833
|
if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
|
|
3700
3834
|
if (gen !== fetchGenRef.current) return;
|
|
3701
3835
|
setRecords(newRecords);
|
|
@@ -3707,6 +3841,15 @@ function AuditLog({ title } = {}) {
|
|
|
3707
3841
|
React.useEffect(() => {
|
|
3708
3842
|
fetchLogs(page, debouncedFilters);
|
|
3709
3843
|
}, [fetchLogs, page, debouncedFilters]);
|
|
3844
|
+
return { records, pagination, loading };
|
|
3845
|
+
}
|
|
3846
|
+
function AuditLog({ title } = {}) {
|
|
3847
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
3848
|
+
const { del } = admin.useFetchClient();
|
|
3849
|
+
const { toggleNotification } = admin.useNotification();
|
|
3850
|
+
const [page, setPage] = React.useState(1);
|
|
3851
|
+
const [filters, setFilters] = React.useState({});
|
|
3852
|
+
const { records, pagination, loading } = useAuditLogs(page, filters);
|
|
3710
3853
|
const handleClearAll = async () => {
|
|
3711
3854
|
try {
|
|
3712
3855
|
await del("/strapi-plugin-oidc/audit-logs");
|
|
@@ -3727,9 +3870,7 @@ function AuditLog({ title } = {}) {
|
|
|
3727
3870
|
try {
|
|
3728
3871
|
const cookieMatch = document.cookie.match(/(?:^|;\s*)jwtToken=([^;]+)/);
|
|
3729
3872
|
const token = cookieMatch ? decodeURIComponent(cookieMatch[1]) : "";
|
|
3730
|
-
const queryString = buildQueryString({
|
|
3731
|
-
filters
|
|
3732
|
-
});
|
|
3873
|
+
const queryString = buildQueryString({ filters });
|
|
3733
3874
|
const response = await fetch(`/strapi-plugin-oidc/audit-logs/export?${queryString}`, {
|
|
3734
3875
|
headers: { Authorization: `Bearer ${token}` }
|
|
3735
3876
|
});
|
|
@@ -3797,135 +3938,17 @@ function AuditLog({ title } = {}) {
|
|
|
3797
3938
|
)
|
|
3798
3939
|
] })
|
|
3799
3940
|
] }),
|
|
3800
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3801
|
-
|
|
3941
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3942
|
+
FilterBar,
|
|
3802
3943
|
{
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
borderWidth: "1px",
|
|
3809
|
-
borderStyle: "solid",
|
|
3810
|
-
children: [
|
|
3811
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", marginBottom: 3, children: [
|
|
3812
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Filter, { size: "1.6rem" }) }),
|
|
3813
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h3", children: formatMessage(index.getTrad("auditlog.filters")) })
|
|
3814
|
-
] }),
|
|
3815
|
-
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, wrap: "wrap", children: [
|
|
3816
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3817
|
-
TagDateInput,
|
|
3818
|
-
{
|
|
3819
|
-
placeholder: formatMessage(index.getTrad("auditlog.filters.createdAt")),
|
|
3820
|
-
value: filters.createdAt ?? [],
|
|
3821
|
-
onChange: (selections) => {
|
|
3822
|
-
setFilters((prev) => {
|
|
3823
|
-
if (selections.length === 0) {
|
|
3824
|
-
const { createdAt: _removed, ...rest } = prev;
|
|
3825
|
-
return rest;
|
|
3826
|
-
}
|
|
3827
|
-
return { ...prev, createdAt: selections };
|
|
3828
|
-
});
|
|
3829
|
-
setPage(1);
|
|
3830
|
-
},
|
|
3831
|
-
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Calendar, { width: "1.4rem", height: "1.4rem" }) })
|
|
3832
|
-
}
|
|
3833
|
-
),
|
|
3834
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3835
|
-
TagInput,
|
|
3836
|
-
{
|
|
3837
|
-
value: filters.action ?? [],
|
|
3838
|
-
onChange: (value) => setFilters((prev) => ({ ...prev, action: value })),
|
|
3839
|
-
options: AUDIT_ACTIONS,
|
|
3840
|
-
placeholder: formatMessage(index.getTrad("auditlog.filters.action")),
|
|
3841
|
-
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClipboardList, { size: "1.4rem" }) })
|
|
3842
|
-
}
|
|
3843
|
-
),
|
|
3844
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3845
|
-
TagInput,
|
|
3846
|
-
{
|
|
3847
|
-
value: filters.email ?? [],
|
|
3848
|
-
onChange: (value) => setFilters((prev) => ({ ...prev, email: value })),
|
|
3849
|
-
placeholder: formatMessage(index.getTrad("auditlog.filters.email")),
|
|
3850
|
-
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Mail, { width: "1.4rem", height: "1.4rem" }) }),
|
|
3851
|
-
validate: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)
|
|
3852
|
-
}
|
|
3853
|
-
),
|
|
3854
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3855
|
-
TagInput,
|
|
3856
|
-
{
|
|
3857
|
-
value: filters.ip ?? [],
|
|
3858
|
-
onChange: (value) => setFilters((prev) => ({ ...prev, ip: value })),
|
|
3859
|
-
placeholder: formatMessage(index.getTrad("auditlog.filters.ip")),
|
|
3860
|
-
startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Server, { size: "1.4rem" }) }),
|
|
3861
|
-
validate: (v) => /^(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|::))$/.test(
|
|
3862
|
-
v
|
|
3863
|
-
)
|
|
3864
|
-
}
|
|
3865
|
-
),
|
|
3866
|
-
hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3867
|
-
SizedButton,
|
|
3868
|
-
{
|
|
3869
|
-
size: "S",
|
|
3870
|
-
variant: "danger-light",
|
|
3871
|
-
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
|
|
3872
|
-
onClick: clearFilters,
|
|
3873
|
-
children: formatMessage(index.getTrad("auditlog.filters.clear"))
|
|
3874
|
-
}
|
|
3875
|
-
)
|
|
3876
|
-
] })
|
|
3877
|
-
]
|
|
3944
|
+
filters,
|
|
3945
|
+
hasActiveFilters,
|
|
3946
|
+
onFiltersChange: setFilters,
|
|
3947
|
+
onResetPage: () => setPage(1),
|
|
3948
|
+
onClear: clearFilters
|
|
3878
3949
|
}
|
|
3879
3950
|
),
|
|
3880
|
-
/* @__PURE__ */ jsxRuntime.
|
|
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
|
-
)
|
|
3928
|
-
] }),
|
|
3951
|
+
/* @__PURE__ */ jsxRuntime.jsx(LogTable, { records, loading, hasActiveFilters }),
|
|
3929
3952
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3930
3953
|
TablePagination,
|
|
3931
3954
|
{
|
|
@@ -3995,7 +4018,7 @@ const SwitchInput = styled__default.default.input`
|
|
|
3995
4018
|
&:checked + span:before {
|
|
3996
4019
|
transform: translateX(16px);
|
|
3997
4020
|
}
|
|
3998
|
-
|
|
4021
|
+
|
|
3999
4022
|
&:disabled + span {
|
|
4000
4023
|
pointer-events: none;
|
|
4001
4024
|
}
|
|
@@ -4013,7 +4036,7 @@ const SwitchSlider = styled__default.default.span`
|
|
|
4013
4036
|
|
|
4014
4037
|
&:before {
|
|
4015
4038
|
position: absolute;
|
|
4016
|
-
content:
|
|
4039
|
+
content: '';
|
|
4017
4040
|
height: 18px;
|
|
4018
4041
|
width: 18px;
|
|
4019
4042
|
left: 3px;
|
|
@@ -4023,21 +4046,26 @@ const SwitchSlider = styled__default.default.span`
|
|
|
4023
4046
|
border-radius: 50%;
|
|
4024
4047
|
}
|
|
4025
4048
|
`;
|
|
4026
|
-
function CustomSwitch({
|
|
4049
|
+
function CustomSwitch({
|
|
4050
|
+
checked,
|
|
4051
|
+
onChange,
|
|
4052
|
+
label,
|
|
4053
|
+
disabled
|
|
4054
|
+
}) {
|
|
4027
4055
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, children: [
|
|
4028
4056
|
/* @__PURE__ */ jsxRuntime.jsxs(SwitchContainer, { $disabled: disabled, children: [
|
|
4029
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4030
|
-
SwitchInput,
|
|
4031
|
-
{
|
|
4032
|
-
type: "checkbox",
|
|
4033
|
-
checked,
|
|
4034
|
-
onChange,
|
|
4035
|
-
disabled
|
|
4036
|
-
}
|
|
4037
|
-
),
|
|
4057
|
+
/* @__PURE__ */ jsxRuntime.jsx(SwitchInput, { type: "checkbox", checked, onChange, disabled }),
|
|
4038
4058
|
/* @__PURE__ */ jsxRuntime.jsx(SwitchSlider, {})
|
|
4039
4059
|
] }),
|
|
4040
|
-
label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4060
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4061
|
+
designSystem.Typography,
|
|
4062
|
+
{
|
|
4063
|
+
variant: "pi",
|
|
4064
|
+
fontWeight: "bold",
|
|
4065
|
+
textColor: disabled ? "neutral500" : "neutral800",
|
|
4066
|
+
children: label
|
|
4067
|
+
}
|
|
4068
|
+
)
|
|
4041
4069
|
] });
|
|
4042
4070
|
}
|
|
4043
4071
|
function formatDatetimeForFilename(date) {
|
|
@@ -4059,19 +4087,15 @@ function downloadJson(basename, data) {
|
|
|
4059
4087
|
a.click();
|
|
4060
4088
|
URL.revokeObjectURL(url);
|
|
4061
4089
|
}
|
|
4090
|
+
const defaultSnapshot = {
|
|
4091
|
+
oidcRoles: [],
|
|
4092
|
+
users: [],
|
|
4093
|
+
useWhitelist: false,
|
|
4094
|
+
enforceOIDC: false
|
|
4095
|
+
};
|
|
4062
4096
|
const initialState = {
|
|
4063
|
-
current: {
|
|
4064
|
-
|
|
4065
|
-
users: [],
|
|
4066
|
-
useWhitelist: false,
|
|
4067
|
-
enforceOIDC: false
|
|
4068
|
-
},
|
|
4069
|
-
initial: {
|
|
4070
|
-
oidcRoles: [],
|
|
4071
|
-
users: [],
|
|
4072
|
-
useWhitelist: false,
|
|
4073
|
-
enforceOIDC: false
|
|
4074
|
-
},
|
|
4097
|
+
current: { ...defaultSnapshot },
|
|
4098
|
+
initial: { ...defaultSnapshot },
|
|
4075
4099
|
roles: [],
|
|
4076
4100
|
enforceOIDCConfig: null,
|
|
4077
4101
|
auditLogEnabled: true,
|
|
@@ -177,7 +177,10 @@ const en = {
|
|
|
177
177
|
"user.invalid_state": "State parameter mismatch. Please restart the login flow.",
|
|
178
178
|
"user.signInError": "Authentication failed. Please try again.",
|
|
179
179
|
"settings.section": "OIDC",
|
|
180
|
-
"settings.configuration": "Configuration"
|
|
180
|
+
"settings.configuration": "Configuration",
|
|
181
|
+
"audit.login_failure": "Error: {message}",
|
|
182
|
+
"audit.roles_updated": "Roles updated to: {roles}",
|
|
183
|
+
"audit.user_created": "Roles assigned: {roles}"
|
|
181
184
|
};
|
|
182
185
|
function getTrad(id) {
|
|
183
186
|
const pluginIdWithId = `${pluginId}.${id}`;
|
|
@@ -189,9 +192,31 @@ function getTrad(id) {
|
|
|
189
192
|
function t(id) {
|
|
190
193
|
return en[id];
|
|
191
194
|
}
|
|
195
|
+
const PLUGIN_UID = "plugin::strapi-plugin-oidc";
|
|
196
|
+
const PERMISSIONS = {
|
|
197
|
+
READ: `${PLUGIN_UID}.read`
|
|
198
|
+
};
|
|
199
|
+
const AUDIT_LOG_DEFAULTS = {
|
|
200
|
+
ADMIN_PAGE_SIZE: 10
|
|
201
|
+
};
|
|
202
|
+
const UI_DEFAULTS = {
|
|
203
|
+
MIN_SPINNER_MS: 400
|
|
204
|
+
};
|
|
205
|
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
192
206
|
const name = pluginPkg.strapi.displayName;
|
|
193
207
|
const index = {
|
|
194
208
|
register(app) {
|
|
209
|
+
const AppPage = React__default.default.lazy(() => Promise.resolve().then(() => require("./index-BbgFpvmz.js")));
|
|
210
|
+
const link = {
|
|
211
|
+
id: "configuration",
|
|
212
|
+
to: `/settings/${pluginId}`,
|
|
213
|
+
intlLabel: {
|
|
214
|
+
id: "settings.configuration",
|
|
215
|
+
defaultMessage: "Configuration"
|
|
216
|
+
},
|
|
217
|
+
Component: AppPage,
|
|
218
|
+
permissions: [{ action: PERMISSIONS.READ, subject: null }]
|
|
219
|
+
};
|
|
195
220
|
app.addSettingsLink(
|
|
196
221
|
{
|
|
197
222
|
id: "oidc",
|
|
@@ -200,18 +225,7 @@ const index = {
|
|
|
200
225
|
defaultMessage: "OIDC"
|
|
201
226
|
}
|
|
202
227
|
},
|
|
203
|
-
|
|
204
|
-
id: "configuration",
|
|
205
|
-
to: `/settings/${pluginId}`,
|
|
206
|
-
intlLabel: {
|
|
207
|
-
id: "settings.configuration",
|
|
208
|
-
defaultMessage: "Configuration"
|
|
209
|
-
},
|
|
210
|
-
Component: async () => {
|
|
211
|
-
return await Promise.resolve().then(() => require("./index-Bmg4eTYb.js"));
|
|
212
|
-
},
|
|
213
|
-
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
214
|
-
}
|
|
228
|
+
link
|
|
215
229
|
);
|
|
216
230
|
app.registerPlugin({
|
|
217
231
|
id: pluginId,
|
|
@@ -344,5 +358,9 @@ const index = {
|
|
|
344
358
|
return importedTrads;
|
|
345
359
|
}
|
|
346
360
|
};
|
|
361
|
+
exports.AUDIT_LOG_DEFAULTS = AUDIT_LOG_DEFAULTS;
|
|
362
|
+
exports.EMAIL_REGEX = EMAIL_REGEX;
|
|
363
|
+
exports.UI_DEFAULTS = UI_DEFAULTS;
|
|
364
|
+
exports.en = en;
|
|
347
365
|
exports.getTrad = getTrad;
|
|
348
366
|
exports.index = index;
|