strapi-plugin-oidc 1.2.4 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,39 +37,32 @@ module.exports = ({ env }) => ({
37
37
  'strapi-plugin-oidc': {
38
38
  enabled: true,
39
39
  config: {
40
- // Set to true to store the token in local storage, false for session storage
41
- REMEMBER_ME: false,
42
- // How long the remember me session should last in days (defaults to 30 days)
43
- REMEMBER_ME_DAYS: 30,
44
-
45
- // OpenID Connect Settings
46
- OIDC_REDIRECT_URI: 'http://localhost:1337/strapi-plugin-oidc/oidc/callback', // Callback URI after successful login
40
+ // --- Required ---
47
41
  OIDC_CLIENT_ID: '[Client ID from OpenID Provider]',
48
42
  OIDC_CLIENT_SECRET: '[Client Secret from OpenID Provider]',
49
-
50
- OIDC_SCOPES: 'openid profile email', // Standard OIDC scopes
51
-
52
- // API Endpoints required for OIDC provider
43
+ OIDC_REDIRECT_URI: '[Your Strapi URL]/strapi-plugin-oidc/oidc/callback',
53
44
  OIDC_AUTHORIZATION_ENDPOINT: '[Authorization Endpoint]',
54
45
  OIDC_TOKEN_ENDPOINT: '[Token Endpoint]',
55
46
  OIDC_USER_INFO_ENDPOINT: '[User Info Endpoint]',
56
- OIDC_USER_INFO_ENDPOINT_WITH_AUTH_HEADER: false,
57
- OIDC_GRANT_TYPE: 'authorization_code',
58
47
 
59
- // Customizable user field mapping for user creation
60
- OIDC_FAMILY_NAME_FIELD: 'family_name',
61
- OIDC_GIVEN_NAME_FIELD: 'given_name',
62
-
63
- // Redirect to OIDC provider's logout page when users log out of Strapi
64
- OIDC_LOGOUT_URL: '[OIDC Provider Logout URL]',
48
+ // --- Defaults provided only set if your provider differs ---
49
+ OIDC_SCOPES: 'openid profile email',
50
+ OIDC_GRANT_TYPE: 'authorization_code',
51
+ OIDC_FAMILY_NAME_FIELD: 'family_name', // OIDC claim for the user's surname
52
+ OIDC_GIVEN_NAME_FIELD: 'given_name', // OIDC claim for the user's first name
53
+
54
+ // --- Optional ---
55
+ OIDC_USER_INFO_ENDPOINT_WITH_AUTH_HEADER: false, // true = Bearer token header, false = query param
56
+ OIDC_LOGOUT_URL: '', // OIDC provider logout URL; omit to return to Strapi login instead
57
+ OIDC_SSO_BUTTON_TEXT: 'Login via SSO', // Text on the SSO button injected into the login page
58
+ OIDC_ENFORCE: null, // null = use Admin UI setting; true/false = override it in config
59
+ REMEMBER_ME: false, // true = persist session across browser restarts, using Strapi's built-in refresh token duration
65
60
  },
66
61
  },
67
62
  // ...
68
63
  });
69
64
  ```
70
65
 
71
- Make sure to replace the placeholder values (e.g., `[Client ID from OpenID Provider]`) with the actual connection details from your chosen OIDC identity provider.
72
-
73
66
  ## How to Login
74
67
 
75
68
  Once configured, you can initiate the OIDC login flow by navigating to:
@@ -77,7 +70,7 @@ Once configured, you can initiate the OIDC login flow by navigating to:
77
70
 
78
71
  (e.g., `http://localhost:1337/strapi-plugin-oidc/oidc` for local development).
79
72
 
80
- When the **Enforce OIDC Login** option is enabled in the Admin Settings, the standard Strapi admin login page will be automatically redirected to this URL.
73
+ When the **Enforce OIDC Login** option is enabled in the Admin Settings, the standard login fields are removed from the login page and only the SSO button remains — click it to start the OIDC flow.
81
74
 
82
75
  ## Admin Settings
83
76
 
@@ -85,7 +78,9 @@ Once the plugin is installed and configured, you can manage the OIDC settings fr
85
78
 
