strapi-plugin-oidc 1.8.5 → 1.9.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.
@@ -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-C8nfr95D.js");
10
+ const index = require("./index-C5fI9GEC.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: ${({ $selected, $inRange, $pending, $future, $alreadySelected, theme }) => $pending ? theme.colors.warning600 : $selected ? theme.colors.neutral0 : $inRange ? theme.colors.primary600 : theme.colors.neutral800};
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$1 = /^[^\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$1.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$1.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$1.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"))
@@ -1081,7 +1087,6 @@ const AUDIT_ACTIONS = [
1081
1087
  "user_created"
1082
1088
  ];
1083
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}|::))$/;
1084
- const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1085
1090
  function FilterBar({
1086
1091
  filters,
1087
1092
  hasActiveFilters,
@@ -1114,7 +1119,7 @@ function FilterBar({
1114
1119
  onChange: (selections) => {
1115
1120
  onFiltersChange((prev) => {
1116
1121
  if (selections.length === 0) {
1117
- const { createdAt, ...rest } = prev;
1122
+ const { createdAt: _createdAt, ...rest } = prev;
1118
1123
  return rest;
1119
1124
  }
1120
1125
  return { ...prev, createdAt: selections };
@@ -1141,7 +1146,7 @@ function FilterBar({
1141
1146
  onChange: (value) => onFiltersChange((prev) => ({ ...prev, email: value })),
1142
1147
  placeholder: formatMessage(index.getTrad("auditlog.filters.email")),
1143
1148
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.Mail, { width: "1.4rem", height: "1.4rem" }) }),
1144
- validate: (v) => EMAIL_REGEX.test(v)
1149
+ validate: (v) => index.EMAIL_REGEX.test(v)
1145
1150
  }
1146
1151
  ),
1147
1152
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1181,25 +1186,36 @@ function LogTable({ records, loading, hasActiveFilters }) {
1181
1186
  ] }) }),
1182
1187
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tbody, { children: [
1183
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")) }) }) }) }),
1184
- records.map((record) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { style: { opacity: loading ? 0.4 : 1, transition: "opacity 0.15s" }, children: [
1185
- /* @__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" } }) }) }),
1186
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
1187
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.action }),
1188
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: formatMessage(index.getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsxRuntime.jsx(
1189
- icons.Information,
1190
- {
1191
- "aria-hidden": true,
1192
- style: { cursor: "help" },
1193
- width: "1.4rem",
1194
- height: "1.4rem",
1195
- fill: "primary600"
1196
- }
1197
- ) })
1198
- ] }) }),
1199
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.email ?? "—" }) }),
1200
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: record.ip ?? "—" }) }),
1201
- /* @__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: "—" }) })
1202
- ] }, record.id))
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
+ })
1203
1219
  ] })
1204
1220
  ] }),
1205
1221
  loading && records.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
@@ -3773,8 +3789,7 @@ function buildQueryString(params) {
3773
3789
  { encodeValuesOnly: true }
3774
3790
  );
3775
3791
  }
3776
- const PAGE_SIZE = 10;
3777
- const MIN_SPINNER_MS = 400;
3792
+ const PAGE_SIZE = index.AUDIT_LOG_DEFAULTS.ADMIN_PAGE_SIZE;
3778
3793
  function useDebounced(value, delay = 300) {
3779
3794
  const [debounced, setDebounced] = React.useState(value);
3780
3795
  React.useEffect(() => {
@@ -3814,7 +3829,7 @@ function useAuditLogs(page, filters) {
3814
3829
  };
3815
3830
  } catch {
3816
3831
  }
3817
- const remaining = MIN_SPINNER_MS - (Date.now() - startTime);
3832
+ const remaining = index.UI_DEFAULTS.MIN_SPINNER_MS - (Date.now() - startTime);
3818
3833
  if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
3819
3834
  if (gen !== fetchGenRef.current) return;
3820
3835
  setRecords(newRecords);
@@ -4003,7 +4018,7 @@ const SwitchInput = styled__default.default.input`
4003
4018
  &:checked + span:before {
4004
4019
  transform: translateX(16px);
4005
4020
  }
4006
-
4021
+
4007
4022
  &:disabled + span {
4008
4023
  pointer-events: none;
4009
4024
  }
@@ -4021,7 +4036,7 @@ const SwitchSlider = styled__default.default.span`
4021
4036
 
4022
4037
  &:before {
4023
4038
  position: absolute;
4024
- content: "";
4039
+ content: '';
4025
4040
  height: 18px;
4026
4041
  width: 18px;
4027
4042
  left: 3px;
@@ -4031,21 +4046,26 @@ const SwitchSlider = styled__default.default.span`
4031
4046
  border-radius: 50%;
4032
4047
  }
4033
4048
  `;
4034
- function CustomSwitch({ checked, onChange, label, disabled }) {
4049
+ function CustomSwitch({
4050
+ checked,
4051
+ onChange,
4052
+ label,
4053
+ disabled
4054
+ }) {
4035
4055
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, children: [
4036
4056
  /* @__PURE__ */ jsxRuntime.jsxs(SwitchContainer, { $disabled: disabled, children: [
4037
- /* @__PURE__ */ jsxRuntime.jsx(
4038
- SwitchInput,
4039
- {
4040
- type: "checkbox",
4041
- checked,
4042
- onChange,
4043
- disabled
4044
- }
4045
- ),
4057
+ /* @__PURE__ */ jsxRuntime.jsx(SwitchInput, { type: "checkbox", checked, onChange, disabled }),
4046
4058
  /* @__PURE__ */ jsxRuntime.jsx(SwitchSlider, {})
4047
4059
  ] }),
4048
- label && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: disabled ? "neutral500" : "neutral800", children: label })
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
+ )
4049
4069
  ] });
