@stackframe/stack 2.5.17 → 2.5.19

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 (108) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/credential-sign-in.js +4 -1
  3. package/dist/components/credential-sign-in.js.map +1 -1
  4. package/dist/components/elements/sidebar-layout.d.mts +21 -0
  5. package/dist/components/elements/sidebar-layout.d.ts +21 -0
  6. package/dist/components/elements/sidebar-layout.js +125 -0
  7. package/dist/components/elements/sidebar-layout.js.map +1 -0
  8. package/dist/components/elements/user-avatar.d.mts +5 -11
  9. package/dist/components/elements/user-avatar.d.ts +5 -11
  10. package/dist/components/elements/user-avatar.js.map +1 -1
  11. package/dist/components/message-cards/predefined-message-card.d.mts +1 -1
  12. package/dist/components/message-cards/predefined-message-card.d.ts +1 -1
  13. package/dist/components/message-cards/predefined-message-card.js +8 -0
  14. package/dist/components/message-cards/predefined-message-card.js.map +1 -1
  15. package/dist/components/selected-team-switcher.d.mts +1 -0
  16. package/dist/components/selected-team-switcher.d.ts +1 -0
  17. package/dist/components/selected-team-switcher.js +35 -5
  18. package/dist/components/selected-team-switcher.js.map +1 -1
  19. package/dist/components-page/account-settings.js +123 -31
  20. package/dist/components-page/account-settings.js.map +1 -1
  21. package/dist/components-page/auth-page.d.mts +1 -0
  22. package/dist/components-page/auth-page.d.ts +1 -0
  23. package/dist/components-page/auth-page.js +4 -1
  24. package/dist/components-page/auth-page.js.map +1 -1
  25. package/dist/components-page/forgot-password.d.mts +4 -1
  26. package/dist/components-page/forgot-password.d.ts +4 -1
  27. package/dist/components-page/forgot-password.js +55 -7
  28. package/dist/components-page/forgot-password.js.map +1 -1
  29. package/dist/components-page/password-reset.d.mts +6 -2
  30. package/dist/components-page/password-reset.d.ts +6 -2
  31. package/dist/components-page/password-reset.js +100 -8
  32. package/dist/components-page/password-reset.js.map +1 -1
  33. package/dist/components-page/stack-handler.d.mts +1 -0
  34. package/dist/components-page/stack-handler.d.ts +1 -0
  35. package/dist/components-page/stack-handler.js +32 -6
  36. package/dist/components-page/stack-handler.js.map +1 -1
  37. package/dist/{components/password-reset-form.d.mts → components-page/team-creation.d.mts} +2 -3
  38. package/dist/{components/password-reset-form.d.ts → components-page/team-creation.d.ts} +2 -3
  39. package/dist/components-page/team-creation.js +92 -0
  40. package/dist/components-page/team-creation.js.map +1 -0
  41. package/dist/components-page/team-invitation.d.mts +8 -0
  42. package/dist/components-page/team-invitation.d.ts +8 -0
  43. package/dist/components-page/team-invitation.js +141 -0
  44. package/dist/components-page/team-invitation.js.map +1 -0
  45. package/dist/components-page/team-settings.d.mts +8 -0
  46. package/dist/components-page/team-settings.d.ts +8 -0
  47. package/dist/components-page/team-settings.js +139 -0
  48. package/dist/components-page/team-settings.js.map +1 -0
  49. package/dist/esm/components/credential-sign-in.js +4 -1
  50. package/dist/esm/components/credential-sign-in.js.map +1 -1
  51. package/dist/esm/components/elements/sidebar-layout.js +90 -0
  52. package/dist/esm/components/elements/sidebar-layout.js.map +1 -0
  53. package/dist/esm/components/elements/user-avatar.js.map +1 -1
  54. package/dist/esm/components/message-cards/predefined-message-card.js +8 -0
  55. package/dist/esm/components/message-cards/predefined-message-card.js.map +1 -1
  56. package/dist/esm/components/selected-team-switcher.js +39 -7
  57. package/dist/esm/components/selected-team-switcher.js.map +1 -1
  58. package/dist/esm/components-page/account-settings.js +114 -32
  59. package/dist/esm/components-page/account-settings.js.map +1 -1
  60. package/dist/esm/components-page/auth-page.js +4 -1
  61. package/dist/esm/components-page/auth-page.js.map +1 -1
  62. package/dist/esm/components-page/forgot-password.js +52 -5
  63. package/dist/esm/components-page/forgot-password.js.map +1 -1
  64. package/dist/esm/components-page/password-reset.js +101 -9
  65. package/dist/esm/components-page/password-reset.js.map +1 -1
  66. package/dist/esm/components-page/stack-handler.js +32 -6
  67. package/dist/esm/components-page/stack-handler.js.map +1 -1
  68. package/dist/esm/components-page/team-creation.js +68 -0
  69. package/dist/esm/components-page/team-creation.js.map +1 -0
  70. package/dist/esm/components-page/team-invitation.js +107 -0
  71. package/dist/esm/components-page/team-invitation.js.map +1 -0
  72. package/dist/esm/components-page/team-settings.js +115 -0
  73. package/dist/esm/components-page/team-settings.js.map +1 -0
  74. package/dist/esm/generated/global-css.js +1 -1
  75. package/dist/esm/generated/global-css.js.map +1 -1
  76. package/dist/esm/lib/auth.js +5 -1
  77. package/dist/esm/lib/auth.js.map +1 -1
  78. package/dist/esm/lib/stack-app.js +272 -25
  79. package/dist/esm/lib/stack-app.js.map +1 -1
  80. package/dist/generated/global-css.d.mts +1 -1
  81. package/dist/generated/global-css.d.ts +1 -1
  82. package/dist/generated/global-css.js +1 -1
  83. package/dist/generated/global-css.js.map +1 -1
  84. package/dist/index.d.mts +2 -1
  85. package/dist/index.d.ts +2 -1
  86. package/dist/lib/auth.js +5 -1
  87. package/dist/lib/auth.js.map +1 -1
  88. package/dist/lib/hooks.d.mts +1 -0
  89. package/dist/lib/hooks.d.ts +1 -0
  90. package/dist/lib/stack-app.d.mts +64 -5
  91. package/dist/lib/stack-app.d.ts +64 -5
  92. package/dist/lib/stack-app.js +272 -25
  93. package/dist/lib/stack-app.js.map +1 -1
  94. package/dist/providers/stack-provider-client.d.mts +1 -0
  95. package/dist/providers/stack-provider-client.d.ts +1 -0
  96. package/dist/providers/stack-provider.d.mts +1 -0
  97. package/dist/providers/stack-provider.d.ts +1 -0
  98. package/package.json +10 -6
  99. package/dist/components/forgot-password-form.d.mts +0 -7
  100. package/dist/components/forgot-password-form.d.ts +0 -7
  101. package/dist/components/forgot-password-form.js +0 -83
  102. package/dist/components/forgot-password-form.js.map +0 -1
  103. package/dist/components/password-reset-form.js +0 -135
  104. package/dist/components/password-reset-form.js.map +0 -1
  105. package/dist/esm/components/forgot-password-form.js +0 -59
  106. package/dist/esm/components/forgot-password-form.js.map +0 -1
  107. package/dist/esm/components/password-reset-form.js +0 -105
  108. package/dist/esm/components/password-reset-form.js.map +0 -1
@@ -1,9 +1,11 @@
1
1
  "use client";
2
2
  "use strict";
3
3
  "use client";
4
+ var __create = Object.create;
4
5
  var __defProp = Object.defineProperty;
5
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
7
9
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
10
  var __export = (target, all) => {
9
11
  for (var name in all)
@@ -17,6 +19,14 @@ var __copyProps = (to, from, except, desc) => {
17
19
  }
18
20
  return to;
19
21
  };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
20
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
31
 
22
32
  // src/components-page/account-settings.tsx
@@ -25,14 +35,44 @@ __export(account_settings_exports, {
25
35
  AccountSettings: () => AccountSettings
26
36
  });
27
37
  module.exports = __toCommonJS(account_settings_exports);
28
- var import__ = require("..");
29
- var import_predefined_message_card = require("../components/message-cards/predefined-message-card");
30
- var import_user_avatar = require("../components/elements/user-avatar");
31
- var import_react = require("react");
32
- var import_form_warning = require("../components/elements/form-warning");
33
38
  var import_password = require("@stackframe/stack-shared/dist/helpers/password");
