strapi-plugin-firebase-authentication 1.1.11 → 1.2.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.
Files changed (33) hide show
  1. package/dist/_chunks/{App-DZQe17x8.js → App-B7d4qS3T.js} +203 -141
  2. package/dist/_chunks/{App-BY1gNGKH.mjs → App-CQ9ehArz.mjs} +112 -29
  3. package/dist/_chunks/{api-D_4cdJU5.mjs → api-BM2UtpvM.mjs} +1 -1
  4. package/dist/_chunks/{api-DR4wmAFN.js → api-DYP-1kdx.js} +1 -1
  5. package/dist/_chunks/{index-D8pv1Q6h.mjs → index-0tTyhxbb.mjs} +148 -34
  6. package/dist/_chunks/{index-BnT1fFPr.js → index-B5EwGI_y.js} +2 -2
  7. package/dist/_chunks/{index-DtGfwf9S.mjs → index-CMFutRyI.mjs} +2 -2
  8. package/dist/_chunks/{index-dVTLVmwU.js → index-Cwp9xkG4.js} +148 -34
  9. package/dist/admin/index.js +1 -1
  10. package/dist/admin/index.mjs +1 -1
  11. package/dist/admin/src/components/user-management/ResendVerification/ResendVerification.d.ts +9 -0
  12. package/dist/admin/src/components/user-management/index.d.ts +1 -0
  13. package/dist/admin/src/pages/Settings/api.d.ts +4 -0
  14. package/dist/admin/src/pages/utils/api.d.ts +2 -1
  15. package/dist/server/index.js +6447 -2301
  16. package/dist/server/index.mjs +6444 -2298
  17. package/dist/server/src/config/index.d.ts +1 -1
  18. package/dist/server/src/content-types/index.d.ts +23 -0
  19. package/dist/server/src/controllers/firebaseController.d.ts +24 -0
  20. package/dist/server/src/controllers/index.d.ts +4 -0
  21. package/dist/server/src/controllers/userController.d.ts +1 -0
  22. package/dist/server/src/index.d.ts +65 -2
  23. package/dist/server/src/services/emailService.d.ts +19 -0
  24. package/dist/server/src/services/firebaseService.d.ts +19 -2
  25. package/dist/server/src/services/index.d.ts +37 -1
  26. package/dist/server/src/services/settingsService.d.ts +2 -0
  27. package/dist/server/src/services/tokenService.d.ts +49 -0
  28. package/dist/server/src/services/userService.d.ts +27 -1
  29. package/dist/server/src/templates/defaults/email-verification.d.ts +2 -0
  30. package/dist/server/src/templates/defaults/index.d.ts +2 -0
  31. package/dist/server/src/templates/defaults/password-changed.d.ts +2 -0
  32. package/dist/server/src/templates/types.d.ts +6 -2
  33. package/package.json +1 -1
@@ -5,13 +5,13 @@ import { Provider } from "@radix-ui/react-tooltip";
5
5
  import React, { useState, useCallback, useMemo, useEffect, useRef, useLayoutEffect } from "react";
6
6
  import { Link, Flex, Box, Button, Tooltip, Tbody, Tr, Td, Checkbox, Typography, Modal, Table, Thead, Th, SingleSelect, SingleSelectOption, SearchForm, Searchbar, IconButton, Dialog, Tabs, TextInput, Alert, Field, Toggle, Divider } from "@strapi/design-system";
7
7
  import { useIntl } from "react-intl";
8
- import { i as isArguments_1, a as isBufferExports, b as isTypedArray_1, c as isLength_1, d as isFunction_1, _ as _getTag, e as _Stack, f as _equalArrays, g as _equalByTag, h as isObjectLike_1, j as getDefaultExportFromCjs, k as _baseGetTag, l as _MapCache, m as _Symbol, P as PLUGIN_ID, n as getAugmentedNamespace, o as commonjsGlobal } from "./index-DtGfwf9S.mjs";
8
+ import { i as isArguments_1, a as isBufferExports, b as isTypedArray_1, c as isLength_1, d as isFunction_1, _ as _getTag, e as _Stack, f as _equalArrays, g as _equalByTag, h as isObjectLike_1, j as getDefaultExportFromCjs, k as _baseGetTag, l as _MapCache, m as _Symbol, P as PLUGIN_ID, n as getAugmentedNamespace, o as commonjsGlobal } from "./index-CMFutRyI.mjs";
9
9
  import { ArrowLeft, Key, Trash, WarningCircle, CaretUp, CaretDown, Search, Plus, Pencil } from "@strapi/icons";