86
79
  - **Whitelist Management**: Restrict login to specific users by adding their email addresses to the whitelist. You can also whitelist entire email domains (e.g., `*@company.com`). If the whitelist is empty, any user who successfully authenticates via your OIDC provider will be able to log in and an account will be automatically created for them.
87
80
  - **Default Role Assignment**: Select the default Strapi admin role that will be assigned to newly created users when they log in for the first time via OIDC.
88
- - **Enforce OIDC Login**: When enabled, the default Strapi email and password login form will be disabled and the standard login will be redirected to the OIDC login URL, forcing all administrators to log in using your OIDC provider. _(Note: This option is automatically disabled and grayed out if your whitelist is empty to prevent accidentally locking everyone out of the admin panel)._
81
+ - **SSO Login Button**: A "Login via SSO" button is always injected into the Strapi login page, allowing users to authenticate via OIDC. The button text is configurable via the `OIDC_SSO_BUTTON_TEXT` config option.
82
+ - **Enforce OIDC Login**: When enabled, the standard email/password fields, remember me checkbox, login button, and forgot-password link are removed from the login page, leaving only the SSO button. All direct login API calls are also blocked server-side. _(Note: This option is automatically disabled and grayed out if your whitelist is empty to prevent accidentally locking everyone out of the admin panel)._
83
+ - **`OIDC_ENFORCE` config override**: Setting `OIDC_ENFORCE: true` or `OIDC_ENFORCE: false` in your plugin config takes priority over the Admin UI toggle and locks it. Set `OIDC_ENFORCE: false` in your config to regain access if you are ever locked out, then restart Strapi.
89
84
 
90
85
  ## Credits & Changes
91
86
 
