strapi-plugin-firebase-authentication 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.
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const m = require("react");
5
- const api = require("./api-FVfrlu9T.js");
5
+ const api = require("./api-Bg075IIT.js");
6
6
  const admin = require("@strapi/strapi/admin");
7
7
  const reactRouterDom = require("react-router-dom");
8
8
  function SettingsPage() {
@@ -25,6 +25,8 @@ function SettingsPage() {
25
25
  "http://localhost:3000/verify-email"
26
26
  );
27
27
  const [emailVerificationEmailSubject, setEmailVerificationEmailSubject] = m.useState("Verify Your Email");
28
+ const [includeCredentialsInPasswordResetLink, setIncludeCredentialsInPasswordResetLink] = m.useState(false);
29
+ const [includeCredentialsInVerificationLink, setIncludeCredentialsInVerificationLink] = m.useState(false);
28
30
  const [loading, setLoading] = m.useState(true);
29
31
  const [showEditModal, setShowEditModal] = m.useState(false);
30
32
  const [editWebApiKey, setEditWebApiKey] = m.useState("");
@@ -53,6 +55,8 @@ function SettingsPage() {
53
55
  setMagicLinkExpiryHours(data?.magicLinkExpiryHours || 1);
54
56
  setEmailVerificationUrl(data?.emailVerificationUrl || "http://localhost:3000/verify-email");
55
57
  setEmailVerificationEmailSubject(data?.emailVerificationEmailSubject || "Verify Your Email");
58
+ setIncludeCredentialsInPasswordResetLink(data?.includeCredentialsInPasswordResetLink || false);
59
+ setIncludeCredentialsInVerificationLink(data?.includeCredentialsInVerificationLink || false);
56
60
  }).catch((error) => {
57
61
  setLoading(false);
58
62
  console.error("Error retrieving Firebase config:", error);
@@ -80,6 +84,8 @@ function SettingsPage() {
80
84
  setMagicLinkExpiryHours(1);
81
85
  setEmailVerificationUrl("http://localhost:3000/verify-email");
82
86
  setEmailVerificationEmailSubject("Verify Your Email");
87
+ setIncludeCredentialsInPasswordResetLink(false);
88
+ setIncludeCredentialsInVerificationLink(false);
83
89
  setLoading(false);
84
90
  toggleNotification({
85
91
  type: "success",
@@ -107,7 +113,9 @@ function SettingsPage() {
107
113
  magicLinkEmailSubject,
108
114
  magicLinkExpiryHours,
109
115
  emailVerificationUrl,
110
- emailVerificationEmailSubject
116
+ emailVerificationEmailSubject,
117
+ includeCredentialsInPasswordResetLink,
118
+ includeCredentialsInVerificationLink
111
119
  });
112
120
  if (!data || !data.firebase_config_json) {
113
121
  throw new Error("Invalid response from server");
@@ -140,7 +148,9 @@ function SettingsPage() {
140
148
  magicLinkEmailSubject,
141
149
  magicLinkExpiryHours,
142
150
  emailVerificationUrl,
143
- emailVerificationEmailSubject
151
+ emailVerificationEmailSubject,
152
+ includeCredentialsInPasswordResetLink,
153
+ includeCredentialsInVerificationLink
144
154
  });
145
155
  if (data) {
146
156
  setPasswordRequirementsRegex(data.passwordRequirementsRegex || passwordRequirementsRegex);
@@ -153,6 +163,12 @@ function SettingsPage() {
153
163
  setMagicLinkExpiryHours(data.magicLinkExpiryHours || magicLinkExpiryHours);
154
164
  setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
155
165
  setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
166
+ setIncludeCredentialsInPasswordResetLink(
167
+ data.includeCredentialsInPasswordResetLink ?? includeCredentialsInPasswordResetLink
168
+ );
169
+ setIncludeCredentialsInVerificationLink(
170
+ data.includeCredentialsInVerificationLink ?? includeCredentialsInVerificationLink
171
+ );
156
172
  }
157
173
  setLoading(false);
158
174
  toggleNotification({
@@ -181,7 +197,9 @@ function SettingsPage() {
181
197
  magicLinkEmailSubject,
182
198
  magicLinkExpiryHours,
183
199
  emailVerificationUrl,
184
- emailVerificationEmailSubject
200
+ emailVerificationEmailSubject,
201
+ includeCredentialsInPasswordResetLink,
202
+ includeCredentialsInVerificationLink
185
203
  });
186
204
  if (data) {
187
205
  setEnableMagicLink(data.enableMagicLink || enableMagicLink);
@@ -218,11 +236,16 @@ function SettingsPage() {
218
236
  magicLinkEmailSubject,
219
237
  magicLinkExpiryHours,
220
238
  emailVerificationUrl,
221
- emailVerificationEmailSubject
239
+ emailVerificationEmailSubject,
240
+ includeCredentialsInPasswordResetLink,
241
+ includeCredentialsInVerificationLink
222
242
  });
223
243
  if (data) {
224
244
  setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
225
245
  setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
246
+ setIncludeCredentialsInVerificationLink(
247
+ data.includeCredentialsInVerificationLink ?? includeCredentialsInVerificationLink
248
+ );
226
249
  }
227
250
  setLoading(false);
228
251
  toggleNotification({
@@ -260,7 +283,9 @@ function SettingsPage() {
260
283
  magicLinkEmailSubject,
261
284
  magicLinkExpiryHours,
262
285
  emailVerificationUrl,
263
- emailVerificationEmailSubject
286
+ emailVerificationEmailSubject,
287
+ includeCredentialsInPasswordResetLink,
288
+ includeCredentialsInVerificationLink
264
289
  });
265
290
  if (!data || !data.firebase_config_json) {
266
291
  throw new Error("Invalid response from server");
@@ -295,7 +320,9 @@ function SettingsPage() {
295
320
  magicLinkEmailSubject,
296
321
  magicLinkExpiryHours,
297
322
  emailVerificationUrl,
298
- emailVerificationEmailSubject
323
+ emailVerificationEmailSubject,
324
+ includeCredentialsInPasswordResetLink,
325
+ includeCredentialsInVerificationLink
299
326
  });
300
327
  if (!data || !data.firebase_config_json) {
301
328
  throw new Error("Invalid response from server");
@@ -677,6 +704,20 @@ function SettingsPage() {
677
704
  }
678
705
  )
679
706
  ] }),
707
+ /* @__PURE__ */ jsxRuntime.jsxs(api.R, { marginBottom: 3, children: [
708
+ /* @__PURE__ */ jsxRuntime.jsx(api.E, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Include Login Credentials in Link" }),
709
+ /* @__PURE__ */ jsxRuntime.jsxs(api.T, { alignItems: "center", gap: 2, children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx(
711
+ api.D1,
712
+ {
713
+ name: "includeCredentialsInPasswordResetLink",
714
+ checked: includeCredentialsInPasswordResetLink,
715
+ onChange: (e) => setIncludeCredentialsInPasswordResetLink(e.target.checked)
716
+ }
717
+ ),
718
+ /* @__PURE__ */ jsxRuntime.jsx(api.E, { variant: "omega", textColor: "neutral600", children: "Append a Firebase custom token to the reset link, allowing users to be automatically logged in" })
719
+ ] })
720
+ ] }),
680
721
  /* @__PURE__ */ jsxRuntime.jsx(
681
722
  api.T,
682
723
  {
@@ -727,6 +768,20 @@ function SettingsPage() {
727
768
  }
728
769
  )
729
770
  ] }),
771
+ /* @__PURE__ */ jsxRuntime.jsxs(api.R, { marginBottom: 3, children: [
772
+ /* @__PURE__ */ jsxRuntime.jsx(api.E, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Include Login Credentials in Link" }),
773
+ /* @__PURE__ */ jsxRuntime.jsxs(api.T, { alignItems: "center", gap: 2, children: [
774
+ /* @__PURE__ */ jsxRuntime.jsx(
775
+ api.D1,
776
+ {
777
+ name: "includeCredentialsInVerificationLink",
778
+ checked: includeCredentialsInVerificationLink,
779
+ onChange: (e) => setIncludeCredentialsInVerificationLink(e.target.checked)
780
+ }
781
+ ),
782
+ /* @__PURE__ */ jsxRuntime.jsx(api.E, { variant: "omega", textColor: "neutral600", children: "Append a Firebase custom token to the verification link, allowing users to be automatically logged in" })
783
+ ] })
784
+ ] }),
730
785
  /* @__PURE__ */ jsxRuntime.jsx(
731
786
  api.T,
732
787
  {
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
- import { T, R, E, J as Jm, N as Nn, G as G0, I as Is, M as M1, D as D1, i as i1, t as t1, g as getFirebaseConfig, s as saveFirebaseConfig, f as delFirebaseConfig, j as savePasswordSettings } from "./api-NexSh9zC.mjs";
3
+ import { T, R, E, J as Jm, N as Nn, G as G0, I as Is, M as M1, D as D1, i as i1, t as t1, g as getFirebaseConfig, s as saveFirebaseConfig, f as delFirebaseConfig, j as savePasswordSettings } from "./api-CLQa5PFi.mjs";
4
4
  import { useNotification, Page } from "@strapi/strapi/admin";
5
5
  import { useNavigate } from "react-router-dom";
6
6
  function SettingsPage() {
@@ -23,6 +23,8 @@ function SettingsPage() {
23
23
  "http://localhost:3000/verify-email"
24
24
  );
25
25
  const [emailVerificationEmailSubject, setEmailVerificationEmailSubject] = useState("Verify Your Email");
26
+ const [includeCredentialsInPasswordResetLink, setIncludeCredentialsInPasswordResetLink] = useState(false);
27
+ const [includeCredentialsInVerificationLink, setIncludeCredentialsInVerificationLink] = useState(false);
26
28
  const [loading, setLoading] = useState(true);
27
29
  const [showEditModal, setShowEditModal] = useState(false);
28
30
  const [editWebApiKey, setEditWebApiKey] = useState("");
@@ -51,6 +53,8 @@ function SettingsPage() {
51
53
  setMagicLinkExpiryHours(data?.magicLinkExpiryHours || 1);
52
54
  setEmailVerificationUrl(data?.emailVerificationUrl || "http://localhost:3000/verify-email");
53
55
  setEmailVerificationEmailSubject(data?.emailVerificationEmailSubject || "Verify Your Email");
56
+ setIncludeCredentialsInPasswordResetLink(data?.includeCredentialsInPasswordResetLink || false);
57
+ setIncludeCredentialsInVerificationLink(data?.includeCredentialsInVerificationLink || false);
54
58
  }).catch((error) => {
55
59
  setLoading(false);
56
60
  console.error("Error retrieving Firebase config:", error);
@@ -78,6 +82,8 @@ function SettingsPage() {
78
82
  setMagicLinkExpiryHours(1);
79
83
  setEmailVerificationUrl("http://localhost:3000/verify-email");
80
84
  setEmailVerificationEmailSubject("Verify Your Email");
85
+ setIncludeCredentialsInPasswordResetLink(false);
86
+ setIncludeCredentialsInVerificationLink(false);
81
87
  setLoading(false);
82
88
  toggleNotification({
83
89
  type: "success",
@@ -105,7 +111,9 @@ function SettingsPage() {
105
111
  magicLinkEmailSubject,
106
112
  magicLinkExpiryHours,
107
113
  emailVerificationUrl,
108
- emailVerificationEmailSubject
114
+ emailVerificationEmailSubject,
115
+ includeCredentialsInPasswordResetLink,
116
+ includeCredentialsInVerificationLink
109
117
  });
110
118
  if (!data || !data.firebase_config_json) {
111
119
  throw new Error("Invalid response from server");
@@ -138,7 +146,9 @@ function SettingsPage() {
138
146
  magicLinkEmailSubject,
139
147
  magicLinkExpiryHours,
140
148
  emailVerificationUrl,
141
- emailVerificationEmailSubject
149
+ emailVerificationEmailSubject,
150
+ includeCredentialsInPasswordResetLink,
151
+ includeCredentialsInVerificationLink
142
152
  });
143
153
  if (data) {
144
154
  setPasswordRequirementsRegex(data.passwordRequirementsRegex || passwordRequirementsRegex);
@@ -151,6 +161,12 @@ function SettingsPage() {
151
161
  setMagicLinkExpiryHours(data.magicLinkExpiryHours || magicLinkExpiryHours);
152
162
  setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
153
163
  setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
164
+ setIncludeCredentialsInPasswordResetLink(
165
+ data.includeCredentialsInPasswordResetLink ?? includeCredentialsInPasswordResetLink
166
+ );
167
+ setIncludeCredentialsInVerificationLink(
168
+ data.includeCredentialsInVerificationLink ?? includeCredentialsInVerificationLink
169
+ );
154
170
  }
155
171
  setLoading(false);
156
172
  toggleNotification({
@@ -179,7 +195,9 @@ function SettingsPage() {
179
195
  magicLinkEmailSubject,
180
196
  magicLinkExpiryHours,
181
197
  emailVerificationUrl,
182
- emailVerificationEmailSubject
198
+ emailVerificationEmailSubject,
199
+ includeCredentialsInPasswordResetLink,
200
+ includeCredentialsInVerificationLink
183
201
  });
184
202
  if (data) {
185
203
  setEnableMagicLink(data.enableMagicLink || enableMagicLink);
@@ -216,11 +234,16 @@ function SettingsPage() {
216
234
  magicLinkEmailSubject,
217
235
  magicLinkExpiryHours,
218
236
  emailVerificationUrl,
219
- emailVerificationEmailSubject
237
+ emailVerificationEmailSubject,
238
+ includeCredentialsInPasswordResetLink,
239
+ includeCredentialsInVerificationLink
220
240
  });
221
241
  if (data) {
222
242
  setEmailVerificationUrl(data.emailVerificationUrl || emailVerificationUrl);
223
243
  setEmailVerificationEmailSubject(data.emailVerificationEmailSubject || emailVerificationEmailSubject);
244
+ setIncludeCredentialsInVerificationLink(
245
+ data.includeCredentialsInVerificationLink ?? includeCredentialsInVerificationLink
246
+ );
224
247
  }
225
248
  setLoading(false);
226
249
  toggleNotification({
@@ -258,7 +281,9 @@ function SettingsPage() {
258
281
  magicLinkEmailSubject,
259
282
  magicLinkExpiryHours,
260
283
  emailVerificationUrl,
261
- emailVerificationEmailSubject
284
+ emailVerificationEmailSubject,
285
+ includeCredentialsInPasswordResetLink,
286
+ includeCredentialsInVerificationLink
262
287
  });
263
288
  if (!data || !data.firebase_config_json) {
264
289
  throw new Error("Invalid response from server");
@@ -293,7 +318,9 @@ function SettingsPage() {
293
318
  magicLinkEmailSubject,
294
319
  magicLinkExpiryHours,
295
320
  emailVerificationUrl,
296
- emailVerificationEmailSubject
321
+ emailVerificationEmailSubject,
322
+ includeCredentialsInPasswordResetLink,
323
+ includeCredentialsInVerificationLink
297
324
  });
298
325
  if (!data || !data.firebase_config_json) {
299
326
  throw new Error("Invalid response from server");
@@ -675,6 +702,20 @@ function SettingsPage() {
675
702
  }
676
703
  )
677
704
  ] }),
705
+ /* @__PURE__ */ jsxs(R, { marginBottom: 3, children: [
706
+ /* @__PURE__ */ jsx(E, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Include Login Credentials in Link" }),
707
+ /* @__PURE__ */ jsxs(T, { alignItems: "center", gap: 2, children: [
708
+ /* @__PURE__ */ jsx(
709
+ D1,
710
+ {
711
+ name: "includeCredentialsInPasswordResetLink",
712
+ checked: includeCredentialsInPasswordResetLink,
713
+ onChange: (e) => setIncludeCredentialsInPasswordResetLink(e.target.checked)
714
+ }
715
+ ),
716
+ /* @__PURE__ */ jsx(E, { variant: "omega", textColor: "neutral600", children: "Append a Firebase custom token to the reset link, allowing users to be automatically logged in" })
717
+ ] })
718
+ ] }),
678
719
  /* @__PURE__ */ jsx(
679
720
  T,
680
721
  {
@@ -725,6 +766,20 @@ function SettingsPage() {
725
766
  }
726
767
  )
727
768
  ] }),
769
+ /* @__PURE__ */ jsxs(R, { marginBottom: 3, children: [
770
+ /* @__PURE__ */ jsx(E, { variant: "omega", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Include Login Credentials in Link" }),
771
+ /* @__PURE__ */ jsxs(T, { alignItems: "center", gap: 2, children: [
772
+ /* @__PURE__ */ jsx(
773
+ D1,
774
+ {
775
+ name: "includeCredentialsInVerificationLink",
776
+ checked: includeCredentialsInVerificationLink,
777
+ onChange: (e) => setIncludeCredentialsInVerificationLink(e.target.checked)
778
+ }
779
+ ),
780
+ /* @__PURE__ */ jsx(E, { variant: "omega", textColor: "neutral600", children: "Append a Firebase custom token to the verification link, allowing users to be automatically logged in" })
781
+ ] })
782
+ ] }),
728
783
  /* @__PURE__ */ jsx(
729
784
  T,
730
785
  {
@@ -2663,7 +2663,7 @@ const index = {
2663
2663
  id: `${PLUGIN_ID}.page.title`,
2664
2664
  defaultMessage: PLUGIN_ID
2665
2665
  },
2666
- Component: () => Promise.resolve().then(() => require("./App-Dg_AxJhA.js")).then((mod) => ({
2666
+ Component: () => Promise.resolve().then(() => require("./App-BmP-duLn.js")).then((mod) => ({
2667
2667
  default: mod.App
2668
2668
  })),
2669
2669
  permissions: PERMISSIONS["menu-link"]
@@ -2685,7 +2685,7 @@ const index = {
2685
2685
  id: "settings",
2686
2686
  to: `/settings/${PLUGIN_ID}`,
2687
2687
  async Component() {
2688
- const component = await Promise.resolve().then(() => require("./index-D41v41O3.js"));
2688
+ const component = await Promise.resolve().then(() => require("./index-B4ptk_Em.js"));
2689
2689
  return component.default;
2690
2690
  },
2691
2691
  permissions: PERMISSIONS["menu-link"]
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-ROJyqJld.js");
2
+ const index = require("../_chunks/index-CyOVjVQb.js");
3
3
  require("react/jsx-runtime");
4
4
  require("@strapi/strapi/admin");
5
5
  require("react-router-dom");
@@ -1,4 +1,4 @@
1
- import { B } from "../_chunks/index-B9spFspk.mjs";
1
+ import { B } from "../_chunks/index-B2NvsXdF.mjs";
2
2
  import "react/jsx-runtime";
3
3
  import "@strapi/strapi/admin";
4
4
  import "react-router-dom";
@@ -10,6 +10,8 @@ export declare const saveFirebaseConfig: (json: string, firebaseWebApiKey?: stri
10
10
  magicLinkExpiryHours?: number;
11
11
  emailVerificationUrl?: string;
12
12
  emailVerificationEmailSubject?: string;
13
+ includeCredentialsInPasswordResetLink?: boolean;
14
+ includeCredentialsInVerificationLink?: boolean;
13
15
  }) => Promise<any>;
14
16
  export declare const getFirebaseConfig: () => Promise<any>;
15
17
  export declare const delFirebaseConfig: () => Promise<any>;
@@ -24,4 +26,6 @@ export declare const savePasswordSettings: (passwordConfig: {
24
26
  magicLinkExpiryHours?: number;
25
27
  emailVerificationUrl?: string;
26
28
  emailVerificationEmailSubject?: string;
29
+ includeCredentialsInPasswordResetLink?: boolean;
30
+ includeCredentialsInVerificationLink?: boolean;
27
31
  }) => Promise<any>;
@@ -330,6 +330,16 @@ const attributes$1 = {
330
330
  emailVerificationEmailSubject: {
331
331
  type: "string",
332
332
  "default": "Verify Your Email"
333
+ },
334
+ includeCredentialsInPasswordResetLink: {
335
+ type: "boolean",
336
+ "default": false,
337
+ description: "Include Firebase custom token in password reset links for auto-login"
338
+ },
339
+ includeCredentialsInVerificationLink: {
340
+ type: "boolean",
341
+ "default": false,
342
+ description: "Include Firebase custom token in email verification links for auto-login"
333
343
  }
334
344
  };
335
345
  const firebaseAuthenticationConfiguration = {
@@ -28994,6 +29004,29 @@ const firebaseController = {
28994
29004
  }
28995
29005
  throw error2;
28996
29006
  }
29007
+ },
29008
+ /**
29009
+ * Check password - validates a password against the authenticated user's Firebase account
29010
+ * POST /api/firebase-authentication/checkPassword
29011
+ * Authenticated endpoint - requires valid JWT (enforced by is-authenticated policy)
29012
+ *
29013
+ * @param ctx - Koa context with { password } in body
29014
+ * @returns { valid: true } or { valid: false }
29015
+ */
29016
+ async checkPassword(ctx) {
29017
+ strapi.log.debug("checkPassword endpoint called");
29018
+ try {
29019
+ const { password } = ctx.request.body || {};
29020
+ const user = ctx.state.user;
29021
+ if (!password) {
29022
+ throw new ValidationError$1("Password is required");
29023
+ }
29024
+ const result = await strapi.plugin(pluginName).service("firebaseService").checkPassword(user, password);
29025
+ ctx.body = result;
29026
+ } catch (error2) {
29027
+ strapi.log.error("checkPassword controller error:", error2);
29028
+ throw error2;
29029
+ }
28997
29030
  }
28998
29031
  };
28999
29032
  const STRAPI_DESTINATION = "strapi";
@@ -29196,7 +29229,9 @@ const settingsController = {
29196
29229
  magicLinkEmailSubject = "Sign in to Your Application",
29197
29230
  magicLinkExpiryHours = 1,
29198
29231
  emailVerificationUrl = "http://localhost:3000/verify-email",
29199
- emailVerificationEmailSubject = "Verify Your Email"
29232
+ emailVerificationEmailSubject = "Verify Your Email",
29233
+ includeCredentialsInPasswordResetLink = false,
29234
+ includeCredentialsInVerificationLink = false
29200
29235
  } = requestBody;
29201
29236
  const existingConfig = await strapi.db.query("plugin::firebase-authentication.firebase-authentication-configuration").findOne({ where: {} });
29202
29237
  let result;
@@ -29212,7 +29247,9 @@ const settingsController = {
29212
29247
  magicLinkEmailSubject,
29213
29248
  magicLinkExpiryHours,
29214
29249
  emailVerificationUrl,
29215
- emailVerificationEmailSubject
29250
+ emailVerificationEmailSubject,
29251
+ includeCredentialsInPasswordResetLink,
29252
+ includeCredentialsInVerificationLink
29216
29253
  }
29217
29254
  });
29218
29255
  } else {
@@ -29228,7 +29265,9 @@ const settingsController = {
29228
29265
  magicLinkEmailSubject,
29229
29266
  magicLinkExpiryHours,
29230
29267
  emailVerificationUrl,
29231
- emailVerificationEmailSubject
29268
+ emailVerificationEmailSubject,
29269
+ includeCredentialsInPasswordResetLink,
29270
+ includeCredentialsInVerificationLink
29232
29271
  }
29233
29272
  });
29234
29273
  }
@@ -29242,7 +29281,9 @@ const settingsController = {
29242
29281
  magicLinkEmailSubject: result.magicLinkEmailSubject,
29243
29282
  magicLinkExpiryHours: result.magicLinkExpiryHours,
29244
29283
  emailVerificationUrl: result.emailVerificationUrl,
29245
- emailVerificationEmailSubject: result.emailVerificationEmailSubject
29284
+ emailVerificationEmailSubject: result.emailVerificationEmailSubject,
29285
+ includeCredentialsInPasswordResetLink: result.includeCredentialsInPasswordResetLink,
29286
+ includeCredentialsInVerificationLink: result.includeCredentialsInVerificationLink
29246
29287
  };
29247
29288
  } catch (error2) {
29248
29289
  throw new ApplicationError$2("Error saving password configuration", {
@@ -29466,6 +29507,14 @@ const contentApi = {
29466
29507
  // Public endpoint - token provides authentication
29467
29508
  policies: []
29468
29509
  }
29510
+ },
29511
+ {
29512
+ method: "POST",
29513
+ path: "/checkPassword",
29514
+ handler: "firebaseController.checkPassword",
29515
+ config: {
29516
+ policies: ["plugin::firebase-authentication.is-authenticated"]
29517
+ }
29469
29518
  }
29470
29519
  ]
29471
29520
  };
@@ -29589,7 +29638,10 @@ const settingsService = ({ strapi: strapi2 }) => {
29589
29638
  magicLinkExpiryHours: configObject.magicLinkExpiryHours || 1,
29590
29639
  // Include email verification configuration fields
29591
29640
  emailVerificationUrl: configObject.emailVerificationUrl || "http://localhost:3000/verify-email",
29592
- emailVerificationEmailSubject: configObject.emailVerificationEmailSubject || "Verify Your Email"
29641
+ emailVerificationEmailSubject: configObject.emailVerificationEmailSubject || "Verify Your Email",
29642
+ // Include credentials in link settings
29643
+ includeCredentialsInPasswordResetLink: configObject.includeCredentialsInPasswordResetLink || false,
29644
+ includeCredentialsInVerificationLink: configObject.includeCredentialsInVerificationLink || false
29593
29645
  };
29594
29646
  } catch (error2) {
29595
29647
  strapi2.log.error(`Firebase config error: ${error2.message}`);
@@ -29634,7 +29686,9 @@ const settingsService = ({ strapi: strapi2 }) => {
29634
29686
  magicLinkEmailSubject = "Sign in to Your Application",
29635
29687
  magicLinkExpiryHours = 1,
29636
29688
  emailVerificationUrl = "http://localhost:3000/verify-email",
29637
- emailVerificationEmailSubject = "Verify Your Email"
29689
+ emailVerificationEmailSubject = "Verify Your Email",
29690
+ includeCredentialsInPasswordResetLink = false,
29691
+ includeCredentialsInVerificationLink = false
29638
29692
  } = requestBody;
29639
29693
  if (!requestBody) throw new ValidationError3(ERROR_MESSAGES.MISSING_DATA);
29640
29694
  try {
@@ -29672,7 +29726,9 @@ const settingsService = ({ strapi: strapi2 }) => {
29672
29726
  magicLinkEmailSubject,
29673
29727
  magicLinkExpiryHours,
29674
29728
  emailVerificationUrl,
29675
- emailVerificationEmailSubject
29729
+ emailVerificationEmailSubject,
29730
+ includeCredentialsInPasswordResetLink,
29731
+ includeCredentialsInVerificationLink
29676
29732
  }
29677
29733
  });
29678
29734
  } else {
@@ -29690,7 +29746,9 @@ const settingsService = ({ strapi: strapi2 }) => {
29690
29746
  magicLinkEmailSubject,
29691
29747
  magicLinkExpiryHours,
29692
29748
  emailVerificationUrl,
29693
- emailVerificationEmailSubject
29749
+ emailVerificationEmailSubject,
29750
+ includeCredentialsInPasswordResetLink,
29751
+ includeCredentialsInVerificationLink
29694
29752
  }
29695
29753
  });
29696
29754
  }
@@ -29727,6 +29785,8 @@ const settingsService = ({ strapi: strapi2 }) => {
29727
29785
  res.magicLinkExpiryHours = res.magicLinkExpiryHours || magicLinkExpiryHours;
29728
29786
  res.emailVerificationUrl = res.emailVerificationUrl || emailVerificationUrl;
29729
29787
  res.emailVerificationEmailSubject = res.emailVerificationEmailSubject || emailVerificationEmailSubject;
29788
+ res.includeCredentialsInPasswordResetLink = res.includeCredentialsInPasswordResetLink ?? includeCredentialsInPasswordResetLink;
29789
+ res.includeCredentialsInVerificationLink = res.includeCredentialsInVerificationLink ?? includeCredentialsInVerificationLink;
29730
29790
  return res;
29731
29791
  } catch (error2) {
29732
29792
  strapi2.log.error("=== FIREBASE CONFIG SAVE ERROR ===");
@@ -30927,7 +30987,16 @@ const firebaseService = ({ strapi: strapi2 }) => ({
30927
30987
  );
30928
30988
  const tokenService2 = strapi2.plugin("firebase-authentication").service("tokenService");
30929
30989
  const token = await tokenService2.generateResetToken(firebaseData.documentId);
30930
- const resetLink = `${resetUrl}?token=${token}`;
30990
+ let resetLink = `${resetUrl}?token=${token}`;
30991
+ if (config2?.includeCredentialsInPasswordResetLink) {
30992
+ try {
30993
+ const customToken = await strapi2.firebase.auth().createCustomToken(firebaseUser.uid);
30994
+ resetLink = `${resetLink}&fjwt=${customToken}`;
30995
+ strapi2.log.info(`[forgotPassword] Added Firebase custom token to reset link`);
30996
+ } catch (tokenError) {
30997
+ strapi2.log.warn(`[forgotPassword] Could not generate custom token: ${tokenError.message}`);
30998
+ }
30999
+ }
30931
31000
  strapi2.log.info(`✅ [forgotPassword] Custom reset link generated for ${email2}`);
30932
31001
  strapi2.log.info(`[forgotPassword] Attempting to send password reset email to: ${email2}`);
30933
31002
  await strapi2.plugin("firebase-authentication").service("emailService").sendPasswordResetEmail(firebaseUser, resetLink);
@@ -31152,7 +31221,16 @@ const firebaseService = ({ strapi: strapi2 }) => ({
31152
31221
  );
31153
31222
  const tokenService2 = strapi2.plugin("firebase-authentication").service("tokenService");
31154
31223
  const token = await tokenService2.generateVerificationToken(firebaseData.documentId, email2);
31155
- const verificationLink = `${verificationUrl}?token=${token}`;
31224
+ let verificationLink = `${verificationUrl}?token=${token}`;
31225
+ if (config2?.includeCredentialsInVerificationLink) {
31226
+ try {
31227
+ const customToken = await strapi2.firebase.auth().createCustomToken(firebaseUser.uid);
31228
+ verificationLink = `${verificationLink}&fjwt=${customToken}`;
31229
+ strapi2.log.info(`[sendVerificationEmail] Added Firebase custom token to verification link`);
31230
+ } catch (tokenError) {
31231
+ strapi2.log.warn(`[sendVerificationEmail] Could not generate custom token: ${tokenError.message}`);
31232
+ }
31233
+ }
31156
31234
  strapi2.log.info(`✅ [sendVerificationEmail] Verification link generated for ${email2}`);
31157
31235
  strapi2.log.info(`[sendVerificationEmail] Attempting to send verification email to: ${email2}`);
31158
31236
  await strapi2.plugin("firebase-authentication").service("emailService").sendVerificationEmail(firebaseUser, verificationLink);
@@ -31264,6 +31342,54 @@ const firebaseService = ({ strapi: strapi2 }) => ({
31264
31342
  }
31265
31343
  throw new ApplicationError$2("Failed to verify email. Please try again.");
31266
31344
  }
31345
+ },
31346
+ /**
31347
+ * Check if a password is valid for the authenticated user
31348
+ * Uses Firebase Identity Toolkit API to verify the password
31349
+ *
31350
+ * @param user - Authenticated user from ctx.state.user
31351
+ * @param password - Password to check
31352
+ * @returns { valid: true } or { valid: false }
31353
+ */
31354
+ async checkPassword(user, password) {
31355
+ if (!user || !user.email) {
31356
+ throw new ValidationError$1("User email is required");
31357
+ }
31358
+ const config2 = await strapi2.plugin("firebase-authentication").service("settingsService").getFirebaseConfigJson();
31359
+ if (!config2 || !config2.firebaseWebApiKey) {
31360
+ throw new ApplicationError$2(
31361
+ "Password verification is not available. Web API Key is not configured.\n\nTo enable password verification:\n1. Go to Firebase Console > Project Settings > General\n2. Copy your Web API Key\n3. Add it in Strapi Admin > Settings > Firebase Authentication > Optional Settings"
31362
+ );
31363
+ }
31364
+ try {
31365
+ const response = await fetch(
31366
+ `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${config2.firebaseWebApiKey}`,
31367
+ {
31368
+ method: "POST",
31369
+ headers: {
31370
+ "Content-Type": "application/json"
31371
+ },
31372
+ body: JSON.stringify({
31373
+ email: user.email,
31374
+ password,
31375
+ returnSecureToken: false
31376
+ })
31377
+ }
31378
+ );
31379
+ const data = await response.json();
31380
+ if (!response.ok) {
31381
+ const errorMessage = data.error?.message || "Authentication failed";
31382
+ strapi2.log.debug(`checkPassword: password invalid for user ${user.email}: ${errorMessage}`);
31383
+ if (errorMessage === "INVALID_PASSWORD" || errorMessage === "INVALID_LOGIN_CREDENTIALS" || errorMessage.includes("INVALID")) {
31384
+ return { valid: false };
31385
+ }
31386
+ return { valid: false };
31387
+ }
31388
+ return { valid: true };
31389
+ } catch (error2) {
31390
+ strapi2.log.error("checkPassword error:", error2);
31391
+ throw new ApplicationError$2("Failed to verify password");
31392
+ }
31267
31393
  }
31268
31394
  });
31269
31395
  const passwordResetTemplate = {