10
10
  import styled from "styled-components";
11
11
  import { RxCheck, RxCross2 } from "react-icons/rx";
12
12
  import { AiOutlineUserAdd, AiFillPhone, AiFillMail, AiFillYahoo, AiFillGithub, AiFillTwitterCircle, AiFillFacebook, AiFillApple, AiFillGoogleCircle } from "react-icons/ai";
13
13
  import { MdPassword } from "react-icons/md";
14
- import { g as getFirebaseConfig$1 } from "./api-D_4cdJU5.mjs";
14
+ import { g as getFirebaseConfig$1 } from "./api-BM2UtpvM.mjs";
15
15
  import * as PhoneInputModule from "react-phone-input-2";
16
16
  import "react-phone-input-2/lib/style.css";
17
17
  import validator from "validator";
@@ -2707,6 +2707,12 @@ const getFirebaseConfig = async () => {
2707
2707
  };
2708
2708
  }
2709
2709
  };
2710
+ const sendVerificationEmail = async (userId) => {
2711
+ const url = `/${PLUGIN_ID}/users/sendVerificationEmail/${userId}`;
2712
+ const { put } = getFetchClient();
2713
+ const { data: result } = await put(url, {});
2714
+ return result;
2715
+ };
2710
2716
  const PaginationFooter = ({ pageCount = 0 }) => {
2711
2717
  const [{ query }, setQuery] = useQueryParams$1();
2712
2718
  const pageSize = query?.pageSize || "10";
@@ -5034,6 +5040,59 @@ const ResetPassword = ({
5034
5040
  ] })
5035
5041
  ] }) });
5036
5042
  };
5043
+ const ResendVerification = ({
5044
+ isOpen,
5045
+ email,
5046
+ userId,
5047
+ onClose,
5048
+ onSendVerificationEmail
5049
+ }) => {
5050
+ const [isLoading, setIsLoading] = useState(false);
5051
+ const [emailSent, setEmailSent] = useState(false);
5052
+ const [error, setError] = useState("");
5053
+ const resetState = () => {
5054
+ setEmailSent(false);
5055
+ setError("");
5056
+ setIsLoading(false);
5057
+ };
5058
+ const handleClose = () => {
5059
+ resetState();
5060
+ onClose();
5061
+ };
5062
+ const handleSendEmail = async () => {
5063
+ try {
5064
+ setIsLoading(true);
5065
+ setError("");
5066
+ await onSendVerificationEmail();
5067
+ setEmailSent(true);
5068
+ } catch (err) {
5069
+ setError(err.message || "Failed to send verification email");
5070
+ } finally {
5071
+ setIsLoading(false);
5072
+ }
5073
+ };
5074
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
5075
+ /* @__PURE__ */ jsx(Dialog.Header, { children: "Resend Verification Email" }),
5076
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, alignItems: "center", children: [
5077
+ !emailSent ? /* @__PURE__ */ jsxs(Fragment, { children: [
5078
+ /* @__PURE__ */ jsxs(Typography, { textAlign: "center", children: [
5079
+ "Send a verification email to ",
5080
+ /* @__PURE__ */ jsx("strong", { children: email }),
5081
+ "?"
5082
+ ] }),
5083
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", textAlign: "center", children: "The link will expire in 1 hour." })
5084
+ ] }) : /* @__PURE__ */ jsxs(Alert, { variant: "success", title: "Email Sent", children: [
5085
+ "Verification email has been sent to ",
5086
+ email
5087
+ ] }),
5088
+ error && /* @__PURE__ */ jsx(Alert, { variant: "danger", title: "Error", children: error })
5089
+ ] }) }),
5090
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
5091
+ /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", children: emailSent ? "Close" : "Cancel" }),
5092
+ !emailSent && /* @__PURE__ */ jsx(Button, { variant: "success", loading: isLoading, onClick: handleSendEmail, children: "Send" })
5093
+ ] })
5094
+ ] }) });
5095
+ };
5037
5096
  const HEADER_TITLE = "Firebase Users";