@@ -97,10 +92,10 @@ This plugin is a hard fork of the original [`strapi-plugin-sso`](https://github.
97
92
  - Redesigned the Whitelist and Role management UI (switched to native Strapi cards, added pagination, etc.).
98
93
  - Added an OIDC logout redirect URL.
99
94
  - Added an option to "Enforce OIDC login" with an admin toggle (automatically disabled if the whitelist is empty).
100
- - Added configurable "Remember Me" duration for sessions (`REMEMBER_ME_DAYS`).
95
+ - Added "Remember Me" support for OIDC sessions, using Strapi's built-in refresh token duration and idle lifespan.
101
96
  - Migrated the testing framework to Vitest and added comprehensive test coverage for controllers and services.
102
97
  - Cleaned up dead code and unused dependencies to improve maintainability.
103
98
  - Upgraded to use newer versions of Node.js.
104
99
  - Added styled success and error pages.
105
- - Added an optional "Login via SSO" button on the Strapi login page, allowing users to authenticate via OIDC without enforcing it for everyone. Button text is configurable from the admin settings.
100
+ - Always injects a "Login via SSO" button on the Strapi login page. Button text is configurable via `OIDC_SSO_BUTTON_TEXT`. When enforcement is on, standard login fields are hidden so only the SSO button is visible.
106
101
  - Added misc. quality of life improvements and bug fixes.
@@ -7,26 +7,19 @@ 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-Cxj6lwW7.js");
10
+ const index = require("./index-Cse9ex24.js");
11
11
  const styled = require("styled-components");
12
12
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
13
13
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
14
- function getTrad(id) {
15
- const pluginIdWithId = `${index.pluginId}.${id}`;
16
- return {
17
- id: pluginIdWithId,
18
- defaultMessage: index.en[id] || pluginIdWithId
19
- };
20
- }
21
14
  function Role({ oidcRoles, roles, onChangeRole }) {
22
15
  const { formatMessage } = reactIntl.useIntl();
23
16
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
24
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textColor: "neutral600", marginBottom: 4, children: formatMessage(getTrad("roles.notes")) }),
17
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textColor: "neutral600", marginBottom: 4, children: formatMessage(index.getTrad("roles.notes")) }),
25
18
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, marginBottom: 4, children: oidcRoles.map((oidcRole) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
26
19
  designSystem.MultiSelect,
27
20
  {
28
21
  withTags: true,
29
- placeholder: formatMessage(getTrad("roles.placeholder")),
22
+ placeholder: formatMessage(index.getTrad("roles.placeholder")),
30
23
  value: oidcRole.role ? oidcRole.role.map((r) => String(r)) : [],
31
24
  onChange: (value) => {
32
25
  if (value && value.length > 0) {
@@ -78,7 +71,7 @@ function Whitelist({
78
71
  if (users.some((user) => user.email === emailText)) {
79
72
  toggleNotification({
80
73
  type: "warning",
81
- message: formatMessage(getTrad("whitelist.error.unique"))
74
+ message: formatMessage(index.getTrad("whitelist.error.unique"))
82
75
  });
83
76
  } else {
84
77
  await onSave(emailText, selectedRoles);
@@ -90,8 +83,8 @@ function Whitelist({
90
83
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
91
84
  return emailRegex.test(email);
92
85
  }, [email]);
93
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
94
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textColor: "neutral600", marginBottom: 4, children: formatMessage(getTrad("whitelist.description")) }),
86
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
87
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { tag: "p", variant: "omega", textColor: "neutral600", marginBottom: 4, children: formatMessage(index.getTrad("whitelist.description")) }),
95
88
  useWhitelist && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
96
89
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, marginTop: 5, marginBottom: 5, alignItems: "flex-start", children: [
97
90
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Root, { children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -102,14 +95,14 @@ function Whitelist({
102
95
  value: email,
103
96
  hasError: Boolean(email && !isValidEmail()),
104
97
  onChange: (e) => setEmail(e.currentTarget.value),
105
- placeholder: formatMessage(getTrad("whitelist.email.placeholder"))
98
+ placeholder: formatMessage(index.getTrad("whitelist.email.placeholder"))
106
99
  }
107
100
  ) }) }),
108
101
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Root, { children: /* @__PURE__ */ jsxRuntime.jsx(
109
102
  designSystem.MultiSelect,
110
103
  {
111
104
  withTags: true,
112
- placeholder: formatMessage(getTrad("whitelist.roles.placeholder")),
105
+ placeholder: formatMessage(index.getTrad("whitelist.roles.placeholder")),
113
106
  value: selectedRoles,
114
107
  onChange: (value) => {
115
108
  setSelectedRoles(value || []);
@@ -125,20 +118,20 @@ function Whitelist({
125
118
  disabled: loading || email.trim() === "" || !isValidEmail(),
126
119
  loading,
127
120
  onClick: onSaveEmail,
128
- children: formatMessage(getTrad("page.add"))
121
+ children: formatMessage(index.getTrad("page.add"))
129
122
  }
130
123
  ) })
131
124
  ] }),
132
125
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
133
126
  /* @__PURE__ */ jsxRuntime.jsxs(CustomTable, { colCount: 5, rowCount: users.length, children: [
134
127
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
135
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(getTrad("whitelist.table.no")) }),
136
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(getTrad("whitelist.table.email")) }),
137
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(getTrad("whitelist.table.roles")) }),
138
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(getTrad("whitelist.table.created")) }),
128
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("whitelist.table.no")) }),
129
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("whitelist.table.email")) }),
130
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("whitelist.table.roles")) }),
131
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: formatMessage(index.getTrad("whitelist.table.created")) }),
139
132
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { paddingRight: 0 }, children: " " })
140
133
  ] }) }),
141
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: 5, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage(getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index2) => {
134
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: 5, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage(index.getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index$1) => {
142
135
  const getRoleNames = (roleIds) => roleIds.map((roleId) => {
143
136
  const r = roles.find((ro) => String(ro.id) === String(roleId));
144
137
  return r ? r.name : roleId;
@@ -152,7 +145,7 @@ function Whitelist({
152
145
  userRolesNames = getRoleNames(defaultRolesIds);
153
146
  }
154
147
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
155
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: index2 + 1 + (page - 1) * PAGE_SIZE }),
148
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: index$1 + 1 + (page - 1) * PAGE_SIZE }),
156
149
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: user.email }),
157
150
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: userRolesNames || "-" }),
158
151
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(LocalizedDate, { date: user.createdAt }) }),
@@ -166,27 +159,27 @@ function Whitelist({
166
159
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
167
160
  designSystem.IconButton,
168
161
  {
169
- label: formatMessage(getTrad("whitelist.delete.label")),
162
+ label: formatMessage(index.getTrad("whitelist.delete.label")),
170
163
  withTooltip: false,
171
164
  children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
172
165
  }
173
166
  ) }),
