@stackframe/stack 2.8.2 → 2.8.5

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 (157) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/components/api-key-dialogs.js +184 -0
  3. package/dist/components/api-key-dialogs.js.map +1 -0
  4. package/dist/components/api-key-table.js +149 -0
  5. package/dist/components/api-key-table.js.map +1 -0
  6. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +151 -0
  7. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
  8. package/dist/components-page/account-settings/api-keys/api-keys-page.js +70 -0
  9. package/dist/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
  10. package/dist/components-page/account-settings/editable-text.js +75 -0
  11. package/dist/components-page/account-settings/editable-text.js.map +1 -0
  12. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js +46 -0
  13. package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
  14. package/dist/components-page/account-settings/email-and-auth/emails-section.js +188 -0
  15. package/dist/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
  16. package/dist/components-page/account-settings/email-and-auth/mfa-section.js +146 -0
  17. package/dist/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
  18. package/dist/components-page/account-settings/email-and-auth/otp-section.js +89 -0
  19. package/dist/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
  20. package/dist/components-page/account-settings/email-and-auth/passkey-section.js +92 -0
  21. package/dist/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
  22. package/dist/components-page/account-settings/email-and-auth/password-section.js +181 -0
  23. package/dist/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
  24. package/dist/components-page/account-settings/page-layout.js +34 -0
  25. package/dist/components-page/account-settings/page-layout.js.map +1 -0
  26. package/dist/components-page/account-settings/profile-page/profile-page.js +75 -0
  27. package/dist/components-page/account-settings/profile-page/profile-page.js.map +1 -0
  28. package/dist/components-page/account-settings/section.js +44 -0
  29. package/dist/components-page/account-settings/section.js.map +1 -0
  30. package/dist/components-page/account-settings/settings/delete-account-section.js +87 -0
  31. package/dist/components-page/account-settings/settings/delete-account-section.js.map +1 -0
  32. package/dist/components-page/account-settings/settings/settings-page.js +40 -0
  33. package/dist/components-page/account-settings/settings/settings-page.js.map +1 -0
  34. package/dist/components-page/account-settings/settings/sign-out-section.js +54 -0
  35. package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -0
  36. package/dist/components-page/account-settings/teams/leave-team-section.js +79 -0
  37. package/dist/components-page/account-settings/teams/leave-team-section.js.map +1 -0
  38. package/dist/components-page/account-settings/teams/team-api-keys-section.js +89 -0
  39. package/dist/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
  40. package/dist/components-page/account-settings/teams/team-creation-page.js +92 -0
  41. package/dist/components-page/account-settings/teams/team-creation-page.js.map +1 -0
  42. package/dist/components-page/account-settings/teams/team-display-name-section.js +57 -0
  43. package/dist/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
  44. package/dist/components-page/account-settings/teams/team-member-invitation-section.js +131 -0
  45. package/dist/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
  46. package/dist/components-page/account-settings/teams/team-member-list-section.js +61 -0
  47. package/dist/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
  48. package/dist/components-page/account-settings/teams/team-page.js +50 -0
  49. package/dist/components-page/account-settings/teams/team-page.js.map +1 -0
  50. package/dist/components-page/account-settings/teams/team-profile-image-section.js +59 -0
  51. package/dist/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
  52. package/dist/components-page/account-settings/teams/team-profile-user-section.js +56 -0
  53. package/dist/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
  54. package/dist/components-page/account-settings.js +34 -1072
  55. package/dist/components-page/account-settings.js.map +1 -1
  56. package/dist/components-page/section.js +6 -0
  57. package/dist/components-page/section.js.map +1 -0
  58. package/dist/esm/components/api-key-dialogs.js +157 -0
  59. package/dist/esm/components/api-key-dialogs.js.map +1 -0
  60. package/dist/esm/components/api-key-table.js +125 -0
  61. package/dist/esm/components/api-key-table.js.map +1 -0
  62. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +126 -0
  63. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
  64. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +45 -0
  65. package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
  66. package/dist/esm/components-page/account-settings/editable-text.js +50 -0
  67. package/dist/esm/components-page/account-settings/editable-text.js.map +1 -0
  68. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js +21 -0
  69. package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
  70. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +163 -0
  71. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
  72. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +111 -0
  73. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
  74. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js +64 -0
  75. package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
  76. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js +67 -0
  77. package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
  78. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +146 -0
  79. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
  80. package/dist/esm/components-page/account-settings/page-layout.js +9 -0
  81. package/dist/esm/components-page/account-settings/page-layout.js.map +1 -0
  82. package/dist/esm/components-page/account-settings/profile-page/profile-page.js +50 -0
  83. package/dist/esm/components-page/account-settings/profile-page/profile-page.js.map +1 -0
  84. package/dist/esm/components-page/account-settings/section.js +19 -0
  85. package/dist/esm/components-page/account-settings/section.js.map +1 -0
  86. package/dist/esm/components-page/account-settings/settings/delete-account-section.js +62 -0
  87. package/dist/esm/components-page/account-settings/settings/delete-account-section.js.map +1 -0
  88. package/dist/esm/components-page/account-settings/settings/settings-page.js +15 -0
  89. package/dist/esm/components-page/account-settings/settings/settings-page.js.map +1 -0
  90. package/dist/esm/components-page/account-settings/settings/sign-out-section.js +29 -0
  91. package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -0
  92. package/dist/esm/components-page/account-settings/teams/leave-team-section.js +54 -0
  93. package/dist/esm/components-page/account-settings/teams/leave-team-section.js.map +1 -0
  94. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +64 -0
  95. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
  96. package/dist/esm/components-page/account-settings/teams/team-creation-page.js +67 -0
  97. package/dist/esm/components-page/account-settings/teams/team-creation-page.js.map +1 -0
  98. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js +32 -0
  99. package/dist/esm/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
  100. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +106 -0
  101. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
  102. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js +36 -0
  103. package/dist/esm/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
  104. package/dist/esm/components-page/account-settings/teams/team-page.js +25 -0
  105. package/dist/esm/components-page/account-settings/teams/team-page.js.map +1 -0
  106. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js +34 -0
  107. package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
  108. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js +31 -0
  109. package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
  110. package/dist/esm/components-page/account-settings.js +34 -1061
  111. package/dist/esm/components-page/account-settings.js.map +1 -1
  112. package/dist/esm/components-page/section.js +4 -0
  113. package/dist/esm/components-page/section.js.map +1 -0
  114. package/dist/esm/lib/stack-app/api-keys/index.js +14 -6
  115. package/dist/esm/lib/stack-app/api-keys/index.js.map +1 -1
  116. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +26 -23
  117. package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  118. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +169 -0
  119. package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  120. package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
  121. package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
  122. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +148 -8
  123. package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  124. package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  125. package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  126. package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  127. package/dist/esm/lib/stack-app/index.js.map +1 -1
  128. package/dist/esm/lib/stack-app/internal-api-keys/index.js +14 -0
  129. package/dist/esm/lib/stack-app/internal-api-keys/index.js.map +1 -0
  130. package/dist/esm/lib/stack-app/projects/index.js +3 -1
  131. package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
  132. package/dist/esm/lib/stack-app/teams/index.js.map +1 -1
  133. package/dist/esm/lib/stack-app/users/index.js.map +1 -1
  134. package/dist/index.d.mts +103 -35
  135. package/dist/index.d.ts +103 -35
  136. package/dist/lib/stack-app/api-keys/index.js +16 -7
  137. package/dist/lib/stack-app/api-keys/index.js.map +1 -1
  138. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +25 -22
  139. package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
  140. package/dist/lib/stack-app/apps/implementations/client-app-impl.js +169 -0
  141. package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
  142. package/dist/lib/stack-app/apps/implementations/common.js +1 -1
  143. package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
  144. package/dist/lib/stack-app/apps/implementations/server-app-impl.js +148 -8
  145. package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
  146. package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
  147. package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
  148. package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
  149. package/dist/lib/stack-app/index.js.map +1 -1
  150. package/dist/lib/stack-app/internal-api-keys/index.js +39 -0
  151. package/dist/lib/stack-app/internal-api-keys/index.js.map +1 -0
  152. package/dist/lib/stack-app/project-configs/index.js.map +1 -1
  153. package/dist/lib/stack-app/projects/index.js +3 -1
  154. package/dist/lib/stack-app/projects/index.js.map +1 -1
  155. package/dist/lib/stack-app/teams/index.js.map +1 -1
  156. package/dist/lib/stack-app/users/index.js.map +1 -1
  157. package/package.json +5 -4
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components-page/account-settings/api-keys/api-keys-page.tsx
21
+ var api_keys_page_exports = {};
22
+ __export(api_keys_page_exports, {
23
+ ApiKeysPage: () => ApiKeysPage
24
+ });
25
+ module.exports = __toCommonJS(api_keys_page_exports);
26
+ var import_stack_ui = require("@stackframe/stack-ui");
27
+ var import_react = require("react");
28
+ var import_api_key_dialogs = require("../../../components/api-key-dialogs");
29
+ var import_api_key_table = require("../../../components/api-key-table");
30
+ var import_hooks = require("../../../lib/hooks");
31
+ var import_translations = require("../../../lib/translations");
32
+ var import_page_layout = require("../page-layout");
33
+ var import_jsx_runtime = require("react/jsx-runtime");
34
+ function ApiKeysPage() {
35
+ const { t } = (0, import_translations.useTranslation)();
36
+ const user = (0, import_hooks.useUser)({ or: "redirect" });
37
+ const apiKeys = user.useApiKeys();
38
+ const [isNewApiKeyDialogOpen, setIsNewApiKeyDialogOpen] = (0, import_react.useState)(false);
39
+ const [returnedApiKey, setReturnedApiKey] = (0, import_react.useState)(null);
40
+ const CreateDialog = import_api_key_dialogs.CreateApiKeyDialog;
41
+ const ShowDialog = import_api_key_dialogs.ShowApiKeyDialog;
42
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_page_layout.PageLayout, { children: [
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { onClick: () => setIsNewApiKeyDialogOpen(true), children: t("Create API Key") }),
44
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_api_key_table.ApiKeyTable, { apiKeys }),
45
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
46
+ CreateDialog,
47
+ {
48
+ open: isNewApiKeyDialogOpen,
49
+ onOpenChange: setIsNewApiKeyDialogOpen,
50
+ onKeyCreated: setReturnedApiKey,
51
+ createApiKey: async (data) => {
52
+ const apiKey = await user.createApiKey(data);
53
+ return apiKey;
54
+ }
55
+ }
56
+ ),
57
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
58
+ ShowDialog,
59
+ {
60
+ apiKey: returnedApiKey,
61
+ onClose: () => setReturnedApiKey(null)
62
+ }
63
+ )
64
+ ] });
65
+ }
66
+ // Annotate the CommonJS export names for ESM import in node:
67
+ 0 && (module.exports = {
68
+ ApiKeysPage
69
+ });
70
+ //# sourceMappingURL=api-keys-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/api-keys/api-keys-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Button } from \"@stackframe/stack-ui\";\nimport { useState } from \"react\";\nimport { CreateApiKeyDialog, ShowApiKeyDialog } from \"../../../components/api-key-dialogs\";\nimport { ApiKeyTable } from \"../../../components/api-key-table\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { ApiKey, ApiKeyCreationOptions } from \"../../../lib/stack-app/api-keys\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { PageLayout } from \"../page-layout\";\n\n\nexport function ApiKeysPage() {\n const { t } = useTranslation();\n\n const user = useUser({ or: 'redirect' });\n const apiKeys = user.useApiKeys();\n\n const [isNewApiKeyDialogOpen, setIsNewApiKeyDialogOpen] = useState(false);\n const [returnedApiKey, setReturnedApiKey] = useState<ApiKey<\"user\", true> | null>(null);\n\n const CreateDialog = CreateApiKeyDialog<\"user\">;\n const ShowDialog = ShowApiKeyDialog<\"user\">;\n\n return (\n <PageLayout>\n <Button onClick={() => setIsNewApiKeyDialogOpen(true)}>\n {t(\"Create API Key\")}\n </Button>\n <ApiKeyTable apiKeys={apiKeys} />\n <CreateDialog\n open={isNewApiKeyDialogOpen}\n onOpenChange={setIsNewApiKeyDialogOpen}\n onKeyCreated={setReturnedApiKey}\n createApiKey={async (data: ApiKeyCreationOptions<\"user\">) => {\n const apiKey = await user.createApiKey(data);\n return apiKey;\n }}\n />\n <ShowDialog\n apiKey={returnedApiKey}\n onClose={() => setReturnedApiKey(null)}\n />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAAuB;AACvB,mBAAyB;AACzB,6BAAqD;AACrD,2BAA4B;AAC5B,mBAAwB;AAExB,0BAA+B;AAC/B,yBAA2B;AAgBvB;AAbG,SAAS,cAAc;AAC5B,QAAM,EAAE,EAAE,QAAI,oCAAe;AAE7B,QAAM,WAAO,sBAAQ,EAAE,IAAI,WAAW,CAAC;AACvC,QAAM,UAAU,KAAK,WAAW;AAEhC,QAAM,CAAC,uBAAuB,wBAAwB,QAAI,uBAAS,KAAK;AACxE,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,uBAAwC,IAAI;AAExF,QAAM,eAAe;AACrB,QAAM,aAAa;AAEnB,SACE,6CAAC,iCACC;AAAA,gDAAC,0BAAO,SAAS,MAAM,yBAAyB,IAAI,GACjD,YAAE,gBAAgB,GACrB;AAAA,IACA,4CAAC,oCAAY,SAAkB;AAAA,IAC/B;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,cAAc;AAAA,QACd,cAAc,OAAO,SAAwC;AAC3D,gBAAM,SAAS,MAAM,KAAK,aAAa,IAAI;AAC3C,iBAAO;AAAA,QACT;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS,MAAM,kBAAkB,IAAI;AAAA;AAAA,IACvC;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components-page/account-settings/editable-text.tsx
21
+ var editable_text_exports = {};
22
+ __export(editable_text_exports, {
23
+ EditableText: () => EditableText
24
+ });
25
+ module.exports = __toCommonJS(editable_text_exports);
26
+ var import_stack_ui = require("@stackframe/stack-ui");
27
+ var import_lucide_react = require("lucide-react");
28
+ var import_react = require("react");
29
+ var import_translations = require("../../lib/translations");
30
+ var import_jsx_runtime = require("react/jsx-runtime");
31
+ function EditableText(props) {
32
+ const [editing, setEditing] = (0, import_react.useState)(false);
33
+ const [editingValue, setEditingValue] = (0, import_react.useState)(props.value);
34
+ const { t } = (0, import_translations.useTranslation)();
35
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center gap-2", children: editing ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
36
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
37
+ import_stack_ui.Input,
38
+ {
39
+ value: editingValue,
40
+ onChange: (e) => setEditingValue(e.target.value)
41
+ }
42
+ ),
43
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44
+ import_stack_ui.Button,
45
+ {
46
+ size: "sm",
47
+ onClick: async () => {
48
+ await props.onSave?.(editingValue);
49
+ setEditing(false);
50
+ },
51
+ children: t("Save")
52
+ }
53
+ ),
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
55
+ import_stack_ui.Button,
56
+ {
57
+ size: "sm",
58
+ variant: "secondary",
59
+ onClick: () => {
60
+ setEditingValue(props.value);
61
+ setEditing(false);
62
+ },
63
+ children: t("Cancel")
64
+ }
65
+ )
66
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: props.value }),
68
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { onClick: () => setEditing(true), size: "icon", variant: "ghost", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Edit, { className: "w-4 h-4" }) })
69
+ ] }) });
70
+ }
71
+ // Annotate the CommonJS export names for ESM import in node:
72
+ 0 && (module.exports = {
73
+ EditableText
74
+ });
75
+ //# sourceMappingURL=editable-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components-page/account-settings/editable-text.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { Button, Input, Typography } from \"@stackframe/stack-ui\";\nimport { Edit } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { useTranslation } from \"../../lib/translations\";\n\n\nexport function EditableText(props: { value: string, onSave?: (value: string) => void | Promise<void> }) {\n const [editing, setEditing] = useState(false);\n const [editingValue, setEditingValue] = useState(props.value);\n const { t } = useTranslation();\n\n return (\n <div className='flex items-center gap-2'>\n {editing ? (\n <>\n <Input\n value={editingValue}\n onChange={(e) => setEditingValue(e.target.value)}\n />\n <Button\n size='sm'\n onClick={async () => {\n await props.onSave?.(editingValue);\n setEditing(false);\n }}\n >\n {t(\"Save\")}\n </Button>\n <Button\n size='sm'\n variant='secondary'\n onClick={() => {\n setEditingValue(props.value);\n setEditing(false);\n }}>\n {t(\"Cancel\")}\n </Button>\n </>\n ) : (\n <>\n <Typography>{props.value}</Typography>\n <Button onClick={() => setEditing(true)} size='icon' variant='ghost'>\n <Edit className=\"w-4 h-4\" />\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,sBAA0C;AAC1C,0BAAqB;AACrB,mBAAyB;AACzB,0BAA+B;AAWvB;AARD,SAAS,aAAa,OAA4E;AACvG,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,MAAM,KAAK;AAC5D,QAAM,EAAE,EAAE,QAAI,oCAAe;AAE7B,SACE,4CAAC,SAAI,WAAU,2BACZ,oBACC,4EACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,gBAAgB,EAAE,OAAO,KAAK;AAAA;AAAA,IACjD;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,YAAY;AACnB,gBAAM,MAAM,SAAS,YAAY;AACjC,qBAAW,KAAK;AAAA,QAClB;AAAA,QAEC,YAAE,MAAM;AAAA;AAAA,IACX;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,SAAS,MAAM;AACb,0BAAgB,MAAM,KAAK;AAC3B,qBAAW,KAAK;AAAA,QAClB;AAAA,QACC,YAAE,QAAQ;AAAA;AAAA,IACb;AAAA,KACF,IAEA,4EACE;AAAA,gDAAC,8BAAY,gBAAM,OAAM;AAAA,IACzB,4CAAC,0BAAO,SAAS,MAAM,WAAW,IAAI,GAAG,MAAK,QAAO,SAAQ,SAC3D,sDAAC,4BAAK,WAAU,WAAU,GAC5B;AAAA,KACF,GAEJ;AAEJ;","names":[]}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components-page/account-settings/email-and-auth/email-and-auth-page.tsx
21
+ var email_and_auth_page_exports = {};
22
+ __export(email_and_auth_page_exports, {
23
+ EmailsAndAuthPage: () => EmailsAndAuthPage
24
+ });
25
+ module.exports = __toCommonJS(email_and_auth_page_exports);
26
+ var import_page_layout = require("../page-layout");
27
+ var import_emails_section = require("./emails-section");
28
+ var import_mfa_section = require("./mfa-section");
29
+ var import_otp_section = require("./otp-section");
30
+ var import_passkey_section = require("./passkey-section");
31
+ var import_password_section = require("./password-section");
32
+ var import_jsx_runtime = require("react/jsx-runtime");
33
+ function EmailsAndAuthPage() {
34
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_page_layout.PageLayout, { children: [
35
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_emails_section.EmailsSection, {}),
36
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_password_section.PasswordSection, {}),
37
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_passkey_section.PasskeySection, {}),
38
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_otp_section.OtpSection, {}),
39
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_mfa_section.MfaSection, {})
40
+ ] });
41
+ }
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ EmailsAndAuthPage
45
+ });
46
+ //# sourceMappingURL=email-and-auth-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/email-and-auth/email-and-auth-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { PageLayout } from \"../page-layout\";\nimport { EmailsSection } from \"./emails-section\";\nimport { MfaSection } from \"./mfa-section\";\nimport { OtpSection } from \"./otp-section\";\nimport { PasskeySection } from \"./passkey-section\";\nimport { PasswordSection } from \"./password-section\";\n\nexport function EmailsAndAuthPage() {\n return (\n <PageLayout>\n <EmailsSection/>\n <PasswordSection />\n <PasskeySection />\n <OtpSection />\n <MfaSection />\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAA2B;AAC3B,4BAA8B;AAC9B,yBAA2B;AAC3B,yBAA2B;AAC3B,6BAA+B;AAC/B,8BAAgC;AAI5B;AAFG,SAAS,oBAAoB;AAClC,SACE,6CAAC,iCACC;AAAA,gDAAC,uCAAa;AAAA,IACd,4CAAC,2CAAgB;AAAA,IACjB,4CAAC,yCAAe;AAAA,IAChB,4CAAC,iCAAW;AAAA,IACZ,4CAAC,iCAAW;AAAA,KACd;AAEJ;","names":[]}
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components-page/account-settings/email-and-auth/emails-section.tsx
21
+ var emails_section_exports = {};
22
+ __export(emails_section_exports, {
23
+ EmailsSection: () => EmailsSection
24
+ });
25
+ module.exports = __toCommonJS(emails_section_exports);
26
+ var import_yup = require("@hookform/resolvers/yup");
27
+ var import_known_errors = require("@stackframe/stack-shared/dist/known-errors");
28
+ var import_schema_fields = require("@stackframe/stack-shared/dist/schema-fields");
29
+ var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
30
+ var import_stack_ui = require("@stackframe/stack-ui");
31
+ var import_react = require("react");
32
+ var import_react_hook_form = require("react-hook-form");
33
+ var import_form_warning = require("../../../components/elements/form-warning");
34
+ var import_hooks = require("../../../lib/hooks");
35
+ var import_translations = require("../../../lib/translations");
36
+ var import_jsx_runtime = require("react/jsx-runtime");
37
+ function EmailsSection() {
38
+ const { t } = (0, import_translations.useTranslation)();
39
+ const user = (0, import_hooks.useUser)({ or: "redirect" });
40
+ const contactChannels = user.useContactChannels();
41
+ const [addingEmail, setAddingEmail] = (0, import_react.useState)(contactChannels.length === 0);
42
+ const [addingEmailLoading, setAddingEmailLoading] = (0, import_react.useState)(false);
43
+ const [addedEmail, setAddedEmail] = (0, import_react.useState)(null);
44
+ const isLastEmail = contactChannels.filter((x) => x.usedForAuth && x.type === "email").length === 1;
45
+ (0, import_react.useEffect)(() => {
46
+ if (addedEmail) {
47
+ (0, import_promises.runAsynchronously)(async () => {
48
+ const cc = contactChannels.find((x) => x.value === addedEmail);
49
+ if (cc && !cc.isVerified) {
50
+ await cc.sendVerificationEmail();
51
+ }
52
+ setAddedEmail(null);
53
+ });
54
+ }
55
+ }, [contactChannels, addedEmail]);
56
+ const emailSchema = (0, import_schema_fields.yupObject)({
57
+ email: (0, import_schema_fields.strictEmailSchema)(t("Please enter a valid email address")).notOneOf(contactChannels.map((x) => x.value), t("Email already exists")).defined().nonEmpty(t("Email is required"))
58
+ });
59
+ const { register, handleSubmit, formState: { errors }, reset } = (0, import_react_hook_form.useForm)({
60
+ resolver: (0, import_yup.yupResolver)(emailSchema)
61
+ });
62
+ const onSubmit = async (data) => {
63
+ setAddingEmailLoading(true);
64
+ try {
65
+ await user.createContactChannel({ type: "email", value: data.email, usedForAuth: false });
66
+ setAddedEmail(data.email);
67
+ } finally {
68
+ setAddingEmailLoading(false);
69
+ }
70
+ setAddingEmail(false);
71
+ reset();
72
+ };
73
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
74
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col md:flex-row justify-between mb-4 gap-4", children: [
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium", children: t("Emails") }),
76
+ addingEmail ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
77
+ "form",
78
+ {
79
+ onSubmit: (e) => {
80
+ e.preventDefault();
81
+ (0, import_promises.runAsynchronously)(handleSubmit(onSubmit));
82
+ },
83
+ className: "flex flex-col",
84
+ children: [
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
87
+ import_stack_ui.Input,
88
+ {
89
+ ...register("email"),
90
+ placeholder: t("Enter email")
91
+ }
92
+ ),
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", loading: addingEmailLoading, children: t("Add") }),
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
95
+ import_stack_ui.Button,
96
+ {
97
+ variant: "secondary",
98
+ onClick: () => {
99
+ setAddingEmail(false);
100
+ reset();
101
+ },
102
+ children: t("Cancel")
103
+ }
104
+ )
105
+ ] }),
106
+ errors.email && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.email.message })
107
+ ]
108
+ }
109
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex md:justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "secondary", onClick: () => setAddingEmail(true), children: t("Add an email") }) })
110
+ ] }),
111
+ contactChannels.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Table, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableBody, { children: contactChannels.filter((x) => x.type === "email").sort((a, b) => {
112
+ if (a.isPrimary !== b.isPrimary) return a.isPrimary ? -1 : 1;
113
+ if (a.isVerified !== b.isVerified) return a.isVerified ? -1 : 1;
114
+ return 0;
115
+ }).map((x) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.TableRow, { children: [
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col md:flex-row gap-2 md:gap-4", children: [
117
+ x.value,
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
119
+ x.isPrimary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Badge, { children: t("Primary") }) : null,
120
+ !x.isVerified ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Badge, { variant: "destructive", children: t("Unverified") }) : null,
121
+ x.usedForAuth ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Badge, { variant: "outline", children: t("Used for sign-in") }) : null
122
+ ] })
123
+ ] }) }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.ActionCell, { items: [
125
+ ...!x.isVerified ? [{
126
+ item: t("Send verification email"),
127
+ onClick: async () => {
128
+ await x.sendVerificationEmail();
129
+ }
130
+ }] : [],
131
+ ...!x.isPrimary && x.isVerified ? [{
132
+ item: t("Set as primary"),
133
+ onClick: async () => {
134
+ await x.update({ isPrimary: true });
135
+ }
136
+ }] : !x.isPrimary ? [{
137
+ item: t("Set as primary"),
138
+ onClick: async () => {
139
+ },
140
+ disabled: true,
141
+ disabledTooltip: t("Please verify your email first")
142
+ }] : [],
143
+ ...!x.usedForAuth && x.isVerified ? [{
144
+ item: t("Use for sign-in"),
145
+ onClick: async () => {
146
+ try {
147
+ await x.update({ usedForAuth: true });
148
+ } catch (e) {
149
+ if (e instanceof import_known_errors.KnownErrors.ContactChannelAlreadyUsedForAuthBySomeoneElse) {
150
+ alert(t("This email is already used for sign-in by another user."));
151
+ }
152
+ }
153
+ }
154
+ }] : [],
155
+ ...x.usedForAuth && !isLastEmail ? [{
156
+ item: t("Stop using for sign-in"),
157
+ onClick: async () => {
158
+ await x.update({ usedForAuth: false });
159
+ }
160
+ }] : x.usedForAuth ? [{
161
+ item: t("Stop using for sign-in"),
162
+ onClick: async () => {
163
+ },
164
+ disabled: true,
165
+ disabledTooltip: t("You can not remove your last sign-in email")
166
+ }] : [],
167
+ ...!isLastEmail || !x.usedForAuth ? [{
168
+ item: t("Remove"),
169
+ onClick: async () => {
170
+ await x.delete();
171
+ },
172
+ danger: true
173
+ }] : [{
174
+ item: t("Remove"),
175
+ onClick: async () => {
176
+ },
177
+ disabled: true,
178
+ disabledTooltip: t("You can not remove your last sign-in email")
179
+ }]
180
+ ] }) })
181
+ ] }, x.id)) }) }) }) : null
182
+ ] });
183
+ }
184
+ // Annotate the CommonJS export names for ESM import in node:
185
+ 0 && (module.exports = {
186
+ EmailsSection
187
+ });
188
+ //# sourceMappingURL=emails-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/email-and-auth/emails-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { KnownErrors } from \"@stackframe/stack-shared/dist/known-errors\";\nimport { strictEmailSchema, yupObject } from \"@stackframe/stack-shared/dist/schema-fields\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { ActionCell, Badge, Button, Input, Table, TableBody, TableCell, TableRow, Typography } from \"@stackframe/stack-ui\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { FormWarningText } from \"../../../components/elements/form-warning\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\n\nexport function EmailsSection() {\n const { t } = useTranslation();\n const user = useUser({ or: 'redirect' });\n const contactChannels = user.useContactChannels();\n const [addingEmail, setAddingEmail] = useState(contactChannels.length === 0);\n const [addingEmailLoading, setAddingEmailLoading] = useState(false);\n const [addedEmail, setAddedEmail] = useState<string | null>(null);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const isLastEmail = contactChannels.filter(x => x.usedForAuth && x.type === 'email').length === 1;\n\n useEffect(() => {\n if (addedEmail) {\n runAsynchronously(async () => {\n const cc = contactChannels.find(x => x.value === addedEmail);\n if (cc && !cc.isVerified) {\n await cc.sendVerificationEmail();\n }\n setAddedEmail(null);\n });\n }\n }, [contactChannels, addedEmail]);\n\n const emailSchema = yupObject({\n email: strictEmailSchema(t('Please enter a valid email address'))\n .notOneOf(contactChannels.map(x => x.value), t('Email already exists'))\n .defined()\n .nonEmpty(t('Email is required')),\n });\n\n const { register, handleSubmit, formState: { errors }, reset } = useForm({\n resolver: yupResolver(emailSchema)\n });\n\n const onSubmit = async (data: yup.InferType<typeof emailSchema>) => {\n setAddingEmailLoading(true);\n try {\n await user.createContactChannel({ type: 'email', value: data.email, usedForAuth: false });\n setAddedEmail(data.email);\n } finally {\n setAddingEmailLoading(false);\n }\n setAddingEmail(false);\n reset();\n };\n\n return (\n <div>\n <div className='flex flex-col md:flex-row justify-between mb-4 gap-4'>\n <Typography className='font-medium'>{t(\"Emails\")}</Typography>\n {addingEmail ? (\n <form\n onSubmit={(e) => {\n e.preventDefault();\n runAsynchronously(handleSubmit(onSubmit));\n }}\n className='flex flex-col'\n >\n <div className='flex gap-2'>\n <Input\n {...register(\"email\")}\n placeholder={t(\"Enter email\")}\n />\n <Button type=\"submit\" loading={addingEmailLoading}>\n {t(\"Add\")}\n </Button>\n <Button\n variant='secondary'\n onClick={() => {\n setAddingEmail(false);\n reset();\n }}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n {errors.email && <FormWarningText text={errors.email.message} />}\n </form>\n ) : (\n <div className='flex md:justify-end'>\n <Button variant='secondary' onClick={() => setAddingEmail(true)}>{t(\"Add an email\")}</Button>\n </div>\n )}\n </div>\n\n {contactChannels.length > 0 ? (\n <div className='border rounded-md'>\n <Table>\n <TableBody>\n {/*eslint-disable-next-line @typescript-eslint/no-unnecessary-condition*/}\n {contactChannels.filter(x => x.type === 'email')\n .sort((a, b) => {\n if (a.isPrimary !== b.isPrimary) return a.isPrimary ? -1 : 1;\n if (a.isVerified !== b.isVerified) return a.isVerified ? -1 : 1;\n return 0;\n })\n .map(x => (\n <TableRow key={x.id}>\n <TableCell>\n <div className='flex flex-col md:flex-row gap-2 md:gap-4'>\n {x.value}\n <div className='flex gap-2'>\n {x.isPrimary ? <Badge>{t(\"Primary\")}</Badge> : null}\n {!x.isVerified ? <Badge variant='destructive'>{t(\"Unverified\")}</Badge> : null}\n {x.usedForAuth ? <Badge variant='outline'>{t(\"Used for sign-in\")}</Badge> : null}\n </div>\n </div>\n </TableCell>\n <TableCell className=\"flex justify-end\">\n <ActionCell items={[\n ...(!x.isVerified ? [{\n item: t(\"Send verification email\"),\n onClick: async () => { await x.sendVerificationEmail(); },\n }] : []),\n ...(!x.isPrimary && x.isVerified ? [{\n item: t(\"Set as primary\"),\n onClick: async () => { await x.update({ isPrimary: true }); },\n }] :\n !x.isPrimary ? [{\n item: t(\"Set as primary\"),\n onClick: async () => {},\n disabled: true,\n disabledTooltip: t(\"Please verify your email first\"),\n }] : []),\n ...(!x.usedForAuth && x.isVerified ? [{\n item: t(\"Use for sign-in\"),\n onClick: async () => {\n try {\n await x.update({ usedForAuth: true });\n } catch (e) {\n if (e instanceof KnownErrors.ContactChannelAlreadyUsedForAuthBySomeoneElse) {\n alert(t(\"This email is already used for sign-in by another user.\"));\n }\n }\n }\n }] : []),\n ...(x.usedForAuth && !isLastEmail ? [{\n item: t(\"Stop using for sign-in\"),\n onClick: async () => { await x.update({ usedForAuth: false }); },\n }] : x.usedForAuth ? [{\n item: t(\"Stop using for sign-in\"),\n onClick: async () => {},\n disabled: true,\n disabledTooltip: t(\"You can not remove your last sign-in email\"),\n }] : []),\n ...(!isLastEmail || !x.usedForAuth ? [{\n item: t(\"Remove\"),\n onClick: async () => { await x.delete(); },\n danger: true,\n }] : [{\n item: t(\"Remove\"),\n onClick: async () => {},\n disabled: true,\n disabledTooltip: t(\"You can not remove your last sign-in email\"),\n }]),\n ]}/>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/components-page/account-settings/email-and-auth/mfa-section.tsx
31
+ var mfa_section_exports = {};
32
+ __export(mfa_section_exports, {
33
+ MfaSection: () => MfaSection
34
+ });
35
+ module.exports = __toCommonJS(mfa_section_exports);
36
+ var import_otp = require("@oslojs/otp");
37
+ var import_use_async_callback = require("@stackframe/stack-shared/dist/hooks/use-async-callback");
38
+ var import_crypto = require("@stackframe/stack-shared/dist/utils/crypto");
39
+ var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
40
+ var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
41
+ var import_stack_ui = require("@stackframe/stack-ui");
42
+ var QRCode = __toESM(require("qrcode"));
43
+ var import_react = require("react");
44
+ var import_hooks = require("../../../lib/hooks");
45
+ var import_translations = require("../../../lib/translations");
46
+ var import_section = require("../section");
47
+ var import_jsx_runtime = require("react/jsx-runtime");
48
+ function MfaSection() {
49
+ const { t } = (0, import_translations.useTranslation)();
50
+ const project = (0, import_hooks.useStackApp)().useProject();
51
+ const user = (0, import_hooks.useUser)({ or: "throw" });
52
+ const [generatedSecret, setGeneratedSecret] = (0, import_react.useState)(null);
53
+ const [qrCodeUrl, setQrCodeUrl] = (0, import_react.useState)(null);
54
+ const [mfaCode, setMfaCode] = (0, import_react.useState)("");
55
+ const [isMaybeWrong, setIsMaybeWrong] = (0, import_react.useState)(false);
56
+ const isEnabled = user.isMultiFactorRequired;
57
+ const [handleSubmit, isLoading] = (0, import_use_async_callback.useAsyncCallback)(async () => {
58
+ await user.update({
59
+ totpMultiFactorSecret: generatedSecret
60
+ });
61
+ setGeneratedSecret(null);
62
+ setQrCodeUrl(null);
63
+ setMfaCode("");
64
+ }, [generatedSecret, user]);
65
+ (0, import_react.useEffect)(() => {
66
+ setIsMaybeWrong(false);
67
+ (0, import_promises.runAsynchronouslyWithAlert)(async () => {
68
+ if (generatedSecret && (0, import_otp.verifyTOTP)(generatedSecret, 30, 6, mfaCode)) {
69
+ await handleSubmit();
70
+ }
71
+ setIsMaybeWrong(true);
72
+ });
73
+ }, [mfaCode, generatedSecret, handleSubmit]);
74
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
75
+ import_section.Section,
76
+ {
77
+ title: t("Multi-factor authentication"),
78
+ description: isEnabled ? t("Multi-factor authentication is currently enabled.") : t("Multi-factor authentication is currently disabled."),
79
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4", children: [
80
+ !isEnabled && generatedSecret && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
81
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: t("Scan this QR code with your authenticator app:") }),
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { width: 200, height: 200, src: qrCodeUrl ?? (0, import_errors.throwErr)("TOTP QR code failed to generate"), alt: t("TOTP multi-factor authentication QR code") }),
83
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: t("Then, enter your six-digit MFA code:") }),
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
85
+ import_stack_ui.Input,
86
+ {
87
+ value: mfaCode,
88
+ onChange: (e) => {
89
+ setIsMaybeWrong(false);
90
+ setMfaCode(e.target.value);
91
+ },
92
+ placeholder: "123456",
93
+ maxLength: 6,
94
+ disabled: isLoading
95
+ }
96
+ ),
97
+ isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: t("Incorrect code. Please try again.") }),
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
99
+ import_stack_ui.Button,
100
+ {
101
+ variant: "secondary",
102
+ onClick: () => {
103
+ setGeneratedSecret(null);
104
+ setQrCodeUrl(null);
105
+ setMfaCode("");
106
+ },
107
+ children: t("Cancel")
108
+ }
109
+ ) })
110
+ ] }),
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex gap-2", children: isEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
112
+ import_stack_ui.Button,
113
+ {
114
+ variant: "secondary",
115
+ onClick: async () => {
116
+ await user.update({
117
+ totpMultiFactorSecret: null
118
+ });
119
+ },
120
+ children: t("Disable MFA")
121
+ }
122
+ ) : !generatedSecret && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
123
+ import_stack_ui.Button,
124
+ {
125
+ variant: "secondary",
126
+ onClick: async () => {
127
+ const secret = (0, import_crypto.generateRandomValues)(new Uint8Array(20));
128
+ setQrCodeUrl(await generateTotpQrCode(project, user, secret));
129
+ setGeneratedSecret(secret);
130
+ },
131
+ children: t("Enable MFA")
132
+ }
133
+ ) })
134
+ ] })
135
+ }
136
+ );
137
+ }
138
+ async function generateTotpQrCode(project, user, secret) {
139
+ const uri = (0, import_otp.createTOTPKeyURI)(project.displayName, user.primaryEmail ?? user.id, secret, 30, 6);
140
+ return await QRCode.toDataURL(uri);
141
+ }
142
+ // Annotate the CommonJS export names for ESM import in node:
143
+ 0 && (module.exports = {
144
+ MfaSection
145
+ });
146
+ //# sourceMappingURL=mfa-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components-page/account-settings/email-and-auth/mfa-section.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { createTOTPKeyURI, verifyTOTP } from \"@oslojs/otp\";\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, Input, Typography } from \"@stackframe/stack-ui\";\nimport * as QRCode from 'qrcode';\nimport { useEffect, useState } from \"react\";\nimport { CurrentUser, Project } from '../../..';\nimport { useStackApp, useUser } from \"../../../lib/hooks\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { Section } from \"../section\";\n\nexport function MfaSection() {\n const { t } = useTranslation();\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 && verifyTOTP(generatedSecret, 30, 6, mfaCode)) {\n await handleSubmit();\n }\n setIsMaybeWrong(true);\n });\n }, [mfaCode, generatedSecret, handleSubmit]);\n\n return (\n <Section\n title={t(\"Multi-factor authentication\")}\n description={isEnabled\n ? t(\"Multi-factor authentication is currently enabled.\")\n : t(\"Multi-factor authentication is currently disabled.\")}\n >\n <div className='flex flex-col gap-4'>\n {!isEnabled && generatedSecret && (\n <>\n <Typography>{t(\"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={t(\"TOTP multi-factor authentication QR code\")} />\n <Typography>{t(\"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\">{t(\"Incorrect code. Please try again.\")}</Typography>\n )}\n <div className='flex'>\n <Button\n variant='secondary'\n onClick={() => {\n setGeneratedSecret(null);\n setQrCodeUrl(null);\n setMfaCode(\"\");\n }}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n </>\n )}\n <div className='flex gap-2'>\n {isEnabled ? (\n <Button\n variant='secondary'\n onClick={async () => {\n await user.update({\n totpMultiFactorSecret: null,\n });\n }}\n >\n {t(\"Disable MFA\")}\n </Button>\n ) : !generatedSecret && (\n <Button\n variant='secondary'\n onClick={async () => {\n const secret = generateRandomValues(new Uint8Array(20));\n setQrCodeUrl(await generateTotpQrCode(project, user, secret));\n setGeneratedSecret(secret);\n }}\n >\n {t(\"Enable MFA\")}\n </Button>\n )}\n </div>\n </div>\n </Section>\n );\n}\n\n\nasync function generateTotpQrCode(project: Project, user: CurrentUser, secret: Uint8Array) {\n const uri = createTOTPKeyURI(project.displayName, user.primaryEmail ?? user.id, secret, 30, 6);\n return await QRCode.toDataURL(uri) as any;\n}\n"],"mappings":"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","names":[]}