4050
4070
  }
4051
4071
  function formatDatetimeForFilename(date) {
@@ -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,30 @@ 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 link = {
210
+ id: "configuration",
211
+ to: `/settings/${pluginId}`,
212
+ intlLabel: {
213
+ id: "settings.configuration",
214
+ defaultMessage: "Configuration"
215
+ },
216
+ Component: () => Promise.resolve().then(() => require("./index-BJjdJ_L0.js")),
217
+ permissions: [{ action: PERMISSIONS.READ, subject: null }]
218
+ };
195
219
  app.addSettingsLink(
196
220
  {
197
221
  id: "oidc",
@@ -200,18 +224,7 @@ const index = {
200
224
  defaultMessage: "OIDC"
201
225
  }
202
226
  },
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-DDCcJt16.js"));
212
- },
213
- permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
214
- }
227
+ link
215
228
  );
216
229
  app.registerPlugin({
217
230
  id: pluginId,
@@ -344,5 +357,9 @@ const index = {
344
357
  return importedTrads;
345
358
  }
346
359
  };
360
+ exports.AUDIT_LOG_DEFAULTS = AUDIT_LOG_DEFAULTS;
361
+ exports.EMAIL_REGEX = EMAIL_REGEX;
362
+ exports.UI_DEFAULTS = UI_DEFAULTS;
363
+ exports.en = en;
347
364
  exports.getTrad = getTrad;
348
365
  exports.index = index;
@@ -174,7 +174,10 @@ const en = {
174
174
  "user.invalid_state": "State parameter mismatch. Please restart the login flow.",
175
175
  "user.signInError": "Authentication failed. Please try again.",
176
176
  "settings.section": "OIDC",
177
- "settings.configuration": "Configuration"
177
+ "settings.configuration": "Configuration",
178
+ "audit.login_failure": "Error: {message}",
179
+ "audit.roles_updated": "Roles updated to: {roles}",
180
+ "audit.user_created": "Roles assigned: {roles}"
178
181
  };
179
182
  function getTrad(id) {
180
183
  const pluginIdWithId = `${pluginId}.${id}`;
@@ -186,9 +189,30 @@ function getTrad(id) {
186
189
  function t(id) {
187
190
  return en[id];
188
191
  }
192
+ const PLUGIN_UID = "plugin::strapi-plugin-oidc";
193
+ const PERMISSIONS = {
194
+ READ: `${PLUGIN_UID}.read`
195
+ };
196
+ const AUDIT_LOG_DEFAULTS = {
197
+ ADMIN_PAGE_SIZE: 10
198
+ };
199
+ const UI_DEFAULTS = {
200
+ MIN_SPINNER_MS: 400
201
+ };
202
+ const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
189
203
  const name = pluginPkg.strapi.displayName;
190
204
  const index = {
191
205
  register(app) {
206
+ const link = {
207
+ id: "configuration",
208
+ to: `/settings/${pluginId}`,
209
+ intlLabel: {
210
+ id: "settings.configuration",
211
+ defaultMessage: "Configuration"
212
+ },
213
+ Component: () => import("./index-YcZbHa90.mjs"),
214
+ permissions: [{ action: PERMISSIONS.READ, subject: null }]
215
+ };
192
216
  app.addSettingsLink(
193
217
  {
194
218
  id: "oidc",
@@ -197,18 +221,7 @@ const index = {
197
221
  defaultMessage: "OIDC"
198
222
  }
199
223
  },
200
- {
201
- id: "configuration",
202
- to: `/settings/${pluginId}`,
203
- intlLabel: {
204
- id: "settings.configuration",
205
- defaultMessage: "Configuration"
206
- },
207
- Component: async () => {
208
- return await import("./index-DRFXk_MQ.mjs");
209
- },
210
- permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
211
- }
224
+ link
212
225
  );
213
226
  app.registerPlugin({
214
227
  id: pluginId,
@@ -342,6 +355,10 @@ const index = {
342
355
  }
343
356
  };
344
357
  export {
358
+ AUDIT_LOG_DEFAULTS as A,
359
+ EMAIL_REGEX as E,
360
+ UI_DEFAULTS as U,
361
+ en as e,
345
362
  getTrad as g,
346
363
  index as i
347
364
  };
@@ -5,7 +5,7 @@ import { useState, useRef, useId, useEffect, useCallback, useReducer, useMemo, m
5
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-BlfNZYVU.mjs";
8
+ import { g as getTrad, E as EMAIL_REGEX, e as en, A as AUDIT_LOG_DEFAULTS, U as UI_DEFAULTS } from "./index-D0ORg9LL.mjs";
9
9
  import styled from "styled-components";
10
10
  import { Filter, ClipboardList, Server } from "lucide-react";
11
11
  function Role({ oidcRoles, roles, onChangeRole }) {
@@ -422,7 +422,14 @@ const DayButton = styled.button`
422
422
  aspect-ratio: 1;
423
423
  border: none;
424
424
  background: ${({ $selected, $inRange, $pending, theme }) => $pending ? theme.colors.warning200 : $selected ? theme.colors.primary600 : $inRange ? theme.colors.primary100 : "transparent"};
425
- color: ${({ $selected, $inRange, $pending, $future, $alreadySelected, theme }) => $pending ? theme.colors.warning600 : $selected ? theme.colors.neutral0 : $inRange ? theme.colors.primary600 : theme.colors.neutral800};
425
+ color: ${({
426
+ $selected,
427
+ $inRange,
428
+ $pending,
429
+ $future: _future,
430
+ $alreadySelected: _alreadySelected,
431
+ theme
432
+ }) => $pending ? theme.colors.warning600 : $selected ? theme.colors.neutral0 : $inRange ? theme.colors.primary600 : theme.colors.neutral800};
426
433
  opacity: ${({ $future, $alreadySelected }) => $future || $alreadySelected ? 0.4 : 1};
427
434
  border-radius: 4px;
428
435
  cursor: pointer;
@@ -848,7 +855,6 @@ function TablePagination({ page, pageCount, onPageChange, total }) {
848
855
  ] }) });
849
856
  }
850
857
  const PAGE_SIZE$1 = 10;
851
- const EMAIL_REGEX$1 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
852
858
  function Whitelist({
853
859
  users,
854
860
  useWhitelist,
@@ -889,7 +895,7 @@ function Whitelist({
889
895
  if (!Array.isArray(parsed)) throw new Error();
890
896
  const emails = parsed.filter((item) => item?.email).map(
891
897
  (item) => String(item.email).trim().toLowerCase()
892
- ).filter((email2) => EMAIL_REGEX$1.test(email2));
898
+ ).filter((email2) => EMAIL_REGEX.test(email2));
893
899
  const count = await onImport(emails);
894
900
  if (count === 0) {
895
901
  toggleNotification({
@@ -931,7 +937,7 @@ function Whitelist({
931
937
  type: "text",
932
938
  disabled: loading,
933
939
  value: email,
934
- hasError: Boolean(email && !EMAIL_REGEX$1.test(email)),
940
+ hasError: Boolean(email && !EMAIL_REGEX.test(email)),
935
941
  onChange: (e) => setEmail(e.currentTarget.value),
936
942
  placeholder: formatMessage(getTrad("whitelist.email.placeholder")),
937
943
  style: { fontSize: "1.4rem", lineHeight: "2.2rem" }
@@ -942,7 +948,7 @@ function Whitelist({
942
948
  {
943
949
  size: "S",
944
950
  startIcon: /* @__PURE__ */ jsx(Plus, {}),
945
- disabled: loading || email.trim() === "" || !EMAIL_REGEX$1.test(email),
951
+ disabled: loading || email.trim() === "" || !EMAIL_REGEX.test(email),
946
952
  loading,
947
953
  onClick: onSaveEmail,
948
954
  children: formatMessage(getTrad("page.add"))
@@ -1077,7 +1083,6 @@ const AUDIT_ACTIONS = [
1077
1083
  "user_created"
1078
1084
  ];
1079
1085
  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}|::))$/;
1080
- const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1081
1086
  function FilterBar({
1082
1087
  filters,
1083
1088
  hasActiveFilters,
@@ -1110,7 +1115,7 @@ function FilterBar({
1110
1115
  onChange: (selections) => {
1111
1116
  onFiltersChange((prev) => {
1112
1117
  if (selections.length === 0) {
1113
- const { createdAt, ...rest } = prev;
1118
+ const { createdAt: _createdAt, ...rest } = prev;
1114
1119
  return rest;
1115
1120
  }
1116
1121
  return { ...prev, createdAt: selections };
@@ -1177,25 +1182,36 @@ function LogTable({ records, loading, hasActiveFilters }) {
1177
1182
  ] }) }),
1178
1183
  /* @__PURE__ */ jsxs(Tbody, { children: [
1179
1184
  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")) }) }) }) }),
1180
- records.map((record) => /* @__PURE__ */ jsxs(Tr, { style: { opacity: loading ? 0.4 : 1, transition: "opacity 0.15s" }, children: [
1181
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: /* @__PURE__ */ jsx(LocalizedDate, { date: record.createdAt, options: { second: "2-digit" } }) }) }),
1182
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
1183
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.action }),
1184
- /* @__PURE__ */ jsx(Tooltip, { label: formatMessage(getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsx(
1185
- Information,
1186
- {
1187
- "aria-hidden": true,
1188
- style: { cursor: "help" },
1189
- width: "1.4rem",
1190
- height: "1.4rem",
1191
- fill: "primary600"
1192
- }
1193
- ) })
1194
- ] }) }),
1195
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.email ?? "—" }) }),
1196
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.ip ?? "—" }) }),
1197
- /* @__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: "—" }) })
1198
- ] }, record.id))
1185
+ records.map((record) => {
1186
+ const detailKey = record.detailsKey ? `audit.${record.detailsKey}` : null;
1187
+ const detail = detailKey && en[detailKey] ? formatMessage(getTrad(detailKey), record.detailsParams ?? {}) : null;
1188
+ return /* @__PURE__ */ jsxs(
1189
+ Tr,
1190
+ {
1191
+ style: { opacity: loading ? 0.4 : 1, transition: "opacity 0.15s" },
1192
+ children: [
1193
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: /* @__PURE__ */ jsx(LocalizedDate, { date: record.createdAt, options: { second: "2-digit" } }) }) }),
1194
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
1195
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.action }),
1196
+ /* @__PURE__ */ jsx(Tooltip, { label: formatMessage(getTrad(`auditlog.action.${record.action}`)), children: /* @__PURE__ */ jsx(
1197
+ Information,
1198
+ {
1199
+ "aria-hidden": true,
1200
+ style: { cursor: "help" },
1201
+ width: "1.4rem",
1202
+ height: "1.4rem",
1203
+ fill: "primary600"
1204
+ }
1205
+ ) })
1206
+ ] }) }),
1207
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.email ?? "—" }) }),
1208
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: record.ip ?? "—" }) }),
1209
+ /* @__PURE__ */ jsx(Td, { style: { maxWidth: "200px" }, children: detail ? /* @__PURE__ */ jsx(Tooltip, { label: detail, side: "top", children: /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: DETAILS_TEXT_STYLE, children: detail }) }) : /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", children: "—" }) })
1210
+ ]
1211
+ },
1212
+ record.id
1213
+ );
1214
+ })
1199
1215
  ] })
1200
1216
  ] }),
1201
1217
  loading && records.length > 0 && /* @__PURE__ */ jsx(
@@ -3769,8 +3785,7 @@ function buildQueryString(params) {
3769
3785
  { encodeValuesOnly: true }
3770
3786
  );
3771
3787
  }
3772
- const PAGE_SIZE = 10;
3773
- const MIN_SPINNER_MS = 400;
3788
+ const PAGE_SIZE = AUDIT_LOG_DEFAULTS.ADMIN_PAGE_SIZE;
3774
3789
  function useDebounced(value, delay = 300) {
3775
3790
  const [debounced, setDebounced] = useState(value);
3776
3791
  useEffect(() => {
@@ -3810,7 +3825,7 @@ function useAuditLogs(page, filters) {
3810
3825
  };
3811
3826
  } catch {
3812
3827
  }
3813
- const remaining = MIN_SPINNER_MS - (Date.now() - startTime);
3828
+ const remaining = UI_DEFAULTS.MIN_SPINNER_MS - (Date.now() - startTime);
3814
3829
  if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
3815
3830
  if (gen !== fetchGenRef.current) return;
3816
3831
  setRecords(newRecords);
@@ -3999,7 +4014,7 @@ const SwitchInput = styled.input`
3999
4014
  &:checked + span:before {
4000
4015
  transform: translateX(16px);
4001
4016
  }
4002
-
4017
+
4003
4018
  &:disabled + span {
4004
4019
  pointer-events: none;
4005
4020
  }
@@ -4017,7 +4032,7 @@ const SwitchSlider = styled.span`
4017
4032
 
4018
4033
  &:before {
4019
4034
  position: absolute;
4020
- content: "";
4035
+ content: '';
4021
4036
  height: 18px;
4022
4037
  width: 18px;
4023
4038
  left: 3px;
@@ -4027,21 +4042,26 @@ const SwitchSlider = styled.span`
4027
4042
  border-radius: 50%;
4028
4043
  }
4029
4044
  `;
4030
- function CustomSwitch({ checked, onChange, label, disabled }) {
4045
+ function CustomSwitch({
4046
+ checked,
4047
+ onChange,
4048
+ label,
4049
+ disabled
4050
+ }) {
4031
4051
  return /* @__PURE__ */ jsxs(Flex, { gap: 3, children: [
4032
4052
  /* @__PURE__ */ jsxs(SwitchContainer, { $disabled: disabled, children: [
4033
- /* @__PURE__ */ jsx(
4034
- SwitchInput,
4035
- {
4036
- type: "checkbox",
4037
- checked,
4038
- onChange,
4039
- disabled
4040
- }
4041
- ),
4053
+ /* @__PURE__ */ jsx(SwitchInput, { type: "checkbox", checked, onChange, disabled }),
4042
4054
  /* @__PURE__ */ jsx(SwitchSlider, {})
4043
4055
  ] }),
4044
- label && /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: disabled ? "neutral500" : "neutral800", children: label })
4056
+ label && /* @__PURE__ */ jsx(
4057
+ Typography,
4058
+ {
4059
+ variant: "pi",
4060
+ fontWeight: "bold",
4061
+ textColor: disabled ? "neutral500" : "neutral800",
4062
+ children: label
4063
+ }
4064
+ )
4045
4065
  ] });
4046
4066
  }
4047
4067
  function formatDatetimeForFilename(date) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const index = require("./index-C8nfr95D.js");
3
+ const index = require("./index-C5fI9GEC.js");
4
4
  require("react");
5
5
  require("react-dom/client");
6
6
  exports.default = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "./index-BlfNZYVU.mjs";
1
+ import { i } from "./index-D0ORg9LL.mjs";
2
2
  import "react";
3
3
  import "react-dom/client";
4
4
  export {