174
167
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
175
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage(getTrad("whitelist.delete.title")) }),
168
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage(index.getTrad("whitelist.delete.title")) }),
176
169
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { fill: "danger600" }), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
177
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", children: formatMessage(getTrad("whitelist.delete.description")) }) }),
170
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", children: formatMessage(index.getTrad("whitelist.delete.description")) }) }),
178
171
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: user.email }) }),
179
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(getTrad("whitelist.delete.note")) }) })
172
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(index.getTrad("whitelist.delete.note")) }) })
180
173
  ] }) }),
181
174
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
182
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, variant: "tertiary", children: formatMessage(getTrad("page.cancel")) }) }),
175
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, variant: "tertiary", children: formatMessage(index.getTrad("page.cancel")) }) }),
183
176
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(
184
177
  designSystem.Button,
185
178
  {
186
179
  fullWidth: true,
187
180
  variant: "danger-light",
188
181
  onClick: () => onDelete(user.email),
189
- children: formatMessage(getTrad("page.ok"))
182
+ children: formatMessage(index.getTrad("page.ok"))
190
183
  }
191
184
  ) })
192
185
  ] })
@@ -206,10 +199,10 @@ function Whitelist({
206
199
  e.preventDefault();
207
200
  setPage((p) => Math.max(1, p - 1));
208
201
  },
209
- children: "Go to previous page"
202
+ children: formatMessage(index.getTrad("pagination.previous"))
210
203
  }
211
204
  ),
212
- Array.from({ length: pageCount }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs(
205
+ Array.from({ length: pageCount }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
213
206
  designSystem.PageLink,
214
207
  {
215
208
  number: i + 1,
@@ -218,10 +211,7 @@ function Whitelist({
218
211
  e.preventDefault();
219
212
  setPage(i + 1);
220
213
  },
221
- children: [
222
- "Go to page ",
223
- i + 1
224
- ]
214
+ children: formatMessage(index.getTrad("pagination.page"), { page: i + 1 })
225
215
  },
226
216
  i + 1
227
217
  )),
@@ -233,12 +223,12 @@ function Whitelist({
233
223
  e.preventDefault();
234
224
  setPage((p) => Math.min(pageCount, p + 1));
235
225
  },
236
- children: "Go to next page"
226
+ children: formatMessage(index.getTrad("pagination.next"))
237
227
  }
238
228
  )
239
229
  ] }) }) })
240
230
  ] })
241
- ] }) });
231
+ ] });
242
232
  }
