strapi-plugin-oidc 1.0.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.
@@ -0,0 +1,489 @@
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { Routes, Route } from "react-router-dom";
3
+ import { useFetchClient, Page, Layouts } from "@strapi/strapi/admin";
4
+ import { useState, useCallback, memo, useEffect } from "react";
5
+ import { Typography, Flex, Box, MultiSelect, MultiSelectOption, Field, Button, Divider, Thead, Tr, Th, Tbody, Td, Dialog, IconButton, Pagination, PreviousLink, PageLink, NextLink, Table, Alert } from "@strapi/design-system";
6
+ import { Plus, Trash, WarningCircle } from "@strapi/icons";
7
+ import { useIntl } from "react-intl";
8
+ import { p as pluginId } from "./index-BuuCScSN.mjs";
9
+ import en from "./en-f0TxVfx7.mjs";
10
+ import styled from "styled-components";
11
+ function getTrad(id) {
12
+ const pluginIdWithId = `${pluginId}.${id}`;
13
+ return {
14
+ id: pluginIdWithId,
15
+ defaultMessage: en[id] || pluginIdWithId
16
+ };
17
+ }
18
+ function Role({ oidcRoles, roles, onChangeRole }) {
19
+ const { formatMessage } = useIntl();
20
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
21
+ /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textColor: "neutral600", marginBottom: 4, children: formatMessage(getTrad("roles.notes")) }),
22
+ /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 4, marginBottom: 4, children: oidcRoles.map((oidcRole) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
23
+ MultiSelect,
24
+ {
25
+ withTags: true,
26
+ placeholder: formatMessage(getTrad("roles.placeholder")),
27
+ value: oidcRole["role"] ? oidcRole["role"].map((r) => r.toString()) : [],
28
+ onChange: (value) => {
29
+ if (value && value.length > 0) {
30
+ onChangeRole(value, oidcRole["oauth_type"]);
31
+ }
32
+ },
33
+ children: roles.map((role) => /* @__PURE__ */ jsx(MultiSelectOption, { value: role.id.toString(), children: role.name }, role.id))
34
+ }
35
+ ) }, oidcRole["oauth_type"])) })
36
+ ] });
37
+ }
38
+ const CustomTable = styled(Table)`
39
+ th, td, th span, td span {
40
+ font-size: 1.3rem !important;
41
+ }
42
+ `;
43
+ const LocalizedDate = ({ date }) => {
44
+ const userLocale = navigator.language || "en-US";
45
+ return new Intl.DateTimeFormat(userLocale, {
46
+ year: "numeric",
47
+ month: "long",
48
+ day: "numeric",
49
+ hour: "2-digit",
50
+ minute: "2-digit"
51
+ }).format(new Date(date));
52
+ };
53
+ function Whitelist({ users, roles, oidcRoles = [], useWhitelist, loading, onSave, onDelete }) {
54
+ const [email, setEmail] = useState("");
55
+ const [selectedRoles, setSelectedRoles] = useState([]);
56
+ const [page, setPage] = useState(1);
57
+ const { formatMessage } = useIntl();
58
+ const PAGE_SIZE = 10;
59
+ const pageCount = Math.ceil(users.length / PAGE_SIZE) || 1;
60
+ const paginatedUsers = users.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);
61
+ const onSaveEmail = useCallback(async () => {
62
+ const emailText = email.trim();
63
+ if (users.some((user) => user.email === emailText)) {
64
+ alert(
65
+ formatMessage(getTrad("whitelist.error.unique"))
66
+ );
67
+ } else {
68
+ await onSave(emailText, selectedRoles);
69
+ setEmail("");
70
+ setSelectedRoles([]);
71
+ }
72
+ }, [email, selectedRoles, users, onSave, formatMessage]);
73
+ const isValidEmail = useCallback(() => {
74
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
75
+ return emailRegex.test(email);
76
+ }, [email]);
77
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Box, { children: [
78
+ /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textColor: "neutral600", marginBottom: 4, children: formatMessage(getTrad("whitelist.description")) }),
79
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, marginTop: 5, marginBottom: 5, alignItems: "flex-start", children: [
80
+ /* @__PURE__ */ jsx(Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsx(
81
+ Field.Input,
82
+ {
83
+ type: "text",
84
+ disabled: loading,
85
+ value: email,
86
+ hasError: Boolean(email && !isValidEmail()),
87
+ onChange: (e) => setEmail(e.currentTarget.value),
88
+ placeholder: formatMessage(getTrad("whitelist.email.placeholder"))
89
+ }
90
+ ) }) }),
91
+ /* @__PURE__ */ jsx(Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsx(
92
+ MultiSelect,
93
+ {
94
+ withTags: true,
95
+ placeholder: formatMessage(getTrad("whitelist.roles.placeholder")),
96
+ value: selectedRoles,
97
+ onChange: (value) => {
98
+ setSelectedRoles(value || []);
99
+ },
100
+ children: roles.map((role) => /* @__PURE__ */ jsx(MultiSelectOption, { value: role.id.toString(), children: role.name }, role.id))
101
+ }
102
+ ) }) }),
103
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
104
+ Button,
105
+ {
106
+ size: "L",
107
+ startIcon: /* @__PURE__ */ jsx(Plus, {}),
108
+ disabled: loading || email.trim() === "" || !isValidEmail(),
109
+ loading,
110
+ onClick: onSaveEmail,
111
+ children: formatMessage(getTrad("page.add"))
112
+ }
113
+ ) })
114
+ ] }),
115
+ /* @__PURE__ */ jsx(Divider, {}),
116
+ /* @__PURE__ */ jsxs(CustomTable, { colCount: 5, rowCount: users.length, children: [
117
+ /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
118
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("whitelist.table.no")) }),
119
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("whitelist.table.email")) }),
120
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("whitelist.table.roles")) }),
121
+ /* @__PURE__ */ jsx(Th, { children: formatMessage(getTrad("whitelist.table.created")) }),
122
+ /* @__PURE__ */ jsx(Th, { style: { paddingRight: 0 }, children: " " })
123
+ ] }) }),
124
+ /* @__PURE__ */ jsx(Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 5, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage(getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index) => {
125
+ let userRolesNames = (user.roles || []).map((roleId) => {
126
+ const r = roles.find((ro) => ro.id.toString() === roleId.toString());
127
+ return r ? r.name : roleId;
128
+ }).join(", ");
129
+ if (!userRolesNames) {
130
+ const defaultRolesIds = oidcRoles.reduce((acc, oidc) => {
131
+ if (oidc.role) {
132
+ acc.push(...oidc.role);
133
+ }
134
+ return acc;
135
+ }, []);
136
+ userRolesNames = defaultRolesIds.map((roleId) => {
137
+ const r = roles.find((ro) => ro.id.toString() === roleId.toString());
138
+ return r ? r.name : roleId;
139
+ }).join(", ");
140
+ }
141
+ return /* @__PURE__ */ jsxs(Tr, { children: [
142
+ /* @__PURE__ */ jsx(Td, { children: index + 1 + (page - 1) * PAGE_SIZE }),
143
+ /* @__PURE__ */ jsx(Td, { children: user.email }),
144
+ /* @__PURE__ */ jsx(Td, { children: userRolesNames || "-" }),
145
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(LocalizedDate, { date: user.createdAt }) }),
146
+ /* @__PURE__ */ jsx(Td, { style: { paddingRight: 0 }, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", onClick: (e) => e.stopPropagation(), style: { width: "100%" }, children: /* @__PURE__ */ jsxs(Dialog.Root, { children: [
147
+ /* @__PURE__ */ jsx(Dialog.Trigger, { children: /* @__PURE__ */ jsx(IconButton, { label: formatMessage(getTrad("whitelist.delete.label")), withTooltip: false, children: /* @__PURE__ */ jsx(Trash, {}) }) }),
148
+ /* @__PURE__ */ jsxs(Dialog.Content, { children: [
149
+ /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage(getTrad("whitelist.delete.title")) }),
150
+ /* @__PURE__ */ jsx(Dialog.Body, { icon: /* @__PURE__ */ jsx(WarningCircle, { fill: "danger600" }), children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 2, children: [
151
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { id: "confirm-description", children: formatMessage(getTrad("whitelist.delete.description")) }) }),
152
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", children: user.email }) }),
153
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "center", marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(getTrad("whitelist.delete.note")) }) })
154
+ ] }) }),
155
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
156
+ /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "tertiary", children: formatMessage(getTrad("page.cancel")) }) }),
157
+ /* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "danger-light", onClick: () => onDelete(user.email), children: formatMessage(getTrad("page.ok")) }) })
158
+ ] })
159
+ ] })
160
+ ] }) }) })
161
+ ] }, user.email);
162
+ }) })
163
+ ] }),
164
+ pageCount > 1 && /* @__PURE__ */ jsx(Box, { paddingTop: 4, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(Pagination, { activePage: page, pageCount, children: [
165
+ /* @__PURE__ */ jsx(PreviousLink, { href: "#", onClick: (e) => {
166
+ e.preventDefault();
167
+ setPage((p) => Math.max(1, p - 1));
168
+ }, children: "Go to previous page" }),
169
+ Array.from({ length: pageCount }).map((_, i) => /* @__PURE__ */ jsxs(PageLink, { number: i + 1, href: "#", onClick: (e) => {
170
+ e.preventDefault();
171
+ setPage(i + 1);
172
+ }, children: [
173
+ "Go to page ",
174
+ i + 1
175
+ ] }, i + 1)),
176
+ /* @__PURE__ */ jsx(NextLink, { href: "#", onClick: (e) => {
177
+ e.preventDefault();
178
+ setPage((p) => Math.min(pageCount, p + 1));
179
+ }, children: "Go to next page" })
180
+ ] }) }) })
181
+ ] }) });
182
+ }
183
+ const AlertMessage = styled.div`
184
+ position: fixed;
185
+ left: 50%;
186
+ transform: translateX(-50%);
187
+ top: 2.875rem;
188
+ z-index: 10;
189
+ width: 31.25rem;
190
+ `;
191
+ function SuccessAlertMessage({ onClose }) {
192
+ const { formatMessage } = useIntl();
193
+ return /* @__PURE__ */ jsx(AlertMessage, { children: /* @__PURE__ */ jsx(
194
+ Alert,
195
+ {
196
+ title: "Success",
197
+ variant: "success",
198
+ closeLabel: "",
199
+ onClose,
200
+ children: formatMessage(getTrad("page.save.success"))
201
+ }
202
+ ) });
203
+ }
204
+ function ErrorAlertMessage({ onClose }) {
205
+ const { formatMessage } = useIntl();
206
+ return /* @__PURE__ */ jsx(AlertMessage, { children: /* @__PURE__ */ jsx(
207
+ Alert,
208
+ {
209
+ title: "Error",
210
+ variant: "danger",
211
+ closeLabel: "",
212
+ onClose,
213
+ children: formatMessage(getTrad("page.save.error"))
214
+ }
215
+ ) });
216
+ }
217
+ function MatchedUserAlertMessage({ onClose, count }) {
218
+ const { formatMessage } = useIntl();
219
+ const id = count > 1 ? "tab.whitelist.users_exists" : "tab.whitelist.user_exists";
220
+ return /* @__PURE__ */ jsx(AlertMessage, { children: /* @__PURE__ */ jsx(
221
+ Alert,
222
+ {
223
+ title: "Info",
224
+ variant: "default",
225
+ closeLabel: "",
226
+ onClose,
227
+ children: formatMessage(getTrad(id))
228
+ }
229
+ ) });
230
+ }
231
+ const SwitchContainer = styled.label`
232
+ position: relative;
233
+ display: inline-block;
234
+ width: 40px;
235
+ height: 24px;
236
+ cursor: ${({ $disabled }) => $disabled ? "not-allowed" : "pointer"};
237
+ opacity: ${({ $disabled }) => $disabled ? 0.5 : 1};
238
+ `;
239
+ const SwitchInput = styled.input`
240
+ opacity: 0;
241
+ width: 0;
242
+ height: 0;
243
+
244
+ &:checked + span {
245
+ background-color: ${({ theme }) => theme.colors.primary600};
246
+ }
247
+
248
+ &:focus + span {
249
+ box-shadow: 0 0 1px ${({ theme }) => theme.colors.primary600};
250
+ }
251
+
252
+ &:checked + span:before {
253
+ transform: translateX(16px);
254
+ }
255
+
256
+ &:disabled + span {
257
+ pointer-events: none;
258
+ }
259
+ `;
260
+ const SwitchSlider = styled.span`
261
+ position: absolute;
262
+ cursor: inherit;
263
+ top: 0;
264
+ left: 0;
265
+ right: 0;
266
+ bottom: 0;
267
+ background-color: ${({ theme }) => theme.colors.neutral300};
268
+ transition: 0.4s;
269
+ border-radius: 24px;
270
+
271
+ &:before {
272
+ position: absolute;
273
+ content: "";
274
+ height: 18px;
275
+ width: 18px;
276
+ left: 3px;
277
+ bottom: 3px;
278
+ background-color: white;
279
+ transition: 0.4s;
280
+ border-radius: 50%;
281
+ }
282
+ `;
283
+ function CustomSwitch({ checked, onChange, label, disabled }) {
284
+ return /* @__PURE__ */ jsxs(Flex, { gap: 3, children: [
285
+ /* @__PURE__ */ jsxs(SwitchContainer, { $disabled: disabled, children: [
286
+ /* @__PURE__ */ jsx(
287
+ SwitchInput,
288
+ {
289
+ type: "checkbox",
290
+ checked,
291
+ onChange,
292
+ disabled
293
+ }
294
+ ),
295
+ /* @__PURE__ */ jsx(SwitchSlider, {})
296
+ ] }),
297
+ label && /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: disabled ? "neutral500" : "neutral800", children: label })
298
+ ] });
299
+ }
300
+ function HomePage() {
301
+ const { formatMessage } = useIntl();
302
+ const [loading, setLoading] = useState(false);
303
+ const [initialOidcRoles, setInitialOIDCRoles] = useState([]);
304
+ const [oidcRoles, setOIDCRoles] = useState([]);
305
+ const [roles, setRoles] = useState([]);
306
+ const [initialUseWhitelist, setInitialUseWhitelist] = useState(false);
307
+ const [useWhitelist, setUseWhitelist] = useState(false);
308
+ const [initialEnforceOIDC, setInitialEnforceOIDC] = useState(false);
309
+ const [enforceOIDC, setEnforceOIDC] = useState(false);
310
+ const [initialUsers, setInitialUsers] = useState([]);
311
+ const [users, setUsers] = useState([]);
312
+ const [showSuccess, setSuccess] = useState(false);
313
+ const [showError, setError] = useState(false);
314
+ const [showMatched, setMatched] = useState(0);
315
+ const { get, put, post, del } = useFetchClient();
316
+ useEffect(() => {
317
+ get(`/strapi-plugin-oidc/oidc-roles`).then((response) => {
318
+ setOIDCRoles(response.data);
319
+ setInitialOIDCRoles(JSON.parse(JSON.stringify(response.data)));
320
+ });
321
+ get(`/admin/roles`).then((response) => {
322
+ setRoles(response.data.data);
323
+ });
324
+ get("/strapi-plugin-oidc/whitelist").then((response) => {
325
+ setUsers(response.data.whitelistUsers);
326
+ setInitialUsers(JSON.parse(JSON.stringify(response.data.whitelistUsers)));
327
+ setUseWhitelist(response.data.useWhitelist);
328
+ setInitialUseWhitelist(response.data.useWhitelist);
329
+ setEnforceOIDC(response.data.enforceOIDC);
330
+ setInitialEnforceOIDC(response.data.enforceOIDC);
331
+ });
332
+ }, [setOIDCRoles, setRoles]);
333
+ const onChangeRole = (values, oidcId) => {
334
+ for (const oidcRole of oidcRoles) {
335
+ if (oidcRole["oauth_type"] === oidcId) {
336
+ oidcRole["role"] = values;
337
+ }
338
+ }
339
+ setOIDCRoles(oidcRoles.slice());
340
+ };
341
+ const onSaveAll = async () => {
342
+ setLoading(true);
343
+ try {
344
+ await put("/strapi-plugin-oidc/oidc-roles", {
345
+ roles: oidcRoles.map((role) => ({
346
+ "oauth_type": role["oauth_type"],
347
+ role: role["role"]
348
+ }))
349
+ });
350
+ await put("/strapi-plugin-oidc/whitelist/settings", {
351
+ useWhitelist,
352
+ enforceOIDC
353
+ });
354
+ const syncResponse = await put("/strapi-plugin-oidc/whitelist/sync", {
355
+ users: users.map((u) => ({ email: u.email, roles: u.roles }))
356
+ });
357
+ setInitialOIDCRoles(JSON.parse(JSON.stringify(oidcRoles)));
358
+ setInitialUseWhitelist(useWhitelist);
359
+ setInitialEnforceOIDC(enforceOIDC);
360
+ get("/strapi-plugin-oidc/whitelist").then((getResponse) => {
361
+ setUsers(getResponse.data.whitelistUsers);
362
+ setInitialUsers(JSON.parse(JSON.stringify(getResponse.data.whitelistUsers)));
363
+ });
364
+ if (syncResponse.data && syncResponse.data.matchedExistingUsersCount > 0) {
365
+ setMatched(syncResponse.data.matchedExistingUsersCount);
366
+ setTimeout(() => {
367
+ setMatched(0);
368
+ }, 3e3);
369
+ } else {
370
+ setSuccess(true);
371
+ setTimeout(() => {
372
+ setSuccess(false);
373
+ }, 3e3);
374
+ }
375
+ } catch (e) {
376
+ console.error(e);
377
+ setError(true);
378
+ setTimeout(() => {
379
+ setError(false);
380
+ }, 3e3);
381
+ } finally {
382
+ setLoading(false);
383
+ }
384
+ };
385
+ const onRegisterWhitelist = async (email, selectedRoles) => {
386
+ const newUser = { email, roles: selectedRoles, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
387
+ setUsers([...users, newUser]);
388
+ };
389
+ const onDeleteWhitelist = async (email) => {
390
+ setUsers(users.filter((u) => u.email !== email));
391
+ };
392
+ const onToggleWhitelist = (e) => {
393
+ const newValue = e.target.checked;
394
+ setUseWhitelist(newValue);
395
+ };
396
+ const onToggleEnforce = (e) => {
397
+ const newValue = e.target.checked;
398
+ setEnforceOIDC(newValue);
399
+ };
400
+ const isDirty = useWhitelist !== initialUseWhitelist || enforceOIDC !== initialEnforceOIDC || JSON.stringify(oidcRoles) !== JSON.stringify(initialOidcRoles) || JSON.stringify(users) !== JSON.stringify(initialUsers);
401
+ return /* @__PURE__ */ jsxs(Page.Protect, { permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }], children: [
402
+ /* @__PURE__ */ jsx(
403
+ Layouts.Header,
404
+ {
405
+ title: formatMessage(getTrad("page.title.oidc")),
406
+ subtitle: formatMessage(getTrad("page.title"))
407
+ }
408
+ ),
409
+ showSuccess && /* @__PURE__ */ jsx(SuccessAlertMessage, { onClose: () => setSuccess(false) }),
410
+ showError && /* @__PURE__ */ jsx(ErrorAlertMessage, { onClose: () => setError(false) }),
411
+ showMatched > 0 && /* @__PURE__ */ jsx(MatchedUserAlertMessage, { count: showMatched, onClose: () => setMatched(0) }),
412
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
413
+ /* @__PURE__ */ jsxs(Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: [
414
+ /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: formatMessage(getTrad("roles.title")) }) }),
415
+ /* @__PURE__ */ jsx(
416
+ Role,
417
+ {
418
+ roles,
419
+ oidcRoles,
420
+ onChangeRole
421
+ }
422
+ )
423
+ ] }),
424
+ /* @__PURE__ */ jsxs(Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: [
425
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", paddingBottom: 4, children: [
426
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: formatMessage(getTrad("whitelist.title")) }),
427
+ /* @__PURE__ */ jsx(
428
+ CustomSwitch,
429
+ {
430
+ checked: useWhitelist,
431
+ onChange: onToggleWhitelist,
432
+ label: useWhitelist ? formatMessage(getTrad("whitelist.toggle.enabled")) : formatMessage(getTrad("whitelist.toggle.disabled"))
433
+ }
434
+ )
435
+ ] }),
436
+ /* @__PURE__ */ jsx(
437
+ Whitelist,
438
+ {
439
+ loading,
440
+ users,
441
+ roles,
442
+ oidcRoles,
443
+ useWhitelist,
444
+ onSave: onRegisterWhitelist,
445
+ onDelete: onDeleteWhitelist
446
+ }
447
+ )
448
+ ] }),
449
+ /* @__PURE__ */ jsx(Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
450
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
451
+ /* @__PURE__ */ jsx(Typography, { variant: "epsilon", tag: "h4", children: formatMessage(getTrad("enforce.title")) }),
452
+ /* @__PURE__ */ jsx(
453
+ CustomSwitch,
454
+ {
455
+ checked: enforceOIDC,
456
+ onChange: onToggleEnforce,
457
+ disabled: useWhitelist && users.length === 0,
458
+ label: enforceOIDC ? formatMessage(getTrad("enforce.toggle.enabled")) : formatMessage(getTrad("enforce.toggle.disabled"))
459
+ }
460
+ )
461
+ ] }),
462
+ enforceOIDC && enforceOIDC !== initialEnforceOIDC && /* @__PURE__ */ jsx(Box, { background: "danger100", padding: 3, hasRadius: true, children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", children: [
463
+ /* @__PURE__ */ jsx(WarningCircle, { fill: "danger600" }),
464
+ /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: formatMessage(getTrad("enforce.warning")) })
465
+ ] }) })
466
+ ] }) }),
467
+ /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(
468
+ Button,
469
+ {
470
+ size: "L",
471
+ onClick: onSaveAll,
472
+ disabled: !isDirty || loading,
473
+ loading,
474
+ children: formatMessage(getTrad("page.save"))
475
+ }
476
+ ) })
477
+ ] }) })
478
+ ] });
479
+ }
480
+ const HomePage$1 = memo(HomePage);
481
+ function App() {
482
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Routes, { children: [
483
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(HomePage$1, {}) }),
484
+ /* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Page.Error, {}) })
485
+ ] }) });
486
+ }
487
+ export {
488
+ App as default
489
+ };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const index = require("./index-C0GkDnGG.js");
4
+ exports.default = index.index;
@@ -0,0 +1,4 @@
1
+ import { i } from "./index-BuuCScSN.mjs";
2
+ export {
3
+ i as default
4
+ };