5038
5097
  const NOTIFICATION_MESSAGES = {
5039
5098
  DELETED: "Deleted",
@@ -5394,24 +5453,10 @@ const HomePage = () => {
5394
5453
  let PhoneInputTemp = PhoneInputModule;
5395
5454
  let unwrapCount = 0;
5396
5455
  while (PhoneInputTemp && typeof PhoneInputTemp === "object" && PhoneInputTemp.default && unwrapCount < 5) {
5397
- console.log(`🔧 Unwrapping PhoneInput layer ${unwrapCount}:`, PhoneInputTemp);
5398
5456
  PhoneInputTemp = PhoneInputTemp.default;
5399
5457
  unwrapCount++;
5400
5458
  }
5401
5459
  const PhoneInput = PhoneInputTemp;
5402
- console.log("🔍 ==================== PhoneInput Final Check ====================");
5403
- console.log(" Unwrap iterations:", unwrapCount);
5404
- console.log(" PhoneInput FINAL:", PhoneInput);
5405
- console.log(" PhoneInput type:", typeof PhoneInput);
5406
- console.log(" PhoneInput $$typeof:", PhoneInput?.$$typeof);
5407
- console.log(" PhoneInput name:", PhoneInput?.name);
5408
- console.log(" PhoneInput displayName:", PhoneInput?.displayName);
5409
- console.log(" Is function?:", typeof PhoneInput === "function");
5410
- console.log(
5411
- " Is valid React component?:",
5412
- typeof PhoneInput === "function" || PhoneInput && PhoneInput.$$typeof
5413
- );
5414
- console.log("🔍 ================================================================");
5415
5460
  const StyledPhoneInputWrapper = styled.div`
5416
5461
  width: 100%;
5417
5462
 
@@ -5935,6 +5980,11 @@ const EditUserForm = ({ data }) => {
5935
5980
  email: "",
5936
5981
  id: ""
5937
5982
  });
5983
+ const [showVerificationDialog, setShowVerificationDialog] = useState({
5984
+ isOpen: false,
5985
+ email: "",
5986
+ id: ""
5987
+ });
5938
5988
  const [passwordConfig, setPasswordConfig] = useState({
5939
5989
  passwordRequirementsRegex: "^.{6,}$",
5940
5990
  passwordRequirementsMessage: "Password must be at least 6 characters long"
@@ -6022,6 +6072,12 @@ const EditUserForm = ({ data }) => {
6022
6072
  });
6023
6073
  }
6024
6074
  }, [userData.uid, toggleNotification]);
6075
+ const handleCloseVerificationDialog = useCallback(() => {
6076
+ setShowVerificationDialog({ isOpen: false, email: "", id: "" });
6077
+ }, []);
6078
+ const handleSendVerificationEmail = useCallback(async () => {
6079
+ await sendVerificationEmail(userData.uid);
6080
+ }, [userData.uid]);
6025
6081
  if (isLoading) {
6026
6082
  return /* @__PURE__ */ jsx(Page.Loading, {});
6027
6083
  }
@@ -6125,20 +6181,37 @@ const EditUserForm = ({ data }) => {
6125
6181
  shadow: "tableShadow",
6126
6182
  children: [
6127
6183
  /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 2, children: "Account Actions" }),
6128
- /* @__PURE__ */ jsx(
6129
- PasswordResetButton,
6130
- {
6131
- user: userData,
6132
- fullWidth: true,
6133
- onClick: () => {
6134
- setShowResetPasswordDialog({
6135
- isOpen: true,
6136
- email: userData.email || "",
6137
- id: userData.uid || ""
6138
- });
6184
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
6185
+ /* @__PURE__ */ jsx(
6186
+ PasswordResetButton,
6187
+ {
6188
+ user: userData,
6189
+ fullWidth: true,
6190
+ onClick: () => {
6191
+ setShowResetPasswordDialog({
6192
+ isOpen: true,
6193
+ email: userData.email || "",
6194
+ id: userData.uid || ""
6195
+ });
6196
+ }
6139
6197
  }
6140
- }
6141
- )
6198
+ ),
6199
+ userData.email && !userData.emailVerified && /* @__PURE__ */ jsx(
6200
+ Button,
6201
+ {
6202
+ variant: "secondary",
6203
+ fullWidth: true,
6204
+ onClick: () => {
6205
+ setShowVerificationDialog({
6206
+ isOpen: true,
6207
+ email: userData.email || "",
6208
+ id: userData.uid || ""
6209
+ });
6210
+ },
6211
+ children: "Resend Verification Email"
6212
+ }
6213
+ )
6214
+ ] })
6142
6215
  ]
6143
6216
  }
6144
6217
  ),
@@ -6203,6 +6276,16 @@ const EditUserForm = ({ data }) => {
6203
6276
  passwordMessage: passwordConfig.passwordRequirementsMessage,
6204
6277
  onSendResetEmail: handleSendResetEmail
6205
6278
  }
6279
+ ),
6280
+ /* @__PURE__ */ jsx(
6281
+ ResendVerification,
6282
+ {
6283
+ isOpen: showVerificationDialog.isOpen,
6284
+ onClose: handleCloseVerificationDialog,
6285
+ email: showVerificationDialog.email,
6286
+ userId: showVerificationDialog.id,
6287
+ onSendVerificationEmail: handleSendVerificationEmail
6288
+ }
6206
6289
  )
6207
6290
  ] });
6208
6291
  };
@@ -1,5 +1,5 @@
1
1
  import { getFetchClient } from "@strapi/strapi/admin";
2
- import { P as PLUGIN_ID } from "./index-DtGfwf9S.mjs";
2
+ import { P as PLUGIN_ID } from "./index-CMFutRyI.mjs";
3
3
  const saveFirebaseConfig = async (json, firebaseWebApiKey, passwordConfig) => {
4
4
  const url = `/${PLUGIN_ID}/settings/firebase-config`;
5
5
  const { post } = getFetchClient();
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const admin = require("@strapi/strapi/admin");
3
- const index = require("./index-BnT1fFPr.js");
3
+ const index = require("./index-B5EwGI_y.js");
4
4
  const saveFirebaseConfig = async (json, firebaseWebApiKey, passwordConfig) => {
5
5
  const url = `/${index.PLUGIN_ID}/settings/firebase-config`;
6
6
  const { post } = admin.getFetchClient();
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
3
  import { Flex, Box, Typography, JSONInput, Button, TextInput, Badge, Textarea, Toggle, NumberInput, Modal } from "@strapi/design-system";
4
4
  import { useNotification, Page } from "@strapi/strapi/admin";
5
- import { g as getFirebaseConfig, s as saveFirebaseConfig, d as delFirebaseConfig, a as savePasswordSettings } from "./api-D_4cdJU5.mjs";
5
+ import { g as getFirebaseConfig, s as saveFirebaseConfig, d as delFirebaseConfig, a as savePasswordSettings } from "./api-BM2UtpvM.mjs";
6
6
  import { useNavigate } from "react-router-dom";
7
7
  function SettingsPage() {
8
8
  const { toggleNotification } = useNotification();
@@ -20,6 +20,10 @@ function SettingsPage() {
20
20
  const [magicLinkUrl, setMagicLinkUrl] = useState("http://localhost:1338/verify-magic-link.html");
21
21
  const [magicLinkEmailSubject, setMagicLinkEmailSubject] = useState("Sign in to Your Application");
22
22
  const [magicLinkExpiryHours, setMagicLinkExpiryHours] = useState(1);
23
+ const [emailVerificationUrl, setEmailVerificationUrl] = useState(
24
+ "http://localhost:3000/verify-email"
25
+ );
26
+ const [emailVerificationEmailSubject, setEmailVerificationEmailSubject] = useState("Verify Your Email");
23
27
  const [loading, setLoading] = useState(true);
24
28
  const [showEditModal, setShowEditModal] = useState(false);
25
29
  const [editWebApiKey, setEditWebApiKey] = useState("");
@@ -46,6 +50,8 @@ function SettingsPage() {
46
50
  setMagicLinkUrl(data?.magicLinkUrl || "http://localhost:1338/verify-magic-link.html");
47
51
  setMagicLinkEmailSubject(data?.magicLinkEmailSubject || "Sign in to Your Application");
48
52
  setMagicLinkExpiryHours(data?.magicLinkExpiryHours || 1);
53
+ setEmailVerificationUrl(data?.emailVerificationUrl || "http://localhost:3000/verify-email");
54
+ setEmailVerificationEmailSubject(data?.emailVerificationEmailSubject || "Verify Your Email");
49
55
  }).catch((error) => {
50
56
  setLoading(false);
51
57
  console.error("Error retrieving Firebase config:", error);
@@ -71,6 +77,8 @@ function SettingsPage() {
71
77
  setMagicLinkUrl("http://localhost:1338/verify-magic-link.html");
72
78
  setMagicLinkEmailSubject("Sign in to Your Application");
73
79
  setMagicLinkExpiryHours(1);
80
+ setEmailVerificationUrl("http://localhost:3000/verify-email");
81
+ setEmailVerificationEmailSubject("Verify Your Email");
74
82
  setLoading(false);
75
83
  toggleNotification({
76
84
  type: "success",
@@ -96,7 +104,9 @@ function SettingsPage() {
96
104
  enableMagicLink,
97
105
  magicLinkUrl,
98
106
  magicLinkEmailSubject,
99
- magicLinkExpiryHours
107
+ magicLinkExpiryHours,
108
+ emailVerificationUrl,
109
+ emailVerificationEmailSubject
100
110
  });
101
111
  if (!data || !data.firebase_config_json) {
102
112
  throw new Error("Invalid response from server");
@@ -127,7 +137,9 @@ function SettingsPage() {
127
137
  enableMagicLink,
128
138
  magicLinkUrl,
129
139
  magicLinkEmailSubject,
130
- magicLinkExpiryHours
140
+ magicLinkExpiryHours,
141
+ emailVerificationUrl,
142
+ emailVerificationEmailSubject
131
143
  });
132
144
  if (data) {
133
145
  setPasswordRequirementsRegex(data.passwordRequirementsRegex || passwordRequirementsRegex);
@@ -138,6 +150,8 @@ function SettingsPage() {
138
150
  setMagicLinkUrl(data.magicLinkUrl || magicLinkUrl);
139
151
  setMagicLinkEmailSubject(data.magicLinkEmailSubject || magicLinkEmailSubject);
140
152
  setMagicLinkExpiryHours(data.magicLinkExpiryHours || magicLinkExpiryHours);
153
+ setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
154
+ setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
141
155
  }
142
156
  setLoading(false);
143
157
  toggleNotification({
@@ -164,13 +178,17 @@ function SettingsPage() {
164
178
  enableMagicLink,
165
179
  magicLinkUrl,
166
180
  magicLinkEmailSubject,
167
- magicLinkExpiryHours
181
+ magicLinkExpiryHours,
182
+ emailVerificationUrl,
183
+ emailVerificationEmailSubject
168
184
  });
169
185
  if (data) {
170
186
  setEnableMagicLink(data.enableMagicLink || enableMagicLink);
171
187
  setMagicLinkUrl(data.magicLinkUrl || magicLinkUrl);
172
188
  setMagicLinkEmailSubject(data.magicLinkEmailSubject || magicLinkEmailSubject);
173
189
  setMagicLinkExpiryHours(data.magicLinkExpiryHours || magicLinkExpiryHours);
190
+ setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
191
+ setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
174
192
  }
175
193
  setLoading(false);
176
194
  toggleNotification({
@@ -186,6 +204,39 @@ function SettingsPage() {
186
204
  setLoading(false);
187
205
  }
188
206
  };
207
+ const handleSaveEmailVerificationSettings = async () => {
208
+ try {
209
+ setLoading(true);
210
+ const data = await savePasswordSettings({
211
+ passwordRequirementsRegex,
212
+ passwordRequirementsMessage,
213
+ passwordResetUrl,
214
+ passwordResetEmailSubject,
215
+ enableMagicLink,
216
+ magicLinkUrl,
217
+ magicLinkEmailSubject,
218
+ magicLinkExpiryHours,
219
+ emailVerificationUrl,
220
+ emailVerificationEmailSubject
221
+ });
222
+ if (data) {
223
+ setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
224
+ setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
225
+ }
226
+ setLoading(false);
227
+ toggleNotification({
228
+ type: "success",
229
+ message: "Email verification settings saved successfully"
230
+ });
231
+ } catch (error) {
232
+ console.error("Error saving email verification settings:", error);
233
+ toggleNotification({
234
+ type: "warning",
235
+ message: "Failed to save email verification settings"
236
+ });
237
+ setLoading(false);
238
+ }
239
+ };
189
240
  const handleAddWebApiKey = () => {
190
241
  setEditWebApiKey("");
191
242
  setShowEditModal(true);
@@ -206,7 +257,9 @@ function SettingsPage() {
206
257
  enableMagicLink,
207
258
  magicLinkUrl,
208
259
  magicLinkEmailSubject,
209
- magicLinkExpiryHours
260
+ magicLinkExpiryHours,
261
+ emailVerificationUrl,
262
+ emailVerificationEmailSubject
210
263
  });
211
264
  if (!data || !data.firebase_config_json) {
212
265
  throw new Error("Invalid response from server");
@@ -239,7 +292,9 @@ function SettingsPage() {
239
292
  enableMagicLink,
240
293
  magicLinkUrl,
241
294
  magicLinkEmailSubject,
242
- magicLinkExpiryHours
295
+ magicLinkExpiryHours,
296
+ emailVerificationUrl,
297
+ emailVerificationEmailSubject
243
298
  });
244
299
  if (!data || !data.firebase_config_json) {
245
300
  throw new Error("Invalid response from server");
@@ -561,34 +616,7 @@ function SettingsPage() {
561
616
  }
562
617
  )
563
618
  ] }),
564
- /* @__PURE__ */ jsxs(Box, { marginBottom: 3, children: [
565
- /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Password Reset URL *" }),
566
- /* @__PURE__ */ jsx(
567
- TextInput,
568
- {
569
- name: "passwordResetUrl",
570
- value: passwordResetUrl,
571
- onChange: (e) => setPasswordResetUrl(e.target.value),
572
- placeholder: "https://yourapp.com/reset-password",
573
- hint: "URL where users will reset their password (your frontend application)",
574
- required: true
575
- }
576
- )
577
- ] }),
578
- /* @__PURE__ */ jsxs(Box, { marginBottom: 3, children: [
579
- /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Reset Email Subject" }),
580
- /* @__PURE__ */ jsx(
581
- TextInput,
582
- {
583
- name: "passwordResetEmailSubject",
584
- value: passwordResetEmailSubject,
585
- onChange: (e) => setPasswordResetEmailSubject(e.target.value),
586
- placeholder: "Reset Your Password",
587
- hint: "Subject line for password reset emails"
588
- }
589
- )
590
- ] }),
591
- /* @__PURE__ */ jsxs(Box, { marginTop: 4, padding: 3, background: "neutral100", borderRadius: "4px", children: [
619
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 4, padding: 3, background: "neutral100", borderRadius: "4px", children: [
592
620
  /* @__PURE__ */ jsx(
593
621
  Typography,
594
622
  {
@@ -621,6 +649,33 @@ function SettingsPage() {
621
649
  ] })
622
650
  ] })
623
651
  ] }),
652
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 3, children: [
653
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Password Reset URL *" }),
654
+ /* @__PURE__ */ jsx(
655
+ TextInput,
656
+ {
657
+ name: "passwordResetUrl",
658
+ value: passwordResetUrl,
659
+ onChange: (e) => setPasswordResetUrl(e.target.value),
660
+ placeholder: "https://yourapp.com/reset-password",
661
+ hint: "URL where users will reset their password (your frontend application)",
662
+ required: true
663
+ }
664
+ )
665
+ ] }),
666
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 3, children: [
667
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Reset Email Subject" }),
668
+ /* @__PURE__ */ jsx(
669
+ TextInput,
670
+ {
671
+ name: "passwordResetEmailSubject",
672
+ value: passwordResetEmailSubject,
673
+ onChange: (e) => setPasswordResetEmailSubject(e.target.value),
674
+ placeholder: "Reset Your Password",
675
+ hint: "Subject line for password reset emails"
676
+ }
677
+ )
678
+ ] }),
624
679
  /* @__PURE__ */ jsx(
625
680
  Flex,
626
681
  {
@@ -633,6 +688,65 @@ function SettingsPage() {
633
688
  }
634
689
  )
635
690
  ] }),
691
+ /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", shadow: "filterShadow", marginBottom: 6, children: [
692
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h2", style: { display: "block", marginBottom: "8px" }, children: "Email Verification" }),
693
+ /* @__PURE__ */ jsx(
694
+ Typography,
695
+ {
696
+ variant: "omega",
697
+ textColor: "neutral600",
698
+ style: { display: "block", marginBottom: "24px" },
699
+ children: "Configure email verification settings for new user registration"
700
+ }
701
+ ),
702
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 3, children: [
703
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Email Verification URL *" }),
704
+ /* @__PURE__ */ jsx(
705
+ TextInput,
706
+ {
707
+ name: "emailVerificationUrl",
708
+ value: emailVerificationUrl,
709
+ onChange: (e) => setEmailVerificationUrl(e.target.value),
710
+ placeholder: "https://yourapp.com/verify-email",
711
+ hint: "URL where users will verify their email address (your frontend application)",
712
+ required: true
713
+ }
714
+ )
715
+ ] }),
716
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 3, children: [
717
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Verification Email Subject" }),
718
+ /* @__PURE__ */ jsx(
719
+ TextInput,
720
+ {
721
+ name: "emailVerificationEmailSubject",
722
+ value: emailVerificationEmailSubject,
723
+ onChange: (e) => setEmailVerificationEmailSubject(e.target.value),
724
+ placeholder: "Verify Your Email",
725
+ hint: "Subject line for email verification emails"
726
+ }
727
+ )
728
+ ] }),
729
+ /* @__PURE__ */ jsx(
730
+ Flex,
731
+ {
732
+ style: {
733
+ marginTop: 24,
734
+ width: "100%"
735
+ },
736
+ justifyContent: "flex-end",
737
+ children: /* @__PURE__ */ jsx(
738
+ Button,
739
+ {
740
+ size: "L",
741
+ variant: "secondary",
742
+ onClick: handleSaveEmailVerificationSettings,
743
+ disabled: loading,
744
+ children: "Save Email Verification Settings"
745
+ }
746
+ )
747
+ }
748
+ )
749
+ ] }),
636
750
  /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", shadow: "filterShadow", marginBottom: 6, children: [
637
751
  /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h2", style: { display: "block", marginBottom: "8px" }, children: "Magic Link Authentication" }),
638
752
  /* @__PURE__ */ jsx(
@@ -739,7 +739,7 @@ const index = {
739
739
  id: `${PLUGIN_ID}.page.title`,
740
740
  defaultMessage: PLUGIN_ID
741
741
  },
742
- Component: () => Promise.resolve().then(() => require("./App-DZQe17x8.js")).then((mod) => ({
742
+ Component: () => Promise.resolve().then(() => require("./App-B7d4qS3T.js")).then((mod) => ({
743
743
  default: mod.App
744
744
  })),
745
745
  permissions: PERMISSIONS["menu-link"]
@@ -761,7 +761,7 @@ const index = {
761
761
  id: "settings",
762
762
  to: `/settings/${PLUGIN_ID}`,
763
763
  async Component() {
764
- const component = await Promise.resolve().then(() => require("./index-dVTLVmwU.js"));
764
+ const component = await Promise.resolve().then(() => require("./index-Cwp9xkG4.js"));
765
765
  return component.default;
766
766
  },
767
767
  permissions: PERMISSIONS["menu-link"]
@@ -738,7 +738,7 @@ const index = {
738
738
  id: `${PLUGIN_ID}.page.title`,
739
739
  defaultMessage: PLUGIN_ID
740
740
  },
741
- Component: () => import("./App-BY1gNGKH.mjs").then((mod) => ({
741
+ Component: () => import("./App-CQ9ehArz.mjs").then((mod) => ({
742
742
  default: mod.App
743
743
  })),
744
744
  permissions: PERMISSIONS["menu-link"]
@@ -760,7 +760,7 @@ const index = {
760
760
  id: "settings",
761
761
  to: `/settings/${PLUGIN_ID}`,
762
762
  async Component() {
763
- const component = await import("./index-D8pv1Q6h.mjs");
763
+ const component = await import("./index-0tTyhxbb.mjs");
764
764
  return component.default;
765
765
  },
766
766
  permissions: PERMISSIONS["menu-link"]