243
233
  const AlertMessage = styled__default.default.div`
244
234
  position: fixed;
@@ -250,11 +240,29 @@ const AlertMessage = styled__default.default.div`
250
240
  `;
251
241
  function SuccessAlertMessage({ onClose }) {
252
242
  const { formatMessage } = reactIntl.useIntl();
253
- return /* @__PURE__ */ jsxRuntime.jsx(AlertMessage, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Success", variant: "success", closeLabel: "", onClose, children: formatMessage(getTrad("page.save.success")) }) });
243
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertMessage, { children: /* @__PURE__ */ jsxRuntime.jsx(
244
+ designSystem.Alert,
245
+ {
246
+ title: formatMessage(index.getTrad("alert.title.success")),
247
+ variant: "success",
248
+ closeLabel: "",
249
+ onClose,
250
+ children: formatMessage(index.getTrad("page.save.success"))
251
+ }
252
+ ) });
254
253
  }
255
254
  function ErrorAlertMessage({ onClose }) {
256
255
  const { formatMessage } = reactIntl.useIntl();
257
- return /* @__PURE__ */ jsxRuntime.jsx(AlertMessage, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Error", variant: "danger", closeLabel: "", onClose, children: formatMessage(getTrad("page.save.error")) }) });
256
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertMessage, { children: /* @__PURE__ */ jsxRuntime.jsx(
257
+ designSystem.Alert,
258
+ {
259
+ title: formatMessage(index.getTrad("alert.title.error")),
260
+ variant: "danger",
261
+ closeLabel: "",
262
+ onClose,
263
+ children: formatMessage(index.getTrad("page.save.error"))
264
+ }
265
+ ) });
258
266
  }
259
267
  function MatchedUserAlertMessage({
260
268
  onClose,
@@ -262,7 +270,16 @@ function MatchedUserAlertMessage({
262
270
  }) {
263
271
  const { formatMessage } = reactIntl.useIntl();
264
272
  const id = count > 1 ? "whitelist.users_exists" : "whitelist.user_exists";
265
- return /* @__PURE__ */ jsxRuntime.jsx(AlertMessage, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Info", variant: "default", closeLabel: "", onClose, children: formatMessage(getTrad(id)) }) });
273
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertMessage, { children: /* @__PURE__ */ jsxRuntime.jsx(
274
+ designSystem.Alert,
275
+ {
276
+ title: formatMessage(index.getTrad("alert.title.info")),
277
+ variant: "default",
278
+ closeLabel: "",
279
+ onClose,
280
+ children: formatMessage(index.getTrad(id))
281
+ }
282
+ ) });
266
283
  }
267
284
  const SwitchContainer = styled__default.default.label`
268
285
  position: relative;