39
+ var import_use_async_callback = require("@stackframe/stack-shared/dist/hooks/use-async-callback");
40
+ var import_crypto = require("@stackframe/stack-shared/dist/utils/crypto");
41
+ var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
42
+ var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
34
43
  var import_stack_ui = require("@stackframe/stack-ui");
44
+ var import_lucide_react = require("lucide-react");
45
+ var import_otp = require("oslo/otp");
46
+ var QRCode = __toESM(require("qrcode"));
47
+ var import_react = require("react");
48
+ var import__ = require("..");
49
+ var import_form_warning = require("../components/elements/form-warning");
50
+ var import_sidebar_layout = require("../components/elements/sidebar-layout");
51
+ var import_user_avatar = require("../components/elements/user-avatar");
35
52
  var import_jsx_runtime = require("react/jsx-runtime");
53
+ function AccountSettings({ fullPage = false }) {
54
+ const user = (0, import__.useUser)({ or: "redirect" });
55
+ const inner = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56
+ import_sidebar_layout.SidebarLayout,
57
+ {
58
+ items: [
59
+ { title: "My Profile", content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProfileSection, {}), icon: import_lucide_react.Contact },
60
+ { title: "Security", content: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4", children: [
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmailVerificationSection, {}),
62
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasswordSection, {}),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MfaSection, {})
64
+ ] }), icon: import_lucide_react.ShieldCheck },
65
+ { title: "Settings", content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SignOutSection, {}), icon: import_lucide_react.Settings }
66
+ ].filter(({ content }) => content),
67
+ title: "Team Settings"
68
+ }
69
+ );
70
+ if (fullPage) {
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Container, { size: 800, className: "stack-scope", children: inner });
72
+ } else {
73
+ return inner;
74
+ }
75
+ }
36
76
  function SettingSection(props) {
37
77
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Card, { children: [
38
78
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
@@ -106,12 +146,12 @@ function EmailVerificationSection() {
106
146
  await user?.sendVerificationEmail();
107
147
  setEmailSent(true);
108
148
  },
109
- children: user?.primaryEmailVerified ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Your email has been verified" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Your email has not been verified" })
149
+ children: user?.primaryEmailVerified ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Your email has been verified." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Your email has not been verified." })
110
150
  }
111
151
  );
112
152
  }
113
153
  function PasswordSection() {
114
- const user = (0, import__.useUser)();
154
+ const user = (0, import__.useUser)({ or: "throw" });
115
155
  const [oldPassword, setOldPassword] = (0, import_react.useState)("");
116
156
  const [oldPasswordError, setOldPasswordError] = (0, import_react.useState)("");
117
157
  const [newPassword, setNewPassword] = (0, import_react.useState)("");
@@ -119,7 +159,7 @@ function PasswordSection() {
119
159
  const [repeatNewPassword, setRepeatNewPassword] = (0, import_react.useState)("");
120
160
  const [repeatNewPasswordError, setRepeatNewPasswordError] = (0, import_react.useState)("");
121
161
  const [passwordChanged, setPasswordChanged] = (0, import_react.useState)(false);
122
- if (!user?.hasPassword) {
162
+ if (!user.hasPassword) {
123
163
  return null;
124
164
  }
125
165
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -216,8 +256,81 @@ function PasswordSection() {
216
256
  }
217
257
  );
218
258
  }
259
+ function MfaSection() {
260
+ const project = (0, import__.useStackApp)().useProject();
261
+ const user = (0, import__.useUser)({ or: "throw" });
262
+ const [generatedSecret, setGeneratedSecret] = (0, import_react.useState)(null);
263
+ const [qrCodeUrl, setQrCodeUrl] = (0, import_react.useState)(null);
264
+ const [mfaCode, setMfaCode] = (0, import_react.useState)("");
265
+ const [isMaybeWrong, setIsMaybeWrong] = (0, import_react.useState)(false);
266
+ const isEnabled = user.isMultiFactorRequired;
267
+ const [handleSubmit, isLoading] = (0, import_use_async_callback.useAsyncCallback)(async () => {
268
+ await user.update({
269
+ totpMultiFactorSecret: generatedSecret
270
+ });
271
+ setGeneratedSecret(null);
272
+ setQrCodeUrl(null);
273
+ setMfaCode("");
274
+ }, [generatedSecret, user]);
275
+ (0, import_react.useEffect)(() => {
276
+ setIsMaybeWrong(false);
277
+ (0, import_promises.runAsynchronouslyWithAlert)(async () => {
278
+ if (generatedSecret && await new import_otp.TOTPController().verify(mfaCode, generatedSecret)) {
279
+ await handleSubmit();
280
+ }
281
+ setIsMaybeWrong(true);
282
+ });
283
+ }, [mfaCode, generatedSecret, handleSubmit]);
284
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
285
+ SettingSection,
286
+ {
287
+ title: "Multi-factor Authentication",
288
+ desc: "Secure your account with an additional layer of security.",
289
+ buttonVariant: "secondary",
290
+ buttonText: isEnabled ? "Disable" : generatedSecret ? "Cancel" : "Enable",
291
+ onButtonClick: async () => {
292
+ if (isEnabled) {
293
+ await user.update({
294
+ totpMultiFactorSecret: null
295
+ });
296
+ } else if (!generatedSecret) {
297
+ const secret = (0, import_crypto.generateRandomValues)(new Uint8Array(20));
298
+ setQrCodeUrl(await generateTotpQrCode(project, user, secret));
299
+ setGeneratedSecret(secret);
300
+ } else {
301
+ setGeneratedSecret(null);
302
+ setQrCodeUrl(null);
303
+ setMfaCode("");
304
+ }
305
+ },
306
+ children: isEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Multi-factor authentication is currently enabled." }) : generatedSecret ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 items-center", children: [
307
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: "Scan this QR code with your authenticator app:" }),
308
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { width: 200, height: 200, src: qrCodeUrl ?? (0, import_errors.throwErr)("TOTP QR code failed to generate"), alt: "TOTP multi-factor authentication QR code" }),
309
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: "Then, enter your six-digit MFA code:" }),
310
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
311
+ import_stack_ui.Input,
312
+ {
313
+ value: mfaCode,
314
+ onChange: (e) => {
315
+ setIsMaybeWrong(false);
316
+ setMfaCode(e.target.value);
317
+ },
318
+ placeholder: "123456",
319
+ maxLength: 6,
320
+ disabled: isLoading
321
+ }
322
+ ),
323
+ isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Incorrect code. Please try again." })
324
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Multi-factor authentication is currently disabled." })
325
+ }
326
+ );
327
+ }
328
+ async function generateTotpQrCode(project, user, secret) {
329
+ const uri = (0, import_otp.createTOTPKeyURI)(project.displayName, user.primaryEmail ?? user.id, secret);
330
+ return await QRCode.toDataURL(uri);
331
+ }
219
332
  function SignOutSection() {
220
- const user = (0, import__.useUser)();
333
+ const user = (0, import__.useUser)({ or: "throw" });
221
334
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
222
335
  SettingSection,
223
336
  {
@@ -225,31 +338,10 @@ function SignOutSection() {
225
338
  desc: "Sign out of your account on this device.",
226
339
  buttonVariant: "secondary",
227
340
  buttonText: "Sign Out",
228
- onButtonClick: () => user?.signOut()
341
+ onButtonClick: () => user.signOut()
229
342
  }
230
343
  );
231
344
  }
232
- function AccountSettings({ fullPage = false }) {
233
- const user = (0, import__.useUser)();
234
- if (!user) {
235
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_predefined_message_card.PredefinedMessageCard, { type: "signedOut", fullPage });
236
- }
237
- const inner = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_stack_ui.cn)(fullPage ? "p-4" : "", "flex flex-col gap-4"), children: [
238
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
239
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { type: "h2", children: "Account Settings" }),
240
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "label", children: "Manage your account" })
241
- ] }),
242
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProfileSection, {}),
243
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmailVerificationSection, {}),
244
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasswordSection, {}),
245
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SignOutSection, {})
246
- ] });
247
- if (fullPage) {
248
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Container, { size: 600, className: "stack-scope", children: inner });
249
- } else {
250
- return inner;
251
- }
252
- }
253
345
  // Annotate the CommonJS export names for ESM import in node:
