@strapi-community/plugin-better-auth-dashboard 1.0.0-alpha.5 → 1.0.0-alpha.7
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/README.md +101 -0
- package/dist/admin/{Root-CFxaaNC8.js → Root-BUuPFmkA.js} +67 -29
- package/dist/admin/Root-BUuPFmkA.js.map +1 -0
- package/dist/admin/{Root-CJNOLkgF.mjs → Root-Rol-uNmC.mjs} +67 -29
- package/dist/admin/Root-Rol-uNmC.mjs.map +1 -0
- package/dist/admin/{index-C4--Z2Qg.js → index-CYaQ-gs-.js} +25 -1
- package/dist/admin/index-CYaQ-gs-.js.map +1 -0
- package/dist/admin/{index-QYGGdXAd.mjs → index-Y9SjzGQY.mjs} +25 -1
- package/dist/admin/index-Y9SjzGQY.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +2 -1
- package/dist/admin/index.mjs.map +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +1 -0
- package/dist/server/index.mjs.map +1 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Strapi + Better Auth Dashboard
|
|
2
|
+
|
|
3
|
+
An admin panel dashboard plugin for [Strapi](https://strapi.io) that provides user management, session monitoring, and analytics for [Better Auth](https://better-auth.com) authentication.
|
|
4
|
+
|
|
5
|
+
> [!CAUTION]
|
|
6
|
+
> This plugin is in BETA state. It is by no means considered stable and should not be used in production. If you want to contribute to its development, please contact any of the maintainers.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- Overview page with user metrics, growth charts, and cohort retention analysis
|
|
11
|
+
- User management: search, create, edit, delete, and ban users
|
|
12
|
+
- Session management: view and revoke active sessions per user from the user detail drawer
|
|
13
|
+
- Organization management (when the Better Auth organization plugin is enabled)
|
|
14
|
+
- Real-time active user tracking (DAU / WAU / MAU)
|
|
15
|
+
- Automatic feature detection — ban, 2FA, email verification, and organization UI adapts to your Better Auth config
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
The additional dashboard plugin requires you to have the Better Auth plugin already installed and configured.
|
|
20
|
+
|
|
21
|
+
### Packages
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @better-auth/infra @strapi-community/plugin-better-auth-dashboard
|
|
25
|
+
# or
|
|
26
|
+
yarn add @better-auth/infra @strapi-community/plugin-better-auth-dashboard
|
|
27
|
+
# or
|
|
28
|
+
pnpm add @better-auth/infra @strapi-community/plugin-better-auth-dashboard
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Configuration
|
|
32
|
+
|
|
33
|
+
> [!CAUTION]
|
|
34
|
+
> This plugin only works if you have not changed the `basePath` of Better Auth. It needs to be the default `/api/auth` path.
|
|
35
|
+
|
|
36
|
+
In order to run this plugin you need to configure the `dash()` and `jwt()` plugins from Better Auth.
|
|
37
|
+
|
|
38
|
+
```typescript title="src/lib/auth.ts"
|
|
39
|
+
import { dash } from "@better-auth/infra";
|
|
40
|
+
import { betterAuth } from 'better-auth';
|
|
41
|
+
import { jwt } from 'better-auth/plugins';
|
|
42
|
+
import { strapiAdapter } from '@strapi-community/plugin-better-auth';
|
|
43
|
+
|
|
44
|
+
export const auth = betterAuth({
|
|
45
|
+
database: strapiAdapter(),
|
|
46
|
+
trustedOrigins: ['http://localhost:3000'],
|
|
47
|
+
plugins: [
|
|
48
|
+
jwt(),
|
|
49
|
+
dash({
|
|
50
|
+
apiUrl: process.env.STRAPI_URL || "http://localhost:1337",
|
|
51
|
+
apiKey:
|
|
52
|
+
process.env.BETTER_AUTH_DASHBOARD_SECRET ||
|
|
53
|
+
"strapi-internal-dashboard-key",
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
advanced: {
|
|
57
|
+
database: {
|
|
58
|
+
generateId: 'serial',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
emailAndPassword: {
|
|
62
|
+
enabled: true,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Start Strapi
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm develop
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The dashboard is now available in the Strapi admin panel.
|
|
74
|
+
|
|
75
|
+
## Pages
|
|
76
|
+
|
|
77
|
+
| Tab | Description |
|
|
78
|
+
| --- | ----------- |
|
|
79
|
+
| **Overview** | User metrics, growth charts, cohort retention, active user rings |
|
|
80
|
+
| **Users** | Searchable user table with create, edit, delete, ban, and session revoke per user |
|
|
81
|
+
| **Organizations** | Organization list with member management (requires Better Auth `organization` plugin) |
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- `@strapi-community/plugin-better-auth` installed and configured
|
|
86
|
+
- Strapi v5.45.0+
|
|
87
|
+
- Better Auth >= 1.4.0
|
|
88
|
+
|
|
89
|
+
## Resources
|
|
90
|
+
|
|
91
|
+
- [Documentation](https://strapi-community.github.io/plugin-better-auth/docs/better-auth/dashboard)
|
|
92
|
+
- [Better Auth Documentation](https://better-auth.com)
|
|
93
|
+
- [Strapi Documentation](https://docs.strapi.io)
|
|
94
|
+
|
|
95
|
+
## Authors
|
|
96
|
+
|
|
97
|
+
- [Boaz Poolman](https://github.com/boazpoolman)
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
See the [LICENSE](./LICENSE.md) file for licensing information.
|
|
@@ -9,7 +9,7 @@ const client$2 = require("@better-auth/infra/client");
|
|
|
9
9
|
const client$1 = require("better-auth/client");
|
|
10
10
|
const icons = require("@strapi/icons");
|
|
11
11
|
const admin = require("@strapi/strapi/admin");
|
|
12
|
-
const index = require("./index-
|
|
12
|
+
const index = require("./index-CYaQ-gs-.js");
|
|
13
13
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
14
14
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
15
15
|
const dashPathMethods = () => ({
|
|
@@ -957,6 +957,21 @@ function CustomFieldsSection({
|
|
|
957
957
|
)) })
|
|
958
958
|
] });
|
|
959
959
|
}
|
|
960
|
+
function EditViewSidePanels({ model, documentId, document: document2 }) {
|
|
961
|
+
const panels = index.getEditViewSidePanels(model);
|
|
962
|
+
if (panels.length === 0) return null;
|
|
963
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: panels.map(({ id, title, Component }) => /* @__PURE__ */ jsxRuntime.jsxs(FormSection, { children: [
|
|
964
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: title }),
|
|
965
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
966
|
+
Component,
|
|
967
|
+
{
|
|
968
|
+
model,
|
|
969
|
+
documentId,
|
|
970
|
+
document: document2
|
|
971
|
+
}
|
|
972
|
+
)
|
|
973
|
+
] }, id)) });
|
|
974
|
+
}
|
|
960
975
|
const SYSTEM_FIELDS = /* @__PURE__ */ new Set([
|
|
961
976
|
"id",
|
|
962
977
|
"documentId",
|
|
@@ -1136,9 +1151,13 @@ function OrganizationDetail({
|
|
|
1136
1151
|
body
|
|
1137
1152
|
);
|
|
1138
1153
|
},
|
|
1139
|
-
onSuccess: () => {
|
|
1154
|
+
onSuccess: async () => {
|
|
1155
|
+
await qc.invalidateQueries({
|
|
1156
|
+
queryKey: ["dash-strapi-org", organizationId]
|
|
1157
|
+
});
|
|
1140
1158
|
qc.invalidateQueries({ queryKey: ["dash-org", organizationId] });
|
|
1141
1159
|
qc.invalidateQueries({ queryKey: ["dash-organizations"] });
|
|
1160
|
+
qc.invalidateQueries({ queryKey: ["dash-strapi-org", organizationId] });
|
|
1142
1161
|
setEditName(void 0);
|
|
1143
1162
|
setEditSlug(void 0);
|
|
1144
1163
|
setEditLogo(void 0);
|
|
@@ -1467,33 +1486,43 @@ function OrganizationDetail({
|
|
|
1467
1486
|
}
|
|
1468
1487
|
)
|
|
1469
1488
|
] }),
|
|
1470
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1471
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1472
|
-
|
|
1473
|
-
|
|
1489
|
+
/* @__PURE__ */ jsxRuntime.jsxs(EditSidebar, { children: [
|
|
1490
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FormSection, { children: [
|
|
1491
|
+
/* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { children: "Details" }),
|
|
1492
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1493
|
+
"div",
|
|
1494
|
+
{
|
|
1495
|
+
style: {
|
|
1496
|
+
display: "grid",
|
|
1497
|
+
gridTemplateColumns: "1fr 1fr",
|
|
1498
|
+
gap: 12
|
|
1499
|
+
},
|
|
1500
|
+
children: [
|
|
1501
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetaItem, { style: { gridColumn: "1 / -1" }, children: [
|
|
1502
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaKey, { children: "Organization ID" }),
|
|
1503
|
+
/* @__PURE__ */ jsxRuntime.jsx(MonoChip, { children: org?.id })
|
|
1504
|
+
] }),
|
|
1505
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetaItem, { children: [
|
|
1506
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaKey, { children: "Members" }),
|
|
1507
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaVal, { children: org?.memberCount ?? 0 })
|
|
1508
|
+
] }),
|
|
1509
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetaItem, { children: [
|
|
1510
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaKey, { children: "Created" }),
|
|
1511
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaVal, { children: org?.createdAt ? new Date(org.createdAt).toLocaleDateString() : "—" })
|
|
1512
|
+
] })
|
|
1513
|
+
]
|
|
1514
|
+
}
|
|
1515
|
+
)
|
|
1516
|
+
] }),
|
|
1517
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1518
|
+
EditViewSidePanels,
|
|
1474
1519
|
{
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
gap: 12
|
|
1479
|
-
},
|
|
1480
|
-
children: [
|
|
1481
|
-
/* @__PURE__ */ jsxRuntime.jsxs(MetaItem, { style: { gridColumn: "1 / -1" }, children: [
|
|
1482
|
-
/* @__PURE__ */ jsxRuntime.jsx(MetaKey, { children: "Organization ID" }),
|
|
1483
|
-
/* @__PURE__ */ jsxRuntime.jsx(MonoChip, { children: org?.id })
|
|
1484
|
-
] }),
|
|
1485
|
-
/* @__PURE__ */ jsxRuntime.jsxs(MetaItem, { children: [
|
|
1486
|
-
/* @__PURE__ */ jsxRuntime.jsx(MetaKey, { children: "Members" }),
|
|
1487
|
-
/* @__PURE__ */ jsxRuntime.jsx(MetaVal, { children: org?.memberCount ?? 0 })
|
|
1488
|
-
] }),
|
|
1489
|
-
/* @__PURE__ */ jsxRuntime.jsxs(MetaItem, { children: [
|
|
1490
|
-
/* @__PURE__ */ jsxRuntime.jsx(MetaKey, { children: "Created" }),
|
|
1491
|
-
/* @__PURE__ */ jsxRuntime.jsx(MetaVal, { children: org?.createdAt ? new Date(org.createdAt).toLocaleDateString() : "—" })
|
|
1492
|
-
] })
|
|
1493
|
-
]
|
|
1520
|
+
model: "plugin::better-auth.organization",
|
|
1521
|
+
documentId: strapiOrgQuery.data?.documentId,
|
|
1522
|
+
document: strapiOrgQuery.data ?? void 0
|
|
1494
1523
|
}
|
|
1495
1524
|
)
|
|
1496
|
-
] })
|
|
1525
|
+
] })
|
|
1497
1526
|
] }) }),
|
|
1498
1527
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: "members", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 5, paddingTop: 6, children: [
|
|
1499
1528
|
/* @__PURE__ */ jsxRuntime.jsxs(FormSection, { children: [
|
|
@@ -4073,10 +4102,10 @@ function UserDetailDrawer({
|
|
|
4073
4102
|
body
|
|
4074
4103
|
);
|
|
4075
4104
|
},
|
|
4076
|
-
onSuccess: () => {
|
|
4105
|
+
onSuccess: async () => {
|
|
4106
|
+
await qc.invalidateQueries({ queryKey: ["dash-strapi-user", userId] });
|
|
4077
4107
|
qc.invalidateQueries({ queryKey: ["dash-user", userId] });
|
|
4078
4108
|
qc.invalidateQueries({ queryKey: ["dash-users"] });
|
|
4079
|
-
qc.invalidateQueries({ queryKey: ["dash-strapi-user", userId] });
|
|
4080
4109
|
setEditName(void 0);
|
|
4081
4110
|
setEditEmail(void 0);
|
|
4082
4111
|
setEditEmailVerified(void 0);
|
|
@@ -4573,7 +4602,15 @@ function UserDetailDrawer({
|
|
|
4573
4602
|
}
|
|
4574
4603
|
)
|
|
4575
4604
|
] })
|
|
4576
|
-
] })
|
|
4605
|
+
] }),
|
|
4606
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4607
|
+
EditViewSidePanels,
|
|
4608
|
+
{
|
|
4609
|
+
model: "plugin::better-auth.user",
|
|
4610
|
+
documentId: strapiUserQuery.data?.documentId,
|
|
4611
|
+
document: strapiUserQuery.data ?? void 0
|
|
4612
|
+
}
|
|
4613
|
+
)
|
|
4577
4614
|
] })
|
|
4578
4615
|
] }) }),
|
|
4579
4616
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: "security", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 5, paddingTop: 6, children: [
|
|
@@ -5686,3 +5723,4 @@ function Root() {
|
|
|
5686
5723
|
}
|
|
5687
5724
|
exports.Root = Root;
|
|
5688
5725
|
exports.default = Root;
|
|
5726
|
+
//# sourceMappingURL=Root-BUuPFmkA.js.map
|