@@ -346,12 +363,9 @@ function useOidcSettings() {
346
363
  const [useWhitelist, setUseWhitelist] = react.useState(false);
347
364
  const [initialEnforceOIDC, setInitialEnforceOIDC] = react.useState(false);
348
365
  const [enforceOIDC, setEnforceOIDC] = react.useState(false);
366
+ const [enforceOIDCConfig, setEnforceOIDCConfig] = react.useState(null);
349
367
  const [initialUsers, setInitialUsers] = react.useState([]);
350
368
  const [users, setUsers] = react.useState([]);
351
- const [initialShowSSOButton, setInitialShowSSOButton] = react.useState(true);
352
- const [showSSOButton, setShowSSOButton] = react.useState(true);
353
- const [initialSSOButtonText, setInitialSSOButtonText] = react.useState("Login via SSO");
354
- const [ssoButtonText, setSSOButtonText] = react.useState("Login via SSO");
355
369
  react.useEffect(() => {
356
370
  get(`/strapi-plugin-oidc/oidc-roles`).then((response) => {
357
371
  setOIDCRoles(response.data);
@@ -367,10 +381,7 @@ function useOidcSettings() {
367
381
  setInitialUseWhitelist(response.data.useWhitelist);
368
382
  setEnforceOIDC(response.data.enforceOIDC);
369
383
  setInitialEnforceOIDC(response.data.enforceOIDC);
370
- setShowSSOButton(response.data.showSSOButton !== false);
371
- setInitialShowSSOButton(response.data.showSSOButton !== false);
372
- setSSOButtonText(response.data.ssoButtonText || "Login via SSO");
373
- setInitialSSOButtonText(response.data.ssoButtonText || "Login via SSO");
384
+ setEnforceOIDCConfig(response.data.enforceOIDCConfig ?? null);
374
385
  });
375
386
  }, [get]);
376
387
  const onChangeRole = (values, oidcId) => {
@@ -400,13 +411,7 @@ function useOidcSettings() {
400
411
  const onToggleEnforce = (e) => {
401
412
  setEnforceOIDC(e.target.checked);
402
413
  };
403
- const onToggleShowSSOButton = (e) => {
404
- setShowSSOButton(e.target.checked);
405
- };
406
- const onChangeSSOButtonText = (e) => {
407
- setSSOButtonText(e.target.value);
408
- };
409
- const isDirty = useWhitelist !== initialUseWhitelist || enforceOIDC !== initialEnforceOIDC || showSSOButton !== initialShowSSOButton || ssoButtonText !== initialSSOButtonText || JSON.stringify(oidcRoles) !== JSON.stringify(initialOidcRoles) || JSON.stringify(users) !== JSON.stringify(initialUsers);
414
+ const isDirty = useWhitelist !== initialUseWhitelist || enforceOIDC !== initialEnforceOIDC || JSON.stringify(oidcRoles) !== JSON.stringify(initialOidcRoles) || JSON.stringify(users) !== JSON.stringify(initialUsers);
410
415
  const onSaveAll = async () => {
411
416
  setLoading(true);
412
417
  try {
@@ -421,15 +426,11 @@ function useOidcSettings() {
421
426
  });
422
427
  await put("/strapi-plugin-oidc/whitelist/settings", {
423
428
  useWhitelist,
424
- enforceOIDC,
425
- showSSOButton,
426
- ssoButtonText
429
+ enforceOIDC
427
430
  });
428
431
  setInitialOIDCRoles(JSON.parse(JSON.stringify(oidcRoles)));
429
432
  setInitialUseWhitelist(useWhitelist);
430
433
  setInitialEnforceOIDC(enforceOIDC);
431
- setInitialShowSSOButton(showSSOButton);
432
- setInitialSSOButtonText(ssoButtonText);
433
434
  get("/strapi-plugin-oidc/whitelist").then((getResponse) => {
434
435
  setUsers(getResponse.data.whitelistUsers);
435
436
  setInitialUsers(JSON.parse(JSON.stringify(getResponse.data.whitelistUsers)));
@@ -459,10 +460,9 @@ function useOidcSettings() {
459
460
  roles,
460
461
  useWhitelist,
461
462
  enforceOIDC,
463
+ enforceOIDCConfig,
462
464
  initialEnforceOIDC,
463
465
  users,
464
- showSSOButton,
465
- ssoButtonText,
466
466
  isDirty
467
467
  },
468
468
  actions: {
@@ -474,8 +474,6 @@ function useOidcSettings() {
474
474
  onDeleteWhitelist,
475
475
  onToggleWhitelist,
476
476
  onToggleEnforce,
477
- onToggleShowSSOButton,
478
- onChangeSSOButtonText,
479
477
  onSaveAll
480
478
  }
481
479
  };
@@ -487,8 +485,8 @@ function HomePage$1() {
487
485
  /* @__PURE__ */ jsxRuntime.jsx(
488
486
  admin.Layouts.Header,
489
487
  {
490
- title: formatMessage(getTrad("page.title.oidc")),
491
- subtitle: formatMessage(getTrad("page.title"))
488
+ title: formatMessage(index.getTrad("page.title.oidc")),
489
+ subtitle: formatMessage(index.getTrad("page.title"))
492
490
  }
493
491
  ),
494
492
  state.showSuccess && /* @__PURE__ */ jsxRuntime.jsx(SuccessAlertMessage, { onClose: () => actions.setSuccess(false) }),
@@ -496,7 +494,7 @@ function HomePage$1() {
496
494
  state.showMatched > 0 && /* @__PURE__ */ jsxRuntime.jsx(MatchedUserAlertMessage, { count: state.showMatched, onClose: () => actions.setMatched(0) }),
497
495
  /* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
498
496
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: [
499
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(getTrad("roles.title")) }) }),
497
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(index.getTrad("roles.title")) }) }),
500
498
  /* @__PURE__ */ jsxRuntime.jsx(
501
499
  Role,
502
500
  {
@@ -508,13 +506,13 @@ function HomePage$1() {
508
506
  ] }),
509
507
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: [
510
508
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", paddingBottom: 4, children: [
511
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(getTrad("whitelist.title")) }),
509
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(index.getTrad("whitelist.title")) }),
512
510
  /* @__PURE__ */ jsxRuntime.jsx(
513
511
  CustomSwitch,
514
512
  {
515
513
  checked: state.useWhitelist,
516
514
  onChange: actions.onToggleWhitelist,
517
- label: state.useWhitelist ? formatMessage(getTrad("whitelist.toggle.enabled")) : formatMessage(getTrad("whitelist.toggle.disabled"))
515
+ label: state.useWhitelist ? formatMessage(index.getTrad("whitelist.toggle.enabled")) : formatMessage(index.getTrad("whitelist.toggle.disabled"))
518
516
  }
519
517
  )
520
518
  ] }),
@@ -532,58 +530,28 @@ function HomePage$1() {
532
530
  )
533
531
  ] }),
