@stackframe/stack 2.8.3 → 2.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +151 -0
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
- package/dist/components-page/account-settings/api-keys/api-keys-page.js +70 -0
- package/dist/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
- package/dist/components-page/account-settings/editable-text.js +75 -0
- package/dist/components-page/account-settings/editable-text.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js +46 -0
- package/dist/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/emails-section.js +188 -0
- package/dist/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/mfa-section.js +146 -0
- package/dist/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/otp-section.js +89 -0
- package/dist/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/passkey-section.js +92 -0
- package/dist/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
- package/dist/components-page/account-settings/email-and-auth/password-section.js +181 -0
- package/dist/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
- package/dist/components-page/account-settings/page-layout.js +34 -0
- package/dist/components-page/account-settings/page-layout.js.map +1 -0
- package/dist/components-page/account-settings/profile-page/profile-page.js +75 -0
- package/dist/components-page/account-settings/profile-page/profile-page.js.map +1 -0
- package/dist/components-page/account-settings/section.js +44 -0
- package/dist/components-page/account-settings/section.js.map +1 -0
- package/dist/components-page/account-settings/settings/delete-account-section.js +87 -0
- package/dist/components-page/account-settings/settings/delete-account-section.js.map +1 -0
- package/dist/components-page/account-settings/settings/settings-page.js +40 -0
- package/dist/components-page/account-settings/settings/settings-page.js.map +1 -0
- package/dist/components-page/account-settings/settings/sign-out-section.js +54 -0
- package/dist/components-page/account-settings/settings/sign-out-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/leave-team-section.js +79 -0
- package/dist/components-page/account-settings/teams/leave-team-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-api-keys-section.js +89 -0
- package/dist/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-creation-page.js +92 -0
- package/dist/components-page/account-settings/teams/team-creation-page.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-display-name-section.js +57 -0
- package/dist/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js +131 -0
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-member-list-section.js +61 -0
- package/dist/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-page.js +50 -0
- package/dist/components-page/account-settings/teams/team-page.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-profile-image-section.js +59 -0
- package/dist/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
- package/dist/components-page/account-settings/teams/team-profile-user-section.js +56 -0
- package/dist/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
- package/dist/components-page/account-settings.js +16 -1173
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/section.js +6 -0
- package/dist/components-page/section.js.map +1 -0
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +126 -0
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +45 -0
- package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/editable-text.js +50 -0
- package/dist/esm/components-page/account-settings/editable-text.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js +21 -0
- package/dist/esm/components-page/account-settings/email-and-auth/email-and-auth-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +163 -0
- package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +111 -0
- package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js +64 -0
- package/dist/esm/components-page/account-settings/email-and-auth/otp-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js +67 -0
- package/dist/esm/components-page/account-settings/email-and-auth/passkey-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +146 -0
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/page-layout.js +9 -0
- package/dist/esm/components-page/account-settings/page-layout.js.map +1 -0
- package/dist/esm/components-page/account-settings/profile-page/profile-page.js +50 -0
- package/dist/esm/components-page/account-settings/profile-page/profile-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/section.js +19 -0
- package/dist/esm/components-page/account-settings/section.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/delete-account-section.js +62 -0
- package/dist/esm/components-page/account-settings/settings/delete-account-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/settings-page.js +15 -0
- package/dist/esm/components-page/account-settings/settings/settings-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/settings/sign-out-section.js +29 -0
- package/dist/esm/components-page/account-settings/settings/sign-out-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/leave-team-section.js +54 -0
- package/dist/esm/components-page/account-settings/teams/leave-team-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +64 -0
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-creation-page.js +67 -0
- package/dist/esm/components-page/account-settings/teams/team-creation-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-display-name-section.js +32 -0
- package/dist/esm/components-page/account-settings/teams/team-display-name-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +106 -0
- package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-member-list-section.js +36 -0
- package/dist/esm/components-page/account-settings/teams/team-member-list-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-page.js +25 -0
- package/dist/esm/components-page/account-settings/teams/team-page.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js +34 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-image-section.js.map +1 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js +31 -0
- package/dist/esm/components-page/account-settings/teams/team-profile-user-section.js.map +1 -0
- package/dist/esm/components-page/account-settings.js +14 -1158
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/section.js +4 -0
- package/dist/esm/components-page/section.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +79 -0
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/stack-app/projects/index.js.map +1 -1
- package/dist/esm/lib/translations.js +0 -1
- package/dist/esm/lib/translations.js.map +1 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +79 -0
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/stack-app/projects/index.js.map +1 -1
- package/dist/lib/translations.js +0 -1
- package/dist/lib/translations.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @stackframe/stack
|
|
2
2
|
|
|
3
|
+
## 2.8.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @stackframe/stack-shared@2.8.6
|
|
9
|
+
- @stackframe/stack-ui@2.8.6
|
|
10
|
+
- @stackframe/stack-sc@2.8.6
|
|
11
|
+
|
|
12
|
+
## 2.8.5
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Various changes
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @stackframe/stack-shared@2.8.5
|
|
19
|
+
- @stackframe/stack-ui@2.8.5
|
|
20
|
+
- @stackframe/stack-sc@2.8.5
|
|
21
|
+
|
|
22
|
+
## 2.8.4
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @stackframe/stack-shared@2.8.4
|
|
28
|
+
- @stackframe/stack-ui@2.8.4
|
|
29
|
+
- @stackframe/stack-sc@2.8.4
|
|
30
|
+
|
|
3
31
|
## 2.8.3
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -0,0 +1,151 @@
|
|
|
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/active-sessions/active-sessions-page.tsx
|
|
21
|
+
var active_sessions_page_exports = {};
|
|
22
|
+
__export(active_sessions_page_exports, {
|
|
23
|
+
ActiveSessionsPage: () => ActiveSessionsPage
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(active_sessions_page_exports);
|
|
26
|
+
var import_dates = require("@stackframe/stack-shared/dist/utils/dates");
|
|
27
|
+
var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
|
|
28
|
+
var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
|
|
29
|
+
var import_stack_ui = require("@stackframe/stack-ui");
|
|
30
|
+
var import_react = require("react");
|
|
31
|
+
var import_hooks = require("../../../lib/hooks");
|
|
32
|
+
var import_translations = require("../../../lib/translations");
|
|
33
|
+
var import_page_layout = require("../page-layout");
|
|
34
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
35
|
+
function ActiveSessionsPage() {
|
|
36
|
+
const { t } = (0, import_translations.useTranslation)();
|
|
37
|
+
const user = (0, import_hooks.useUser)({ or: "throw" });
|
|
38
|
+
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
39
|
+
const [isRevokingAll, setIsRevokingAll] = (0, import_react.useState)(false);
|
|
40
|
+
const [sessions, setSessions] = (0, import_react.useState)([]);
|
|
41
|
+
const [showConfirmRevokeAll, setShowConfirmRevokeAll] = (0, import_react.useState)(false);
|
|
42
|
+
(0, import_react.useEffect)(() => {
|
|
43
|
+
(0, import_promises.runAsynchronously)(async () => {
|
|
44
|
+
setIsLoading(true);
|
|
45
|
+
const sessionsData = await user.getActiveSessions();
|
|
46
|
+
const enhancedSessions = sessionsData;
|
|
47
|
+
setSessions(enhancedSessions);
|
|
48
|
+
setIsLoading(false);
|
|
49
|
+
});
|
|
50
|
+
}, [user]);
|
|
51
|
+
const handleRevokeSession = async (sessionId) => {
|
|
52
|
+
try {
|
|
53
|
+
await user.revokeSession(sessionId);
|
|
54
|
+
setSessions((prev) => prev.filter((session) => session.id !== sessionId));
|
|
55
|
+
} catch (error) {
|
|
56
|
+
(0, import_errors.captureError)("Failed to revoke session", { sessionId, error });
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const handleRevokeAllSessions = async () => {
|
|
61
|
+
setIsRevokingAll(true);
|
|
62
|
+
try {
|
|
63
|
+
const deletionPromises = sessions.filter((session) => !session.isCurrentSession).map((session) => user.revokeSession(session.id));
|
|
64
|
+
await Promise.all(deletionPromises);
|
|
65
|
+
setSessions((prevSessions) => prevSessions.filter((session) => session.isCurrentSession));
|
|
66
|
+
} catch (error) {
|
|
67
|
+
(0, import_errors.captureError)("Failed to revoke all sessions", { error, sessionIds: sessions.map((session) => session.id) });
|
|
68
|
+
throw error;
|
|
69
|
+
} finally {
|
|
70
|
+
setIsRevokingAll(false);
|
|
71
|
+
setShowConfirmRevokeAll(false);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_page_layout.PageLayout, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
75
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
76
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { className: "font-medium", children: t("Active Sessions") }),
|
|
77
|
+
sessions.filter((s) => !s.isCurrentSession).length > 0 && !isLoading && (showConfirmRevokeAll ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
|
|
78
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
79
|
+
import_stack_ui.Button,
|
|
80
|
+
{
|
|
81
|
+
variant: "destructive",
|
|
82
|
+
size: "sm",
|
|
83
|
+
loading: isRevokingAll,
|
|
84
|
+
onClick: handleRevokeAllSessions,
|
|
85
|
+
children: t("Confirm")
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
89
|
+
import_stack_ui.Button,
|
|
90
|
+
{
|
|
91
|
+
variant: "secondary",
|
|
92
|
+
size: "sm",
|
|
93
|
+
disabled: isRevokingAll,
|
|
94
|
+
onClick: () => setShowConfirmRevokeAll(false),
|
|
95
|
+
children: t("Cancel")
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
99
|
+
import_stack_ui.Button,
|
|
100
|
+
{
|
|
101
|
+
variant: "outline",
|
|
102
|
+
size: "sm",
|
|
103
|
+
onClick: () => setShowConfirmRevokeAll(true),
|
|
104
|
+
children: t("Revoke All Other Sessions")
|
|
105
|
+
}
|
|
106
|
+
))
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", className: "mb-4", children: t("These are devices where you're currently logged in. You can revoke access to end a session.") }),
|
|
109
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Skeleton, { className: "h-[300px] w-full rounded-md" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "border rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Table, { children: [
|
|
110
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.TableRow, { children: [
|
|
111
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[200px]", children: t("Session") }),
|
|
112
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[150px]", children: t("IP Address") }),
|
|
113
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[150px]", children: t("Location") }),
|
|
114
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[150px]", children: t("Last used") }),
|
|
115
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[80px]" })
|
|
116
|
+
] }) }),
|
|
117
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableBody, { children: sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { colSpan: 5, className: "text-center py-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", children: t("No active sessions found") }) }) }) : sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.TableRow, { children: [
|
|
118
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
119
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: session.isCurrentSession ? t("Current Session") : t("Other Session") }),
|
|
120
|
+
session.isImpersonation && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Badge, { variant: "secondary", className: "w-fit mt-1", children: t("Impersonation") }),
|
|
121
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", children: t("Signed in {time}", { time: new Date(session.createdAt).toLocaleDateString() }) })
|
|
122
|
+
] }) }),
|
|
123
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: session.geoInfo?.ip || t("-") }) }),
|
|
124
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: session.geoInfo?.cityName || t("Unknown") }) }),
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
126
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: session.lastUsedAt ? (0, import_dates.fromNow)(new Date(session.lastUsedAt)) : t("Never") }),
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "footnote", title: session.lastUsedAt ? new Date(session.lastUsedAt).toLocaleString() : "", children: session.lastUsedAt ? new Date(session.lastUsedAt).toLocaleDateString() : "" })
|
|
128
|
+
] }) }),
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { align: "right", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
130
|
+
import_stack_ui.ActionCell,
|
|
131
|
+
{
|
|
132
|
+
items: [
|
|
133
|
+
{
|
|
134
|
+
item: t("Revoke"),
|
|
135
|
+
onClick: () => handleRevokeSession(session.id),
|
|
136
|
+
danger: true,
|
|
137
|
+
disabled: session.isCurrentSession,
|
|
138
|
+
disabledTooltip: session.isCurrentSession ? t("You cannot revoke your current session") : void 0
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
) })
|
|
143
|
+
] }, session.id)) })
|
|
144
|
+
] }) })
|
|
145
|
+
] }) });
|
|
146
|
+
}
|
|
147
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
148
|
+
0 && (module.exports = {
|
|
149
|
+
ActiveSessionsPage
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=active-sessions-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components-page/account-settings/active-sessions/active-sessions-page.tsx"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { fromNow } from \"@stackframe/stack-shared/dist/utils/dates\";\nimport { captureError } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { ActionCell, Badge, Button, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from \"@stackframe/stack-ui\";\nimport { useEffect, useState } from \"react\";\nimport { useUser } from \"../../../lib/hooks\";\nimport { ActiveSession } from \"../../../lib/stack-app/users\";\nimport { useTranslation } from \"../../../lib/translations\";\nimport { PageLayout } from \"../page-layout\";\n\nexport function ActiveSessionsPage() {\n const { t } = useTranslation();\n const user = useUser({ or: \"throw\" });\n const [isLoading, setIsLoading] = useState(true);\n const [isRevokingAll, setIsRevokingAll] = useState(false);\n const [sessions, setSessions] = useState<ActiveSession[]>([]);\n const [showConfirmRevokeAll, setShowConfirmRevokeAll] = useState(false);\n\n // Fetch sessions when component mounts\n useEffect(() => {\n runAsynchronously(async () => {\n setIsLoading(true);\n const sessionsData = await user.getActiveSessions();\n const enhancedSessions = sessionsData;\n setSessions(enhancedSessions);\n setIsLoading(false);\n });\n }, [user]);\n\n const handleRevokeSession = async (sessionId: string) => {\n try {\n await user.revokeSession(sessionId);\n\n // Remove the session from the list\n setSessions(prev => prev.filter(session => session.id !== sessionId));\n } catch (error) {\n captureError(\"Failed to revoke session\", { sessionId ,error });\n throw error;\n }\n };\n\n const handleRevokeAllSessions = async () => {\n setIsRevokingAll(true);\n try {\n const deletionPromises = sessions\n .filter(session => !session.isCurrentSession)\n .map(session => user.revokeSession(session.id));\n await Promise.all(deletionPromises);\n setSessions(prevSessions => prevSessions.filter(session => session.isCurrentSession));\n } catch (error) {\n captureError(\"Failed to revoke all sessions\", { error, sessionIds: sessions.map(session => session.id) });\n throw error;\n } finally {\n setIsRevokingAll(false);\n setShowConfirmRevokeAll(false);\n }\n };\n\n return (\n <PageLayout>\n <div>\n <div className=\"flex justify-between items-center mb-2\">\n <Typography className='font-medium'>{t(\"Active Sessions\")}</Typography>\n {sessions.filter(s => !s.isCurrentSession).length > 0 && !isLoading && (\n showConfirmRevokeAll ? (\n <div className=\"flex gap-2\">\n <Button\n variant=\"destructive\"\n size=\"sm\"\n loading={isRevokingAll}\n onClick={handleRevokeAllSessions}\n >\n {t(\"Confirm\")}\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n disabled={isRevokingAll}\n onClick={() => setShowConfirmRevokeAll(false)}\n >\n {t(\"Cancel\")}\n </Button>\n </div>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowConfirmRevokeAll(true)}\n >\n {t(\"Revoke All Other Sessions\")}\n </Button>\n )\n )}\n </div>\n <Typography variant='secondary' type='footnote' className=\"mb-4\">\n {t(\"These are devices where you're currently logged in. You can revoke access to end a session.\")}\n </Typography>\n\n {isLoading ? (\n <Skeleton className=\"h-[300px] w-full rounded-md\" />\n ) : (\n <div className='border rounded-md'>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[200px]\">{t(\"Session\")}</TableHead>\n <TableHead className=\"w-[150px]\">{t(\"IP Address\")}</TableHead>\n <TableHead className=\"w-[150px]\">{t(\"Location\")}</TableHead>\n <TableHead className=\"w-[150px]\">{t(\"Last used\")}</TableHead>\n <TableHead className=\"w-[80px]\"></TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {sessions.length === 0 ? (\n <TableRow>\n <TableCell colSpan={5} className=\"text-center py-6\">\n <Typography variant=\"secondary\">{t(\"No active sessions found\")}</Typography>\n </TableCell>\n </TableRow>\n ) : (\n sessions.map((session) => (\n <TableRow key={session.id}>\n <TableCell>\n <div className=\"flex flex-col\">\n {/* We currently do not save any usefull information about the user, in the future, the name should probably say what kind of session it is (e.g. cli, browser, maybe what auth method was used) */}\n <Typography>{session.isCurrentSession ? t(\"Current Session\") : t(\"Other Session\")}</Typography>\n {session.isImpersonation && <Badge variant=\"secondary\" className=\"w-fit mt-1\">{t(\"Impersonation\")}</Badge>}\n <Typography variant='secondary' type='footnote'>\n {t(\"Signed in {time}\", { time: new Date(session.createdAt).toLocaleDateString() })}\n </Typography>\n </div>\n </TableCell>\n <TableCell>\n <Typography>{session.geoInfo?.ip || t('-')}</Typography>\n </TableCell>\n <TableCell>\n <Typography>{session.geoInfo?.cityName || t('Unknown')}</Typography>\n </TableCell>\n <TableCell>\n <div className=\"flex flex-col\">\n <Typography>{session.lastUsedAt ? fromNow(new Date(session.lastUsedAt)) : t(\"Never\")}</Typography>\n <Typography variant='secondary' type='footnote' title={session.lastUsedAt ? new Date(session.lastUsedAt).toLocaleString() : \"\"}>\n {session.lastUsedAt ? new Date(session.lastUsedAt).toLocaleDateString() : \"\"}\n </Typography>\n </div>\n </TableCell>\n <TableCell align=\"right\">\n <ActionCell\n items={[\n {\n item: t(\"Revoke\"),\n onClick: () => handleRevokeSession(session.id),\n danger: true,\n disabled: session.isCurrentSession,\n disabledTooltip: session.isCurrentSession ? t(\"You cannot revoke your current session\") : undefined,\n },\n ]}\n />\n </TableCell>\n </TableRow>\n ))\n )}\n </TableBody>\n </Table>\n </div>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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
|