254
346
  0 && (module.exports = {
255
347
  AccountSettings
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components-page/account-settings.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport { useUser } from '..';\nimport { PredefinedMessageCard } from '../components/message-cards/predefined-message-card';\nimport { UserAvatar } from '../components/elements/user-avatar';\nimport { useState } from 'react';\nimport { FormWarningText } from '../components/elements/form-warning';\nimport { getPasswordError } from '@stackframe/stack-shared/dist/helpers/password';\nimport { Button, Card, CardContent, CardFooter, CardHeader, Container, Input, Label, PasswordInput, Typography, cn } from '@stackframe/stack-ui';\n\nfunction SettingSection(props: {\n title: string,\n desc: string,\n buttonText?: string,\n buttonDisabled?: boolean,\n onButtonClick?: React.ComponentProps<typeof Button>[\"onClick\"],\n buttonVariant?: 'default' | 'secondary',\n children?: React.ReactNode,\n}) {\n return (\n <Card>\n <CardHeader>\n <div>\n <Typography type='h4'>{props.title}</Typography>\n <Typography type='label' variant='secondary'>{props.desc}</Typography>\n </div>\n </CardHeader>\n {props.children && <CardContent>\n <div className='flex flex-col gap-4'>\n {props.children}\n </div>\n </CardContent>}\n {props.buttonText && <CardFooter>\n <div className='flex justify-end w-full'>\n <Button\n disabled={props.buttonDisabled}\n onClick={props.onButtonClick}\n variant={props.buttonVariant}\n >\n {props.buttonText}\n </Button>\n </div>\n </CardFooter>}\n </Card>\n );\n}\n\nfunction ProfileSection() {\n const user = useUser()!;\n const [userInfo, setUserInfo] = useState<{ displayName: string }>({ displayName: user.displayName || '' });\n const [changed, setChanged] = useState(false);\n\n return (\n <SettingSection\n title='Profile'\n desc='Your profile information'\n buttonDisabled={!changed}\n buttonText='Save'\n onButtonClick={async () => {\n await user.update(userInfo);\n setChanged(false);\n }}\n >\n <div className='flex gap-4 items-center'>\n <UserAvatar user={user} size={50}/>\n <div className='flex flex-col'>\n <Typography>{user.displayName}</Typography>\n <Typography variant='secondary' type='label'>{user.primaryEmail}</Typography>\n </div>\n </div>\n\n <div className='flex flex-col'>\n <Label htmlFor='display-name' className='mb-1'>Display Name</Label>\n <Input\n id='display-name'\n value={userInfo.displayName}\n onChange={(e) => {\n setUserInfo((i) => ({...i, displayName: e.target.value }));\n setChanged(true);\n }}\n />\n </div>\n </SettingSection>\n );\n}\n\nfunction EmailVerificationSection() {\n const user = useUser();\n const [emailSent, setEmailSent] = useState(false);\n\n return (\n <SettingSection\n title='Email Verification'\n desc='We want to make sure that you own the email address.'\n buttonDisabled={emailSent}\n buttonText={\n !user?.primaryEmailVerified ?\n emailSent ?\n 'Email sent!' :\n 'Send Email'\n : undefined\n }\n onButtonClick={async () => {\n await user?.sendVerificationEmail();\n setEmailSent(true);\n }}\n >\n {user?.primaryEmailVerified ?\n <Typography variant='success'>Your email has been verified</Typography> :\n <Typography variant='destructive'>Your email has not been verified</Typography>}\n </SettingSection>\n );\n}\n\nfunction PasswordSection() {\n const user = useUser();\n const [oldPassword, setOldPassword] = useState<string>('');\n const [oldPasswordError, setOldPasswordError] = useState<string>('');\n const [newPassword, setNewPassword] = useState<string>('');\n const [newPasswordError, setNewPasswordError] = useState<string>('');\n const [repeatNewPassword, setRepeatNewPassword] = useState<string>('');\n const [repeatNewPasswordError, setRepeatNewPasswordError] = useState<string>('');\n const [passwordChanged, setPasswordChanged] = useState(false);\n\n if (!user?.hasPassword) {\n return null;\n }\n\n return (\n <SettingSection\n title='Password'\n desc='Change your password here.'\n buttonDisabled={passwordChanged || (!oldPassword && !newPassword && !repeatNewPassword)}\n buttonText={passwordChanged ? \"Password changed!\" : 'Update Password'}\n onButtonClick={async () => {\n setOldPasswordError('');\n setNewPasswordError('');\n setRepeatNewPasswordError('');\n if (!oldPassword) {\n setOldPasswordError('Please enter your old password');\n return;\n } else if (!newPassword) {\n setNewPasswordError('Please enter a new password');\n return;\n } else if (!repeatNewPassword) {\n setRepeatNewPasswordError('Please repeat your new password');\n return;\n } else {\n const errorMessage = getPasswordError(newPassword);\n if (errorMessage) {\n setNewPasswordError(errorMessage.message);\n } else {\n if (newPassword !== repeatNewPassword) {\n setRepeatNewPasswordError('Passwords do not match');\n return;\n }\n const errorCode = await user.updatePassword({ oldPassword, newPassword });\n if (errorCode) {\n setOldPasswordError('Incorrect password');\n } else {\n setOldPassword('');\n setNewPassword('');\n setRepeatNewPassword('');\n setPasswordChanged(true);\n }\n }\n }\n }}\n >\n <div className='flex flex-col'>\n <Label htmlFor='old-password' className='mb-1'>Old Password</Label>\n <PasswordInput\n id='old-password'\n value={oldPassword}\n onChange={(e) => {\n setOldPassword(e.target.value);\n setOldPasswordError('');\n setPasswordChanged(false);\n }}\n />\n <FormWarningText text={oldPasswordError} />\n </div>\n <div className='flex flex-col'>\n <Label htmlFor='new-password' className='mb-1'>New Password</Label>\n <PasswordInput\n id='new-password'\n value={newPassword}\n onChange={(e) => {\n setNewPassword(e.target.value);\n setNewPasswordError('');\n setPasswordChanged(false);\n }}\n />\n <FormWarningText text={newPasswordError} />\n </div>\n <div className='flex flex-col'>\n <Label htmlFor='repeat-new-password' className='mb-1'>Repeat New Password</Label>\n <PasswordInput\n id='repeat-new-password'\n value={repeatNewPassword}\n onChange={(e) => {\n setRepeatNewPassword(e.target.value);\n setRepeatNewPasswordError('');\n setPasswordChanged(false);\n }}\n />\n <FormWarningText text={repeatNewPasswordError} />\n </div>\n </SettingSection>\n );\n}\n\nfunction SignOutSection() {\n const user = useUser();\n return (\n <SettingSection\n title='Sign out'\n desc='Sign out of your account on this device.'\n buttonVariant='secondary'\n buttonText='Sign Out'\n onButtonClick={() => user?.signOut()}\n >\n </SettingSection>\n );\n}\n\nexport function AccountSettings({ fullPage=false }: { fullPage?: boolean }) {\n const user = useUser();\n if (!user) {\n return <PredefinedMessageCard type='signedOut' fullPage={fullPage} />;\n }\n\n const inner = (\n <div className={cn(fullPage ? 'p-4' : '', 'flex flex-col gap-4')}>\n <div>\n <Typography type='h2'>Account Settings</Typography>\n <Typography variant='secondary' type='label'>Manage your account</Typography>\n </div>\n\n <ProfileSection />\n <EmailVerificationSection />\n <PasswordSection />\n <SignOutSection />\n </div>\n );\n\n if (fullPage) {\n return (\n <Container size={600} className='stack-scope'>\n {inner}\n </Container>\n );\n } else {\n return inner;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components-page/account-settings.tsx"],"sourcesContent":["'use client';\n\nimport { getPasswordError } from '@stackframe/stack-shared/dist/helpers/password';\nimport { useAsyncCallback } from '@stackframe/stack-shared/dist/hooks/use-async-callback';\nimport { generateRandomValues } from '@stackframe/stack-shared/dist/utils/crypto';\nimport { throwErr } from '@stackframe/stack-shared/dist/utils/errors';\nimport { runAsynchronouslyWithAlert } from '@stackframe/stack-shared/dist/utils/promises';\nimport { Button, Card, CardContent, CardFooter, CardHeader, Container, Input, Label, PasswordInput, Typography } from '@stackframe/stack-ui';\nimport { Contact, Settings, Shield, ShieldCheck } from 'lucide-react';\nimport { TOTPController, createTOTPKeyURI } from \"oslo/otp\";\nimport * as QRCode from 'qrcode';\nimport React, { useEffect, useState } from 'react';\nimport { CurrentUser, Project, useStackApp, useUser } from '..';\nimport { FormWarningText } from '../components/elements/form-warning';\nimport { SidebarLayout } from '../components/elements/sidebar-layout';\nimport { UserAvatar } from '../components/elements/user-avatar';\n\nexport function AccountSettings({ fullPage=false }: { fullPage?: boolean }) {\n const user = useUser({ or: 'redirect' });\n\n const inner = <SidebarLayout\n items={[\n { title: 'My Profile', content: <ProfileSection/>, icon: Contact },\n { title: 'Security', content: <div className='flex flex-col gap-4'>\n <EmailVerificationSection />\n <PasswordSection />\n <MfaSection />\n </div>, icon: ShieldCheck },\n { title: 'Settings', content: <SignOutSection />, icon: Settings },\n ].filter(({ content }) => content as any)}\n title='Team Settings'\n />;\n\n if (fullPage) {\n return (\n <Container size={800} className='stack-scope'>\n {inner}\n </Container>\n );\n } else {\n return inner;\n }\n}\n\n\nfunction SettingSection(props: {\n title: string,\n desc: string,\n buttonText?: string,\n buttonDisabled?: boolean,\n onButtonClick?: React.ComponentProps<typeof Button>[\"onClick\"],\n buttonVariant?: 'default' | 'secondary',\n children?: React.ReactNode,\n}) {\n return (\n <Card>\n <CardHeader>\n <div>\n <Typography type='h4'>{props.title}</Typography>\n <Typography type='label' variant='secondary'>{props.desc}</Typography>\n </div>\n </CardHeader>\n {props.children && <CardContent>\n <div className='flex flex-col gap-4'>\n {props.children}\n </div>\n </CardContent>}\n {props.buttonText && <CardFooter>\n <div className='flex justify-end w-full'>\n <Button\n disabled={props.buttonDisabled}\n onClick={props.onButtonClick}\n variant={props.buttonVariant}\n >\n {props.buttonText}\n </Button>\n </div>\n </CardFooter>}\n </Card>\n );\n}\n\nfunction ProfileSection() {\n const user = useUser()!;\n const [userInfo, setUserInfo] = useState<{ displayName: string }>({ displayName: user.displayName || '' });\n const [changed, setChanged] = useState(false);\n\n return (\n <SettingSection\n title='Profile'\n desc='Your profile information'\n buttonDisabled={!changed}\n buttonText='Save'\n onButtonClick={async () => {\n await user.update(userInfo);\n setChanged(false);\n }}\n >\n <div className='flex gap-4 items-center'>\n <UserAvatar user={user} size={50}/>\n <div className='flex flex-col'>\n <Typography>{user.displayName}</Typography>\n <Typography variant='secondary' type='label'>{user.primaryEmail}</Typography>\n </div>\n </div>\n\n <div className='flex flex-col'>\n <Label htmlFor='display-name' className='mb-1'>Display Name</Label>\n <Input\n id='display-name'\n value={userInfo.displayName}\n onChange={(e) => {\n setUserInfo((i) => ({...i, displayName: e.target.value }));\n setChanged(true);\n }}\n />\n </div>\n </SettingSection>\n );\n}\n\nfunction EmailVerificationSection() {\n const user = useUser();\n const [emailSent, setEmailSent] = useState(false);\n\n return (\n <SettingSection\n title='Email Verification'\n desc='We want to make sure that you own the email address.'\n buttonDisabled={emailSent}\n buttonText={\n !user?.primaryEmailVerified ?\n emailSent ?\n 'Email sent!' :\n 'Send Email'\n : undefined\n }\n onButtonClick={async () => {\n await user?.sendVerificationEmail();\n setEmailSent(true);\n }}\n >\n {user?.primaryEmailVerified ?\n <Typography variant='success'>Your email has been verified.</Typography> :\n <Typography variant='destructive'>Your email has not been verified.</Typography>}\n </SettingSection>\n );\n}\n\nfunction PasswordSection() {\n const user = useUser({ or: \"throw\" });\n const [oldPassword, setOldPassword] = useState<string>('');\n const [oldPasswordError, setOldPasswordError] = useState<string>('');\n const [newPassword, setNewPassword] = useState<string>('');\n const [newPasswordError, setNewPasswordError] = useState<string>('');\n const [repeatNewPassword, setRepeatNewPassword] = useState<string>('');\n const [repeatNewPasswordError, setRepeatNewPasswordError] = useState<string>('');\n const [passwordChanged, setPasswordChanged] = useState(false);\n\n if (!user.hasPassword) {\n return null;\n }\n\n return (\n <SettingSection\n title='Password'\n desc='Change your password here.'\n buttonDisabled={passwordChanged || (!oldPassword && !newPassword && !repeatNewPassword)}\n buttonText={passwordChanged ? \"Password changed!\" : 'Update Password'}\n onButtonClick={async () => {\n setOldPasswordError('');\n setNewPasswordError('');\n setRepeatNewPasswordError('');\n if (!oldPassword) {\n setOldPasswordError('Please enter your old password');\n return;\n } else if (!newPassword) {\n setNewPasswordError('Please enter a new password');\n return;\n } else if (!repeatNewPassword) {\n setRepeatNewPasswordError('Please repeat your new password');\n return;\n } else {\n const errorMessage = getPasswordError(newPassword);\n if (errorMessage) {\n setNewPasswordError(errorMessage.message);\n } else {\n if (newPassword !== repeatNewPassword) {\n setRepeatNewPasswordError('Passwords do not match');\n return;\n }\n const errorCode = await user.updatePassword({ oldPassword, newPassword });\n if (errorCode) {\n setOldPasswordError('Incorrect password');\n } else {\n setOldPassword('');\n setNewPassword('');\n setRepeatNewPassword('');\n setPasswordChanged(true);\n }\n }\n }\n }}\n >\n <div className='flex flex-col'>\n <Label htmlFor='old-password' className='mb-1'>Old Password</Label>\n <PasswordInput\n id='old-password'\n value={oldPassword}\n onChange={(e) => {\n setOldPassword(e.target.value);\n setOldPasswordError('');\n setPasswordChanged(false);\n }}\n />\n <FormWarningText text={oldPasswordError} />\n </div>\n <div className='flex flex-col'>\n <Label htmlFor='new-password' className='mb-1'>New Password</Label>\n <PasswordInput\n id='new-password'\n value={newPassword}\n onChange={(e) => {\n setNewPassword(e.target.value);\n setNewPasswordError('');\n setPasswordChanged(false);\n }}\n />\n <FormWarningText text={newPasswordError} />\n </div>\n <div className='flex flex-col'>\n <Label htmlFor='repeat-new-password' className='mb-1'>Repeat New Password</Label>\n <PasswordInput\n id='repeat-new-password'\n value={repeatNewPassword}\n onChange={(e) => {\n setRepeatNewPassword(e.target.value);\n setRepeatNewPasswordError('');\n setPasswordChanged(false);\n }}\n />\n <FormWarningText text={repeatNewPasswordError} />\n </div>\n </SettingSection>\n );\n}\n\nfunction MfaSection() {\n const project = useStackApp().useProject();\n const user = useUser({ or: \"throw\" });\n const [generatedSecret, setGeneratedSecret] = useState<Uint8Array | null>(null);\n const [qrCodeUrl, setQrCodeUrl] = useState<string | null>(null);\n const [mfaCode, setMfaCode] = useState<string>(\"\");\n const [isMaybeWrong, setIsMaybeWrong] = useState(false);\n const isEnabled = user.isMultiFactorRequired;\n\n const [handleSubmit, isLoading] = useAsyncCallback(async () => {\n await user.update({\n totpMultiFactorSecret: generatedSecret,\n });\n setGeneratedSecret(null);\n setQrCodeUrl(null);\n setMfaCode(\"\");\n }, [generatedSecret, user]);\n\n useEffect(() => {\n setIsMaybeWrong(false);\n runAsynchronouslyWithAlert(async () => {\n if (generatedSecret && await new TOTPController().verify(mfaCode, generatedSecret)) {\n await handleSubmit();\n }\n setIsMaybeWrong(true);\n });\n }, [mfaCode, generatedSecret, handleSubmit]);\n\n return (\n <SettingSection\n title='Multi-factor Authentication'\n desc='Secure your account with an additional layer of security.'\n buttonVariant='secondary'\n buttonText={isEnabled ? 'Disable' : (generatedSecret ? 'Cancel' : 'Enable')}\n onButtonClick={async () => {\n if (isEnabled) {\n await user.update({\n totpMultiFactorSecret: null,\n });\n } else if (!generatedSecret) {\n const secret = generateRandomValues(new Uint8Array(20));\n setQrCodeUrl(await generateTotpQrCode(project, user, secret));\n setGeneratedSecret(secret);\n } else {\n setGeneratedSecret(null);\n setQrCodeUrl(null);\n setMfaCode(\"\");\n }\n }}\n >\n {isEnabled ? (\n <Typography variant=\"success\">Multi-factor authentication is currently enabled.</Typography>\n ) : (\n generatedSecret ? (\n <div className='flex flex-col gap-4 items-center'>\n <Typography>Scan this QR code with your authenticator app:</Typography>\n <img width={200} height={200} src={qrCodeUrl ?? throwErr(\"TOTP QR code failed to generate\")} alt=\"TOTP multi-factor authentication QR code\" />\n <Typography>Then, enter your six-digit MFA code:</Typography>\n <Input\n value={mfaCode}\n onChange={(e) => {\n setIsMaybeWrong(false);\n setMfaCode(e.target.value);\n }}\n placeholder=\"123456\"\n maxLength={6}\n disabled={isLoading}\n />\n {isMaybeWrong && mfaCode.length === 6 && (\n <Typography variant=\"destructive\">Incorrect code. Please try again.</Typography>\n )}\n </div>\n ) : (\n <Typography variant=\"destructive\">Multi-factor authentication is currently disabled.</Typography>\n )\n )}\n </SettingSection>\n );\n}\n\nasync function generateTotpQrCode(project: Project, user: CurrentUser, secret: Uint8Array) {\n const uri = createTOTPKeyURI(project.displayName, user.primaryEmail ?? user.id, secret);\n return await QRCode.toDataURL(uri) as any;\n}\n\nfunction SignOutSection() {\n const user = useUser({ or: \"throw\" });\n return (\n <SettingSection\n title='Sign out'\n desc='Sign out of your account on this device.'\n buttonVariant='secondary'\n buttonText='Sign Out'\n onButtonClick={() => user.signOut()}\n >\n </SettingSection>\n );\n}"],"mappings":"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","names":[]}
@@ -6,6 +6,7 @@ declare function AuthPage({ fullPage, type, automaticRedirect, mockProject, }: {
6
6
  automaticRedirect?: boolean;
7
7
  mockProject?: {
8
8
  config: {
9
+ signUpEnabled: boolean;
9
10
  credentialEnabled: boolean;
10
11
  magicLinkEnabled: boolean;
11
12
  oauthProviders: {
@@ -6,6 +6,7 @@ declare function AuthPage({ fullPage, type, automaticRedirect, mockProject, }: {
6
6
  automaticRedirect?: boolean;
7
7
  mockProject?: {
8
8
  config: {
9
+ signUpEnabled: boolean;
9
10
  credentialEnabled: boolean;
10
11
  magicLinkEnabled: boolean;
11
12
  oauthProviders: {
@@ -57,11 +57,14 @@ function AuthPage({
57
57
  if (user && !mockProject) {
58
58
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_predefined_message_card.PredefinedMessageCard, { type: "signedIn", fullPage });
59
59
  }
60
+ if (type === "sign-up" && !project.config.signUpEnabled) {
61
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_predefined_message_card.PredefinedMessageCard, { type: "signUpDisabled", fullPage });
62
+ }
60
63
  const enableSeparator = (project.config.credentialEnabled || project.config.magicLinkEnabled) && project.config.oauthProviders.length > 0;
61
64
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_maybe_full_page.MaybeFullPage, { fullPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "stack-scope flex flex-col items-stretch", children: [
62
65
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center mb-6", children: [
63
66
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { type: "h2", children: type === "sign-in" ? "Sign in to your account" : "Create a new account" }),
64
- type === "sign-in" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { children: [
67
+ type === "sign-in" ? project.config.signUpEnabled && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { children: [
65
68
  "Don't have an account? ",
66
69
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.StyledLink, { href: stackApp.urls.signUp, onClick: (e) => {
67
70
  (0, import_promises.runAsynchronously)(stackApp.redirectToSignUp());
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components-page/auth-page.tsx"],"sourcesContent":["'use client';\n\nimport { CredentialSignIn } from '../components/credential-sign-in';\nimport { SeparatorWithText } from '../components/elements/separator-with-text';\nimport { OAuthButtonGroup } from '../components/oauth-button-group';\nimport { MaybeFullPage } from '../components/elements/maybe-full-page';\nimport { useUser, useStackApp } from '..';\nimport { PredefinedMessageCard } from '../components/message-cards/predefined-message-card';\nimport { MagicLinkSignIn } from '../components/magic-link-sign-in';\nimport { CredentialSignUp } from '../components/credential-sign-up';\nimport { StyledLink, Tabs, TabsContent, TabsList, TabsTrigger, Typography } from '@stackframe/stack-ui';\nimport { Project } from '../lib/stack-app';\nimport { runAsynchronously } from '@stackframe/stack-shared/dist/utils/promises';\nimport { useEffect } from 'react';\n\nexport function AuthPage({\n fullPage=false,\n type,\n automaticRedirect,\n mockProject,\n}: {\n fullPage?: boolean,\n type: 'sign-in' | 'sign-up',\n automaticRedirect?: boolean,\n mockProject?: {\n config: {\n credentialEnabled: boolean,\n magicLinkEnabled: boolean,\n oauthProviders: {\n id: string,\n }[],\n },\n },\n}) {\n const stackApp = useStackApp();\n const user = useUser();\n const projectFromHook = stackApp.useProject();\n const project = mockProject || projectFromHook;\n\n useEffect(() => {\n if (automaticRedirect) {\n if (user && !mockProject) {\n runAsynchronously(type === 'sign-in' ? stackApp.redirectToAfterSignIn() : stackApp.redirectToAfterSignUp());\n }\n }\n }, [user, mockProject, stackApp, automaticRedirect]);\n\n if (user && !mockProject) {\n return <PredefinedMessageCard type='signedIn' fullPage={fullPage} />;\n }\n\n const enableSeparator = (project.config.credentialEnabled || project.config.magicLinkEnabled) && project.config.oauthProviders.length > 0;\n\n return (\n <MaybeFullPage fullPage={fullPage}>\n <div className='stack-scope flex flex-col items-stretch'>\n <div className=\"text-center mb-6\">\n <Typography type='h2'>\n {type === 'sign-in' ? 'Sign in to your account' : 'Create a new account'}\n </Typography>\n {type === 'sign-in' ? (\n <Typography>\n {\"Don't have an account? \"}\n <StyledLink href={stackApp.urls.signUp} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignUp());\n e.preventDefault();\n }}>\n Sign up\n </StyledLink>\n </Typography>\n ) : (\n <Typography>\n {\"Already have an account? \"}\n <StyledLink href={stackApp.urls.signIn} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignIn());\n e.preventDefault();\n }}>\n Sign in\n </StyledLink>\n </Typography>\n )}\n </div>\n <OAuthButtonGroup type={type} mockProject={mockProject} />\n {enableSeparator && <SeparatorWithText text={'Or continue with'} />}\n {project.config.credentialEnabled && project.config.magicLinkEnabled ? (\n <Tabs defaultValue='magic-link'>\n <TabsList className='w-full mb-2'>\n <TabsTrigger value='magic-link' className='flex-1'>Magic Link</TabsTrigger>\n <TabsTrigger value='password' className='flex-1'>Password</TabsTrigger>\n </TabsList>\n <TabsContent value='magic-link'>\n <MagicLinkSignIn/>\n </TabsContent>\n <TabsContent value='password'>\n {type === 'sign-up' ? <CredentialSignUp/> : <CredentialSignIn/>}\n </TabsContent>\n </Tabs>\n ) : project.config.credentialEnabled ? (\n type === 'sign-up' ? <CredentialSignUp/> : <CredentialSignIn/>\n ) : project.config.magicLinkEnabled ? (\n <MagicLinkSignIn/>\n ) : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,gCAAiC;AACjC,iCAAkC;AAClC,gCAAiC;AACjC,6BAA8B;AAC9B,eAAqC;AACrC,qCAAsC;AACtC,gCAAgC;AAChC,gCAAiC;AACjC,sBAAiF;AAEjF,sBAAkC;AAClC,mBAA0B;AAmCf;AAjCJ,SAAS,SAAS;AAAA,EACvB,WAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAaG;AACD,QAAM,eAAW,sBAAY;AAC7B,QAAM,WAAO,kBAAQ;AACrB,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,UAAU,eAAe;AAE/B,8BAAU,MAAM;AACd,QAAI,mBAAmB;AACrB,UAAI,QAAQ,CAAC,aAAa;AACxB,+CAAkB,SAAS,YAAY,SAAS,sBAAsB,IAAI,SAAS,sBAAsB,CAAC;AAAA,MAC5G;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,aAAa,UAAU,iBAAiB,CAAC;AAEnD,MAAI,QAAQ,CAAC,aAAa;AACxB,WAAO,4CAAC,wDAAsB,MAAK,YAAW,UAAoB;AAAA,EACpE;AAEA,QAAM,mBAAmB,QAAQ,OAAO,qBAAqB,QAAQ,OAAO,qBAAqB,QAAQ,OAAO,eAAe,SAAS;AAExI,SACE,4CAAC,wCAAc,UACb,uDAAC,SAAI,WAAU,2CACb;AAAA,iDAAC,SAAI,WAAU,oBACb;AAAA,kDAAC,8BAAW,MAAK,MACd,mBAAS,YAAY,4BAA4B,wBACpD;AAAA,MACC,SAAS,YACR,6CAAC,8BACE;AAAA;AAAA,QACD,4CAAC,8BAAW,MAAM,SAAS,KAAK,QAAQ,SAAS,CAAC,MAAM;AACtD,iDAAkB,SAAS,iBAAiB,CAAC;AAC7C,YAAE,eAAe;AAAA,QACnB,GAAG,qBAEH;AAAA,SACF,IAEA,6CAAC,8BACE;AAAA;AAAA,QACD,4CAAC,8BAAW,MAAM,SAAS,KAAK,QAAQ,SAAS,CAAC,MAAM;AACtD,iDAAkB,SAAS,iBAAiB,CAAC;AAC7C,YAAE,eAAe;AAAA,QACnB,GAAG,qBAEH;AAAA,SACF;AAAA,OAEJ;AAAA,IACA,4CAAC,8CAAiB,MAAY,aAA0B;AAAA,IACvD,mBAAmB,4CAAC,gDAAkB,MAAM,oBAAoB;AAAA,IAChE,QAAQ,OAAO,qBAAqB,QAAQ,OAAO,mBAClD,6CAAC,wBAAK,cAAa,cACjB;AAAA,mDAAC,4BAAS,WAAU,eAClB;AAAA,oDAAC,+BAAY,OAAM,cAAa,WAAU,UAAS,wBAAU;AAAA,QAC7D,4CAAC,+BAAY,OAAM,YAAW,WAAU,UAAS,sBAAQ;AAAA,SAC3D;AAAA,MACA,4CAAC,+BAAY,OAAM,cACjB,sDAAC,6CAAe,GAClB;AAAA,MACA,4CAAC,+BAAY,OAAM,YAChB,mBAAS,YAAY,4CAAC,8CAAgB,IAAK,4CAAC,8CAAgB,GAC/D;AAAA,OACF,IACE,QAAQ,OAAO,oBACjB,SAAS,YAAY,4CAAC,8CAAgB,IAAK,4CAAC,8CAAgB,IAC1D,QAAQ,OAAO,mBACjB,4CAAC,6CAAe,IACd;AAAA,KACN,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components-page/auth-page.tsx"],"sourcesContent":["'use client';\n\nimport { CredentialSignIn } from '../components/credential-sign-in';\nimport { SeparatorWithText } from '../components/elements/separator-with-text';\nimport { OAuthButtonGroup } from '../components/oauth-button-group';\nimport { MaybeFullPage } from '../components/elements/maybe-full-page';\nimport { useUser, useStackApp } from '..';\nimport { PredefinedMessageCard } from '../components/message-cards/predefined-message-card';\nimport { MagicLinkSignIn } from '../components/magic-link-sign-in';\nimport { CredentialSignUp } from '../components/credential-sign-up';\nimport { StyledLink, Tabs, TabsContent, TabsList, TabsTrigger, Typography } from '@stackframe/stack-ui';\nimport { Project } from '../lib/stack-app';\nimport { runAsynchronously } from '@stackframe/stack-shared/dist/utils/promises';\nimport { useEffect } from 'react';\n\nexport function AuthPage({\n fullPage=false,\n type,\n automaticRedirect,\n mockProject,\n}: {\n fullPage?: boolean,\n type: 'sign-in' | 'sign-up',\n automaticRedirect?: boolean,\n mockProject?: {\n config: {\n signUpEnabled: boolean,\n credentialEnabled: boolean,\n magicLinkEnabled: boolean,\n oauthProviders: {\n id: string,\n }[],\n },\n },\n}) {\n const stackApp = useStackApp();\n const user = useUser();\n const projectFromHook = stackApp.useProject();\n const project = mockProject || projectFromHook;\n\n useEffect(() => {\n if (automaticRedirect) {\n if (user && !mockProject) {\n runAsynchronously(type === 'sign-in' ? stackApp.redirectToAfterSignIn() : stackApp.redirectToAfterSignUp());\n }\n }\n }, [user, mockProject, stackApp, automaticRedirect]);\n\n if (user && !mockProject) {\n return <PredefinedMessageCard type='signedIn' fullPage={fullPage} />;\n }\n\n if (type === 'sign-up' && !project.config.signUpEnabled) {\n return <PredefinedMessageCard type='signUpDisabled' fullPage={fullPage} />;\n }\n\n const enableSeparator = (project.config.credentialEnabled || project.config.magicLinkEnabled) && project.config.oauthProviders.length > 0;\n\n return (\n <MaybeFullPage fullPage={fullPage}>\n <div className='stack-scope flex flex-col items-stretch'>\n <div className=\"text-center mb-6\">\n <Typography type='h2'>\n {type === 'sign-in' ? 'Sign in to your account' : 'Create a new account'}\n </Typography>\n {type === 'sign-in' ? (\n project.config.signUpEnabled && (\n <Typography>\n {\"Don't have an account? \"}\n <StyledLink href={stackApp.urls.signUp} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignUp());\n e.preventDefault();\n }}>\n Sign up\n </StyledLink>\n </Typography>\n )\n ) : (\n <Typography>\n {\"Already have an account? \"}\n <StyledLink href={stackApp.urls.signIn} onClick={(e) => {\n runAsynchronously(stackApp.redirectToSignIn());\n e.preventDefault();\n }}>\n Sign in\n </StyledLink>\n </Typography>\n )}\n </div>\n <OAuthButtonGroup type={type} mockProject={mockProject} />\n {enableSeparator && <SeparatorWithText text={'Or continue with'} />}\n {project.config.credentialEnabled && project.config.magicLinkEnabled ? (\n <Tabs defaultValue='magic-link'>\n <TabsList className='w-full mb-2'>\n <TabsTrigger value='magic-link' className='flex-1'>Magic Link</TabsTrigger>\n <TabsTrigger value='password' className='flex-1'>Password</TabsTrigger>\n </TabsList>\n <TabsContent value='magic-link'>\n <MagicLinkSignIn/>\n </TabsContent>\n <TabsContent value='password'>\n {type === 'sign-up' ? <CredentialSignUp/> : <CredentialSignIn/>}\n </TabsContent>\n </Tabs>\n ) : project.config.credentialEnabled ? (\n type === 'sign-up' ? <CredentialSignUp/> : <CredentialSignIn/>\n ) : project.config.magicLinkEnabled ? (\n <MagicLinkSignIn/>\n ) : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,gCAAiC;AACjC,iCAAkC;AAClC,gCAAiC;AACjC,6BAA8B;AAC9B,eAAqC;AACrC,qCAAsC;AACtC,gCAAgC;AAChC,gCAAiC;AACjC,sBAAiF;AAEjF,sBAAkC;AAClC,mBAA0B;AAoCf;AAlCJ,SAAS,SAAS;AAAA,EACvB,WAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAcG;AACD,QAAM,eAAW,sBAAY;AAC7B,QAAM,WAAO,kBAAQ;AACrB,QAAM,kBAAkB,SAAS,WAAW;AAC5C,QAAM,UAAU,eAAe;AAE/B,8BAAU,MAAM;AACd,QAAI,mBAAmB;AACrB,UAAI,QAAQ,CAAC,aAAa;AACxB,+CAAkB,SAAS,YAAY,SAAS,sBAAsB,IAAI,SAAS,sBAAsB,CAAC;AAAA,MAC5G;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,aAAa,UAAU,iBAAiB,CAAC;AAEnD,MAAI,QAAQ,CAAC,aAAa;AACxB,WAAO,4CAAC,wDAAsB,MAAK,YAAW,UAAoB;AAAA,EACpE;AAEA,MAAI,SAAS,aAAa,CAAC,QAAQ,OAAO,eAAe;AACvD,WAAO,4CAAC,wDAAsB,MAAK,kBAAiB,UAAoB;AAAA,EAC1E;AAEA,QAAM,mBAAmB,QAAQ,OAAO,qBAAqB,QAAQ,OAAO,qBAAqB,QAAQ,OAAO,eAAe,SAAS;AAExI,SACE,4CAAC,wCAAc,UACb,uDAAC,SAAI,WAAU,2CACb;AAAA,iDAAC,SAAI,WAAU,oBACb;AAAA,kDAAC,8BAAW,MAAK,MACd,mBAAS,YAAY,4BAA4B,wBACpD;AAAA,MACC,SAAS,YACR,QAAQ,OAAO,iBACb,6CAAC,8BACE;AAAA;AAAA,QACD,4CAAC,8BAAW,MAAM,SAAS,KAAK,QAAQ,SAAS,CAAC,MAAM;AACtD,iDAAkB,SAAS,iBAAiB,CAAC;AAC7C,YAAE,eAAe;AAAA,QACnB,GAAG,qBAEH;AAAA,SACF,IAGF,6CAAC,8BACE;AAAA;AAAA,QACD,4CAAC,8BAAW,MAAM,SAAS,KAAK,QAAQ,SAAS,CAAC,MAAM;AACtD,iDAAkB,SAAS,iBAAiB,CAAC;AAC7C,YAAE,eAAe;AAAA,QACnB,GAAG,qBAEH;AAAA,SACF;AAAA,OAEJ;AAAA,IACA,4CAAC,8CAAiB,MAAY,aAA0B;AAAA,IACvD,mBAAmB,4CAAC,gDAAkB,MAAM,oBAAoB;AAAA,IAChE,QAAQ,OAAO,qBAAqB,QAAQ,OAAO,mBAClD,6CAAC,wBAAK,cAAa,cACjB;AAAA,mDAAC,4BAAS,WAAU,eAClB;AAAA,oDAAC,+BAAY,OAAM,cAAa,WAAU,UAAS,wBAAU;AAAA,QAC7D,4CAAC,+BAAY,OAAM,YAAW,WAAU,UAAS,sBAAQ;AAAA,SAC3D;AAAA,MACA,4CAAC,+BAAY,OAAM,cACjB,sDAAC,6CAAe,GAClB;AAAA,MACA,4CAAC,+BAAY,OAAM,YAChB,mBAAS,YAAY,4CAAC,8CAAgB,IAAK,4CAAC,8CAAgB,GAC/D;AAAA,OACF,IACE,QAAQ,OAAO,oBACjB,SAAS,YAAY,4CAAC,8CAAgB,IAAK,4CAAC,8CAAgB,IAC1D,QAAQ,OAAO,mBACjB,4CAAC,6CAAe,IACd;AAAA,KACN,GACF;AAEJ;","names":[]}
@@ -1,7 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
+ declare function ForgotPasswordForm({ onSent }: {
4
+ onSent?: () => void;
5
+ }): react_jsx_runtime.JSX.Element;
3
6
  declare function ForgotPassword({ fullPage }: {
4
7
  fullPage?: boolean;
5
8
  }): react_jsx_runtime.JSX.Element;
6
9
 
7
- export { ForgotPassword };
10
+ export { ForgotPassword, ForgotPasswordForm };
@@ -1,7 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
+ declare function ForgotPasswordForm({ onSent }: {
4
+ onSent?: () => void;
5
+ }): react_jsx_runtime.JSX.Element;
3
6
  declare function ForgotPassword({ fullPage }: {
4
7
  fullPage?: boolean;
5
8
  }): react_jsx_runtime.JSX.Element;
6
9
 
7
- export { ForgotPassword };
10
+ export { ForgotPassword, ForgotPasswordForm };
@@ -22,16 +22,63 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  // src/components-page/forgot-password.tsx
23
23
  var forgot_password_exports = {};
24
24
  __export(forgot_password_exports, {
25
- ForgotPassword: () => ForgotPassword
25
+ ForgotPassword: () => ForgotPassword,
26
+ ForgotPasswordForm: () => ForgotPasswordForm
26
27
  });
27
28
  module.exports = __toCommonJS(forgot_password_exports);
28
- var import_forgot_password_form = require("../components/forgot-password-form");
29
- var import_maybe_full_page = require("../components/elements/maybe-full-page");
29
+ var import_yup = require("@hookform/resolvers/yup");
30
+ var import_schema_fields = require("@stackframe/stack-shared/dist/schema-fields");
31
+ var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
32
+ var import_stack_ui = require("@stackframe/stack-ui");
33
+ var import_react = require("react");
34
+ var import_react_hook_form = require("react-hook-form");
30
35
  var import__ = require("..");
36
+ var import_form_warning = require("../components/elements/form-warning");
37
+ var import_maybe_full_page = require("../components/elements/maybe-full-page");
31
38
  var import_predefined_message_card = require("../components/message-cards/predefined-message-card");
32
- var import_react = require("react");
33
- var import_stack_ui = require("@stackframe/stack-ui");
34
39
  var import_jsx_runtime = require("react/jsx-runtime");
40
+ var schema = (0, import_schema_fields.yupObject)({
41
+ email: (0, import_schema_fields.yupString)().email("Please enter a valid email").required("Please enter your email")
42
+ });
43
+ function ForgotPasswordForm({ onSent }) {
44
+ const { register, handleSubmit, formState: { errors }, clearErrors } = (0, import_react_hook_form.useForm)({
45
+ resolver: (0, import_yup.yupResolver)(schema)
46
+ });
47
+ const stackApp = (0, import__.useStackApp)();
48
+ const [loading, setLoading] = (0, import_react.useState)(false);
49
+ const onSubmit = async (data) => {
50
+ setLoading(true);
51
+ try {
52
+ const { email } = data;
53
+ await stackApp.sendForgotPasswordEmail(email);
54
+ onSent?.();
55
+ } finally {
56
+ setLoading(false);
57
+ }
58
+ };
59
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60
+ "form",
61
+ {
62
+ className: "flex flex-col items-stretch stack-scope",
63
+ onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
64
+ noValidate: true,
65
+ children: [
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "email", className: "mb-1", children: "Your Email" }),
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
68
+ import_stack_ui.Input,
69
+ {
70
+ id: "email",
71
+ type: "email",
72
+ ...register("email"),
73
+ onChange: () => clearErrors("email")
74
+ }
75
+ ),
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.email?.message?.toString() }),
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", className: "mt-6", loading, children: "Send Email" })
78
+ ]
79
+ }
80
+ );
81
+ }
35
82
  function ForgotPassword({ fullPage = false }) {
36
83
  const stackApp = (0, import__.useStackApp)();
37
84
  const user = (0, import__.useUser)();
@@ -50,11 +97,12 @@ function ForgotPassword({ fullPage = false }) {
50
97
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.StyledLink, { href: stackApp.urls["signUp"], children: "Sign in" })
51
98
  ] })
52
99
  ] }),
53
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_forgot_password_form.ForgotPasswordForm, { onSent: () => setSent(true) })
100
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ForgotPasswordForm, { onSent: () => setSent(true) })
54
101
  ] });
55
102
  }
56
103
  // Annotate the CommonJS export names for ESM import in node:
57
104
  0 && (module.exports = {
58
- ForgotPassword
105
+ ForgotPassword,
106
+ ForgotPasswordForm
59
107
  });
60
108
  //# sourceMappingURL=forgot-password.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components-page/forgot-password.tsx"],"sourcesContent":["'use client';\n\nimport { ForgotPasswordForm } from \"../components/forgot-password-form\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { useUser, useStackApp } from \"..\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useState } from \"react\";\nimport { StyledLink, Typography } from \"@stackframe/stack-ui\";\n\n\nexport function ForgotPassword({ fullPage=false }: { fullPage?: boolean }) {\n const stackApp = useStackApp();\n const user = useUser();\n const [sent, setSent] = useState(false);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={fullPage} />;\n }\n\n if (sent) {\n return <PredefinedMessageCard type='emailSent' fullPage={fullPage} />;\n }\n\n return (\n <MaybeFullPage fullPage={fullPage}>\n <div className=\"text-center mb-6 stack-scope\">\n <Typography type='h2'>Reset Your Password</Typography>\n <Typography>\n {\"Don't need to reset? \"}\n <StyledLink href={stackApp.urls['signUp']}>\n Sign in\n </StyledLink>\n </Typography>\n </div>\n <ForgotPasswordForm onSent={() => setSent(true)} />\n </MaybeFullPage>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,kCAAmC;AACnC,6BAA8B;AAC9B,eAAqC;AACrC,qCAAsC;AACtC,mBAAyB;AACzB,sBAAuC;AAS5B;AANJ,SAAS,eAAe,EAAE,WAAS,MAAM,GAA2B;AACzE,QAAM,eAAW,sBAAY;AAC7B,QAAM,WAAO,kBAAQ;AACrB,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,KAAK;AAEtC,MAAI,MAAM;AACR,WAAO,4CAAC,wDAAsB,MAAK,YAAW,UAAoB;AAAA,EACpE;AAEA,MAAI,MAAM;AACR,WAAO,4CAAC,wDAAsB,MAAK,aAAY,UAAoB;AAAA,EACrE;AAEA,SACE,6CAAC,wCAAc,UACb;AAAA,iDAAC,SAAI,WAAU,gCACb;AAAA,kDAAC,8BAAW,MAAK,MAAK,iCAAmB;AAAA,MACzC,6CAAC,8BACE;AAAA;AAAA,QACD,4CAAC,8BAAW,MAAM,SAAS,KAAK,QAAQ,GAAG,qBAE3C;AAAA,SACF;AAAA,OACF;AAAA,IACA,4CAAC,kDAAmB,QAAQ,MAAM,QAAQ,IAAI,GAAG;AAAA,KACnD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components-page/forgot-password.tsx"],"sourcesContent":["'use client';\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { yupObject, yupString } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Button, Input, Label, StyledLink, Typography } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\n\nconst schema = yupObject({\n email: yupString().email('Please enter a valid email').required('Please enter your email')\n});\n\nexport function ForgotPasswordForm({ onSent }: { onSent?: () => void }) {\n const { register, handleSubmit, formState: { errors }, clearErrors } = useForm({\n resolver: yupResolver(schema)\n });\n const stackApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n await stackApp.sendForgotPasswordEmail(email);\n onSent?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">Your Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n {...register('email')}\n onChange={() => clearErrors('email')}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n Send Email\n </Button>\n </form>\n );\n}\n\n\nexport function ForgotPassword({ fullPage=false }: { fullPage?: boolean }) {\n const stackApp = useStackApp();\n const user = useUser();\n const [sent, setSent] = useState(false);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={fullPage} />;\n }\n\n if (sent) {\n return <PredefinedMessageCard type='emailSent' fullPage={fullPage} />;\n }\n\n return (\n <MaybeFullPage fullPage={fullPage}>\n <div className=\"text-center mb-6 stack-scope\">\n <Typography type='h2'>Reset Your Password</Typography>\n <Typography>\n {\"Don't need to reset? \"}\n <StyledLink href={stackApp.urls['signUp']}>\n Sign in\n </StyledLink>\n </Typography>\n </div>\n <ForgotPasswordForm onSent={() => setSent(true)} />\n </MaybeFullPage>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAA4B;AAC5B,2BAAqC;AACrC,sBAA2C;AAC3C,sBAA6D;AAC7D,mBAAyB;AACzB,6BAAwB;AAExB,eAAqC;AACrC,0BAAgC;AAChC,6BAA8B;AAC9B,qCAAsC;AAyBlC;AAvBJ,IAAM,aAAS,gCAAU;AAAA,EACvB,WAAO,gCAAU,EAAE,MAAM,4BAA4B,EAAE,SAAS,yBAAyB;AAC3F,CAAC;AAEM,SAAS,mBAAmB,EAAE,OAAO,GAA4B;AACtE,QAAM,EAAE,UAAU,cAAc,WAAW,EAAE,OAAO,GAAG,YAAY,QAAI,gCAAQ;AAAA,IAC7E,cAAU,wBAAY,MAAM;AAAA,EAC9B,CAAC;AACD,QAAM,eAAW,sBAAY;AAC7B,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAE5C,QAAM,WAAW,OAAO,SAAuC;AAC7D,eAAW,IAAI;AACf,QAAI;AACF,YAAM,EAAE,MAAM,IAAI;AAClB,YAAM,SAAS,wBAAwB,KAAK;AAC9C,eAAS;AAAA,IACT,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,UAAU,WAAK,4CAA2B,aAAa,QAAQ,EAAE,CAAC,CAAC;AAAA,MACnE,YAAU;AAAA,MAEV;AAAA,oDAAC,yBAAM,SAAQ,SAAQ,WAAU,QAAO,wBAAU;AAAA,QAClD;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACJ,GAAG,SAAS,OAAO;AAAA,YACpB,UAAU,MAAM,YAAY,OAAO;AAAA;AAAA,QACrC;AAAA,QACA,4CAAC,uCAAgB,MAAM,OAAO,OAAO,SAAS,SAAS,GAAG;AAAA,QAE1D,4CAAC,0BAAO,MAAK,UAAS,WAAU,QAAO,SAAkB,wBAEzD;AAAA;AAAA;AAAA,EACF;AAEJ;AAGO,SAAS,eAAe,EAAE,WAAS,MAAM,GAA2B;AACzE,QAAM,eAAW,sBAAY;AAC7B,QAAM,WAAO,kBAAQ;AACrB,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,KAAK;AAEtC,MAAI,MAAM;AACR,WAAO,4CAAC,wDAAsB,MAAK,YAAW,UAAoB;AAAA,EACpE;AAEA,MAAI,MAAM;AACR,WAAO,4CAAC,wDAAsB,MAAK,aAAY,UAAoB;AAAA,EACrE;AAEA,SACE,6CAAC,wCAAc,UACb;AAAA,iDAAC,SAAI,WAAU,gCACb;AAAA,kDAAC,8BAAW,MAAK,MAAK,iCAAmB;AAAA,MACzC,6CAAC,8BACE;AAAA;AAAA,QACD,4CAAC,8BAAW,MAAM,SAAS,KAAK,QAAQ,GAAG,qBAE3C;AAAA,SACF;AAAA,OACF;AAAA,IACA,4CAAC,sBAAmB,QAAQ,MAAM,QAAQ,IAAI,GAAG;AAAA,KACnD;AAEJ;","names":[]}
@@ -1,8 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
+ declare function PasswordResetForm({ code, fullPage }: {
4
+ code: string;
5
+ fullPage?: boolean;
6
+ }): react_jsx_runtime.JSX.Element;
3
7
  declare function PasswordReset({ searchParams, fullPage, }: {
4
- searchParams?: Record<string, string>;
8
+ searchParams: Record<string, string>;
5
9
  fullPage?: boolean;
6
10
  }): react_jsx_runtime.JSX.Element;
7
11
 
8
- export { PasswordReset };
12
+ export { PasswordReset, PasswordResetForm as default };
@@ -1,8 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
+ declare function PasswordResetForm({ code, fullPage }: {
4
+ code: string;
5
+ fullPage?: boolean;
6
+ }): react_jsx_runtime.JSX.Element;
3
7
  declare function PasswordReset({ searchParams, fullPage, }: {
4
- searchParams?: Record<string, string>;
8
+ searchParams: Record<string, string>;
5
9
  fullPage?: boolean;
6
10
  }): react_jsx_runtime.JSX.Element;
7
11
 
8
- export { PasswordReset };
12
+ export { PasswordReset, PasswordResetForm as default };