534
532
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: [
535
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(getTrad("login.settings.title")) }) }),
536
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
537
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
538
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, wrap: "wrap", children: [
539
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { minWidth: "280px" }, children: formatMessage(getTrad("enforce.title")) }),
540
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { minWidth: "160px", children: /* @__PURE__ */ jsxRuntime.jsx(
541
- CustomSwitch,
542
- {
543
- checked: state.enforceOIDC,
544
- onChange: actions.onToggleEnforce,
545
- disabled: state.useWhitelist && state.users.length === 0,
546
- label: state.enforceOIDC ? formatMessage(getTrad("enforce.toggle.enabled")) : formatMessage(getTrad("enforce.toggle.disabled"))
547
- }
548
- ) })
549
- ] }),
550
- state.enforceOIDC && state.enforceOIDC !== state.initialEnforceOIDC && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "danger100", padding: 3, hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
551
- /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { fill: "danger600" }),
552
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: formatMessage(getTrad("enforce.warning")) })
553
- ] }) })
554
- ] }),
533
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(index.getTrad("login.settings.title")) }) }),
534
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
555
535
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, wrap: "wrap", children: [
556
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { minWidth: "280px" }, children: formatMessage(getTrad("login.sso.show")) }),
536
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { minWidth: "280px" }, children: formatMessage(index.getTrad("enforce.title")) }),
557
537
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { minWidth: "160px", children: /* @__PURE__ */ jsxRuntime.jsx(
558
538
  CustomSwitch,
559
539
  {
560
- checked: state.showSSOButton,
561
- onChange: actions.onToggleShowSSOButton,
562
- label: state.showSSOButton ? formatMessage(getTrad("enforce.toggle.enabled")) : formatMessage(getTrad("enforce.toggle.disabled"))
540
+ checked: state.enforceOIDC,
541
+ onChange: actions.onToggleEnforce,
542
+ disabled: state.enforceOIDCConfig !== null || state.useWhitelist && state.users.length === 0,
543
+ label: state.enforceOIDC ? formatMessage(index.getTrad("enforce.toggle.enabled")) : formatMessage(index.getTrad("enforce.toggle.disabled"))
563
544
  }
564
545
  ) })
565
546
  ] }),
566
- state.showSSOButton && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, wrap: "wrap", children: [
567
- /* @__PURE__ */ jsxRuntime.jsx(
568
- designSystem.Typography,
569
- {
570
- variant: "omega",
571
- tag: "label",
572
- htmlFor: "sso-button-text",
573
- style: { minWidth: "280px" },
574
- children: formatMessage(getTrad("login.sso.button.text.label"))
575
- }
576
- ),
577
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: "160px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
578
- designSystem.TextInput,
579
- {
580
- id: "sso-button-text",
581
- "aria-label": formatMessage(getTrad("login.sso.button.text.label")),
582
- value: state.ssoButtonText,
583
- onChange: actions.onChangeSSOButtonText
584
- }
585
- ) })
586
- ] })
547
+ state.enforceOIDCConfig !== null && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "primary100", padding: 3, hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
548
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Information, { fill: "primary600" }),
549
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "primary600", children: formatMessage(index.getTrad("enforce.config.info")) })
550
+ ] }) }),
551
+ state.enforceOIDCConfig === null && state.enforceOIDC && state.enforceOIDC !== state.initialEnforceOIDC && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "danger100", padding: 3, hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
552
+ /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { fill: "danger600" }),
553
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: formatMessage(index.getTrad("enforce.warning")) })
554
+ ] }) })
587
555
  ] })
588
556
  ] }),
589
557
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -593,7 +561,7 @@ function HomePage$1() {
593
561
  onClick: actions.onSaveAll,
594
562
  disabled: !state.isDirty || state.loading,
595
563
  loading: state.loading,
596
- children: formatMessage(getTrad("page.save"))
564
+ children: formatMessage(index.getTrad("page.save"))
597
565
  }
598
566
  ) })
599
567
  ] }) })