@codaijs/keel 0.2.2 → 0.2.4
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/dist/__tests__/sail-installer.test.js +25 -25
- package/dist/sail-installer.js +174 -174
- package/dist/scaffold.js +68 -68
- package/package.json +58 -58
- package/sails/_template/addon.json +20 -20
- package/sails/_template/install.ts +402 -402
- package/sails/admin-dashboard/README.md +117 -117
- package/sails/admin-dashboard/addon.json +28 -28
- package/sails/admin-dashboard/files/backend/middleware/admin.ts +34 -34
- package/sails/admin-dashboard/files/backend/routes/admin.ts +243 -243
- package/sails/admin-dashboard/files/frontend/components/admin/StatsCard.tsx +40 -40
- package/sails/admin-dashboard/files/frontend/components/admin/UsersTable.tsx +240 -240
- package/sails/admin-dashboard/files/frontend/hooks/useAdmin.ts +149 -149
- package/sails/admin-dashboard/files/frontend/pages/admin/Dashboard.tsx +173 -173
- package/sails/admin-dashboard/files/frontend/pages/admin/UserDetail.tsx +203 -203
- package/sails/admin-dashboard/install.ts +305 -305
- package/sails/analytics/README.md +178 -178
- package/sails/analytics/addon.json +27 -27
- package/sails/analytics/files/frontend/components/AnalyticsProvider.tsx +58 -58
- package/sails/analytics/files/frontend/hooks/useAnalytics.ts +64 -64
- package/sails/analytics/files/frontend/lib/analytics.ts +103 -103
- package/sails/analytics/install.ts +297 -297
- package/sails/file-uploads/addon.json +30 -30
- package/sails/file-uploads/files/backend/routes/files.ts +198 -198
- package/sails/file-uploads/files/backend/schema/files.ts +36 -36
- package/sails/file-uploads/files/backend/services/file-storage.ts +128 -128
- package/sails/file-uploads/files/frontend/components/FileList.tsx +248 -248
- package/sails/file-uploads/files/frontend/components/FileUploadButton.tsx +147 -147
- package/sails/file-uploads/files/frontend/hooks/useFileUpload.ts +106 -106
- package/sails/file-uploads/files/frontend/hooks/useFiles.ts +118 -118
- package/sails/file-uploads/files/frontend/pages/Files.tsx +37 -37
- package/sails/file-uploads/install.ts +466 -466
- package/sails/gdpr/README.md +174 -174
- package/sails/gdpr/addon.json +27 -27
- package/sails/gdpr/files/backend/routes/gdpr.ts +140 -140
- package/sails/gdpr/files/backend/services/gdpr.ts +293 -293
- package/sails/gdpr/files/frontend/components/auth/ConsentCheckboxes.tsx +97 -97
- package/sails/gdpr/files/frontend/components/gdpr/AccountDeletionRequest.tsx +192 -192
- package/sails/gdpr/files/frontend/components/gdpr/DataExportButton.tsx +75 -75
- package/sails/gdpr/files/frontend/pages/PrivacyPolicy.tsx +186 -186
- package/sails/gdpr/install.ts +756 -756
- package/sails/google-oauth/README.md +121 -121
- package/sails/google-oauth/addon.json +22 -22
- package/sails/google-oauth/files/GoogleButton.tsx +50 -50
- package/sails/google-oauth/install.ts +252 -252
- package/sails/i18n/README.md +193 -193
- package/sails/i18n/addon.json +30 -30
- package/sails/i18n/files/frontend/components/LanguageSwitcher.tsx +108 -108
- package/sails/i18n/files/frontend/hooks/useLanguage.ts +31 -31
- package/sails/i18n/files/frontend/lib/i18n.ts +32 -32
- package/sails/i18n/files/frontend/locales/de/common.json +44 -44
- package/sails/i18n/files/frontend/locales/en/common.json +44 -44
- package/sails/i18n/install.ts +407 -407
- package/sails/push-notifications/README.md +163 -163
- package/sails/push-notifications/addon.json +31 -31
- package/sails/push-notifications/files/backend/routes/notifications.ts +153 -153
- package/sails/push-notifications/files/backend/schema/notifications.ts +31 -31
- package/sails/push-notifications/files/backend/services/notifications.ts +117 -117
- package/sails/push-notifications/files/frontend/components/PushNotificationInit.tsx +12 -12
- package/sails/push-notifications/files/frontend/hooks/usePushNotifications.ts +154 -154
- package/sails/push-notifications/install.ts +384 -384
- package/sails/r2-storage/addon.json +29 -29
- package/sails/r2-storage/files/backend/services/storage.ts +71 -71
- package/sails/r2-storage/files/frontend/components/ProfilePictureUpload.tsx +167 -167
- package/sails/r2-storage/install.ts +412 -412
- package/sails/rate-limiting/addon.json +20 -20
- package/sails/rate-limiting/files/backend/middleware/rate-limit-store.ts +104 -104
- package/sails/rate-limiting/files/backend/middleware/rate-limit.ts +137 -137
- package/sails/rate-limiting/install.ts +300 -300
- package/sails/registry.json +107 -107
- package/sails/stripe/README.md +214 -214
- package/sails/stripe/addon.json +24 -24
- package/sails/stripe/files/backend/routes/stripe.ts +154 -154
- package/sails/stripe/files/backend/schema/stripe.ts +74 -74
- package/sails/stripe/files/backend/services/stripe.ts +224 -224
- package/sails/stripe/files/frontend/components/SubscriptionStatus.tsx +135 -135
- package/sails/stripe/files/frontend/hooks/useSubscription.ts +86 -86
- package/sails/stripe/files/frontend/pages/Checkout.tsx +116 -116
- package/sails/stripe/files/frontend/pages/Pricing.tsx +226 -226
- package/sails/stripe/install.ts +378 -378
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
# Admin Dashboard Sail
|
|
2
|
-
|
|
3
|
-
Adds a user management and metrics dashboard to your keel application. Access is restricted to email addresses listed in the `ADMIN_EMAILS` environment variable.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Dashboard with stats cards (total users, new this week/month, active sessions)
|
|
8
|
-
- User signup chart (last 30 days) powered by recharts
|
|
9
|
-
- Users table with search, sorting, and pagination
|
|
10
|
-
- User detail view with admin actions
|
|
11
|
-
- Admin actions: verify email, delete user
|
|
12
|
-
- Access controlled via `ADMIN_EMAILS` environment variable
|
|
13
|
-
- Admin middleware for backend route protection
|
|
14
|
-
|
|
15
|
-
## Prerequisites
|
|
16
|
-
|
|
17
|
-
- A working keel project with BetterAuth authentication
|
|
18
|
-
- At least one user account with an email you want to use as admin
|
|
19
|
-
|
|
20
|
-
## Installation
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx tsx sails/admin-dashboard/install.ts
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
The installer will prompt for admin email addresses and configure everything automatically.
|
|
27
|
-
|
|
28
|
-
## Manual Setup
|
|
29
|
-
|
|
30
|
-
### 1. Environment Variables
|
|
31
|
-
|
|
32
|
-
Add the following to your `.env`:
|
|
33
|
-
|
|
34
|
-
```env
|
|
35
|
-
ADMIN_EMAILS=admin@example.com,another-admin@example.com
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Multiple emails are separated by commas.
|
|
39
|
-
|
|
40
|
-
### 2. Access the Dashboard
|
|
41
|
-
|
|
42
|
-
1. Start your dev server: `npm run dev`
|
|
43
|
-
2. Log in with an admin email address
|
|
44
|
-
3. Navigate to `/admin`
|
|
45
|
-
|
|
46
|
-
## Architecture
|
|
47
|
-
|
|
48
|
-
### Backend
|
|
49
|
-
|
|
50
|
-
**Admin Middleware** (`src/middleware/admin.ts`)
|
|
51
|
-
|
|
52
|
-
Checks if the authenticated user's email is in the `ADMIN_EMAILS` list. Returns 403 if not. Must be used after `requireAuth`.
|
|
53
|
-
|
|
54
|
-
**Admin Routes** (`src/routes/admin.ts`)
|
|
55
|
-
|
|
56
|
-
| Method | Path | Description |
|
|
57
|
-
|--------|------|-------------|
|
|
58
|
-
| GET | /api/admin/users | List users (paginated, searchable) |
|
|
59
|
-
| GET | /api/admin/users/:id | Get user details |
|
|
60
|
-
| PATCH | /api/admin/users/:id | Update user (name, emailVerified) |
|
|
61
|
-
| DELETE | /api/admin/users/:id | Delete a user |
|
|
62
|
-
| GET | /api/admin/stats | Dashboard statistics |
|
|
63
|
-
|
|
64
|
-
All routes require authentication + admin privileges.
|
|
65
|
-
|
|
66
|
-
### Frontend
|
|
67
|
-
|
|
68
|
-
**Dashboard** (`/admin`)
|
|
69
|
-
|
|
70
|
-
The main admin page showing:
|
|
71
|
-
- Stats cards with key metrics
|
|
72
|
-
- Line chart of user signups over the last 30 days
|
|
73
|
-
- Searchable, sortable users table
|
|
74
|
-
|
|
75
|
-
**User Detail** (`/admin/users/:id`)
|
|
76
|
-
|
|
77
|
-
Detailed view of a single user with:
|
|
78
|
-
- User profile information
|
|
79
|
-
- Active session count
|
|
80
|
-
- Admin actions (verify email, delete user)
|
|
81
|
-
|
|
82
|
-
### Components
|
|
83
|
-
|
|
84
|
-
- `StatsCard` - Reusable card for displaying a metric with optional trend
|
|
85
|
-
- `UsersTable` - Table with search, sort, and pagination
|
|
86
|
-
|
|
87
|
-
### Hooks
|
|
88
|
-
|
|
89
|
-
- `useAdminStats()` - Fetch dashboard statistics
|
|
90
|
-
- `useAdminUsers(page, search)` - Fetch paginated user list
|
|
91
|
-
- `fetchUser(id)` - Get single user details
|
|
92
|
-
- `updateUser(id, data)` - Update user fields
|
|
93
|
-
- `deleteUser(id)` - Delete a user
|
|
94
|
-
|
|
95
|
-
## Customization
|
|
96
|
-
|
|
97
|
-
### Adding Admin Link to Header
|
|
98
|
-
|
|
99
|
-
Add a link to the admin dashboard in your Header component for admin users:
|
|
100
|
-
|
|
101
|
-
```tsx
|
|
102
|
-
{isAuthenticated && isAdmin && (
|
|
103
|
-
<Link to="/admin" className="text-sm font-medium text-keel-gray-400 hover:text-white">
|
|
104
|
-
Admin
|
|
105
|
-
</Link>
|
|
106
|
-
)}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
You can check admin status by comparing the user's email against a list fetched from the backend, or by adding an admin check API endpoint.
|
|
110
|
-
|
|
111
|
-
### Extending the Dashboard
|
|
112
|
-
|
|
113
|
-
Add new stats cards by modifying `Dashboard.tsx` and adding corresponding backend queries in `routes/admin.ts`.
|
|
114
|
-
|
|
115
|
-
### Adding More Admin Actions
|
|
116
|
-
|
|
117
|
-
Extend the `PATCH /api/admin/users/:id` endpoint to support additional fields, or add new endpoints for other admin operations (e.g., ban user, reset password, impersonate).
|
|
1
|
+
# Admin Dashboard Sail
|
|
2
|
+
|
|
3
|
+
Adds a user management and metrics dashboard to your keel application. Access is restricted to email addresses listed in the `ADMIN_EMAILS` environment variable.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Dashboard with stats cards (total users, new this week/month, active sessions)
|
|
8
|
+
- User signup chart (last 30 days) powered by recharts
|
|
9
|
+
- Users table with search, sorting, and pagination
|
|
10
|
+
- User detail view with admin actions
|
|
11
|
+
- Admin actions: verify email, delete user
|
|
12
|
+
- Access controlled via `ADMIN_EMAILS` environment variable
|
|
13
|
+
- Admin middleware for backend route protection
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- A working keel project with BetterAuth authentication
|
|
18
|
+
- At least one user account with an email you want to use as admin
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx tsx sails/admin-dashboard/install.ts
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The installer will prompt for admin email addresses and configure everything automatically.
|
|
27
|
+
|
|
28
|
+
## Manual Setup
|
|
29
|
+
|
|
30
|
+
### 1. Environment Variables
|
|
31
|
+
|
|
32
|
+
Add the following to your `.env`:
|
|
33
|
+
|
|
34
|
+
```env
|
|
35
|
+
ADMIN_EMAILS=admin@example.com,another-admin@example.com
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Multiple emails are separated by commas.
|
|
39
|
+
|
|
40
|
+
### 2. Access the Dashboard
|
|
41
|
+
|
|
42
|
+
1. Start your dev server: `npm run dev`
|
|
43
|
+
2. Log in with an admin email address
|
|
44
|
+
3. Navigate to `/admin`
|
|
45
|
+
|
|
46
|
+
## Architecture
|
|
47
|
+
|
|
48
|
+
### Backend
|
|
49
|
+
|
|
50
|
+
**Admin Middleware** (`src/middleware/admin.ts`)
|
|
51
|
+
|
|
52
|
+
Checks if the authenticated user's email is in the `ADMIN_EMAILS` list. Returns 403 if not. Must be used after `requireAuth`.
|
|
53
|
+
|
|
54
|
+
**Admin Routes** (`src/routes/admin.ts`)
|
|
55
|
+
|
|
56
|
+
| Method | Path | Description |
|
|
57
|
+
|--------|------|-------------|
|
|
58
|
+
| GET | /api/admin/users | List users (paginated, searchable) |
|
|
59
|
+
| GET | /api/admin/users/:id | Get user details |
|
|
60
|
+
| PATCH | /api/admin/users/:id | Update user (name, emailVerified) |
|
|
61
|
+
| DELETE | /api/admin/users/:id | Delete a user |
|
|
62
|
+
| GET | /api/admin/stats | Dashboard statistics |
|
|
63
|
+
|
|
64
|
+
All routes require authentication + admin privileges.
|
|
65
|
+
|
|
66
|
+
### Frontend
|
|
67
|
+
|
|
68
|
+
**Dashboard** (`/admin`)
|
|
69
|
+
|
|
70
|
+
The main admin page showing:
|
|
71
|
+
- Stats cards with key metrics
|
|
72
|
+
- Line chart of user signups over the last 30 days
|
|
73
|
+
- Searchable, sortable users table
|
|
74
|
+
|
|
75
|
+
**User Detail** (`/admin/users/:id`)
|
|
76
|
+
|
|
77
|
+
Detailed view of a single user with:
|
|
78
|
+
- User profile information
|
|
79
|
+
- Active session count
|
|
80
|
+
- Admin actions (verify email, delete user)
|
|
81
|
+
|
|
82
|
+
### Components
|
|
83
|
+
|
|
84
|
+
- `StatsCard` - Reusable card for displaying a metric with optional trend
|
|
85
|
+
- `UsersTable` - Table with search, sort, and pagination
|
|
86
|
+
|
|
87
|
+
### Hooks
|
|
88
|
+
|
|
89
|
+
- `useAdminStats()` - Fetch dashboard statistics
|
|
90
|
+
- `useAdminUsers(page, search)` - Fetch paginated user list
|
|
91
|
+
- `fetchUser(id)` - Get single user details
|
|
92
|
+
- `updateUser(id, data)` - Update user fields
|
|
93
|
+
- `deleteUser(id)` - Delete a user
|
|
94
|
+
|
|
95
|
+
## Customization
|
|
96
|
+
|
|
97
|
+
### Adding Admin Link to Header
|
|
98
|
+
|
|
99
|
+
Add a link to the admin dashboard in your Header component for admin users:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
{isAuthenticated && isAdmin && (
|
|
103
|
+
<Link to="/admin" className="text-sm font-medium text-keel-gray-400 hover:text-white">
|
|
104
|
+
Admin
|
|
105
|
+
</Link>
|
|
106
|
+
)}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
You can check admin status by comparing the user's email against a list fetched from the backend, or by adding an admin check API endpoint.
|
|
110
|
+
|
|
111
|
+
### Extending the Dashboard
|
|
112
|
+
|
|
113
|
+
Add new stats cards by modifying `Dashboard.tsx` and adding corresponding backend queries in `routes/admin.ts`.
|
|
114
|
+
|
|
115
|
+
### Adding More Admin Actions
|
|
116
|
+
|
|
117
|
+
Extend the `PATCH /api/admin/users/:id` endpoint to support additional fields, or add new endpoints for other admin operations (e.g., ban user, reset password, impersonate).
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "admin-dashboard",
|
|
3
|
-
"displayName": "Admin Dashboard",
|
|
4
|
-
"description": "Admin dashboard for user management, metrics, and basic analytics",
|
|
5
|
-
"version": "1.0.0",
|
|
6
|
-
"compatibility": ">=1.0.0",
|
|
7
|
-
"requiredEnvVars": [
|
|
8
|
-
{ "key": "ADMIN_EMAILS", "description": "Comma-separated list of admin email addresses" }
|
|
9
|
-
],
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"backend": {},
|
|
12
|
-
"frontend": { "recharts": "^2.15.0" }
|
|
13
|
-
},
|
|
14
|
-
"modifies": {
|
|
15
|
-
"backend": ["src/index.ts", "src/env.ts"],
|
|
16
|
-
"frontend": ["src/router.tsx"]
|
|
17
|
-
},
|
|
18
|
-
"adds": {
|
|
19
|
-
"backend": ["src/middleware/admin.ts", "src/routes/admin.ts"],
|
|
20
|
-
"frontend": [
|
|
21
|
-
"src/pages/admin/Dashboard.tsx",
|
|
22
|
-
"src/pages/admin/UserDetail.tsx",
|
|
23
|
-
"src/components/admin/StatsCard.tsx",
|
|
24
|
-
"src/components/admin/UsersTable.tsx",
|
|
25
|
-
"src/hooks/useAdmin.ts"
|
|
26
|
-
]
|
|
27
|
-
}
|
|
28
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "admin-dashboard",
|
|
3
|
+
"displayName": "Admin Dashboard",
|
|
4
|
+
"description": "Admin dashboard for user management, metrics, and basic analytics",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"compatibility": ">=1.0.0",
|
|
7
|
+
"requiredEnvVars": [
|
|
8
|
+
{ "key": "ADMIN_EMAILS", "description": "Comma-separated list of admin email addresses" }
|
|
9
|
+
],
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"backend": {},
|
|
12
|
+
"frontend": { "recharts": "^2.15.0" }
|
|
13
|
+
},
|
|
14
|
+
"modifies": {
|
|
15
|
+
"backend": ["src/index.ts", "src/env.ts"],
|
|
16
|
+
"frontend": ["src/router.tsx"]
|
|
17
|
+
},
|
|
18
|
+
"adds": {
|
|
19
|
+
"backend": ["src/middleware/admin.ts", "src/routes/admin.ts"],
|
|
20
|
+
"frontend": [
|
|
21
|
+
"src/pages/admin/Dashboard.tsx",
|
|
22
|
+
"src/pages/admin/UserDetail.tsx",
|
|
23
|
+
"src/components/admin/StatsCard.tsx",
|
|
24
|
+
"src/components/admin/UsersTable.tsx",
|
|
25
|
+
"src/hooks/useAdmin.ts"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import type { Request, Response, NextFunction } from "express";
|
|
2
|
-
import { env } from "../env.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Middleware that checks whether the authenticated user is an admin.
|
|
6
|
-
* Admin status is determined by the ADMIN_EMAILS environment variable
|
|
7
|
-
* which contains a comma-separated list of admin email addresses.
|
|
8
|
-
*
|
|
9
|
-
* Must be used AFTER requireAuth so that req.user is populated.
|
|
10
|
-
*/
|
|
11
|
-
export function requireAdmin(
|
|
12
|
-
req: Request,
|
|
13
|
-
res: Response,
|
|
14
|
-
next: NextFunction,
|
|
15
|
-
): void {
|
|
16
|
-
const user = req.user;
|
|
17
|
-
|
|
18
|
-
if (!user) {
|
|
19
|
-
res.status(401).json({ error: "Unauthorized" });
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const adminEmails = (env.ADMIN_EMAILS ?? "")
|
|
24
|
-
.split(",")
|
|
25
|
-
.map((e) => e.trim().toLowerCase())
|
|
26
|
-
.filter(Boolean);
|
|
27
|
-
|
|
28
|
-
if (!adminEmails.includes(user.email.toLowerCase())) {
|
|
29
|
-
res.status(403).json({ error: "Forbidden: admin access required" });
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
next();
|
|
34
|
-
}
|
|
1
|
+
import type { Request, Response, NextFunction } from "express";
|
|
2
|
+
import { env } from "../env.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Middleware that checks whether the authenticated user is an admin.
|
|
6
|
+
* Admin status is determined by the ADMIN_EMAILS environment variable
|
|
7
|
+
* which contains a comma-separated list of admin email addresses.
|
|
8
|
+
*
|
|
9
|
+
* Must be used AFTER requireAuth so that req.user is populated.
|
|
10
|
+
*/
|
|
11
|
+
export function requireAdmin(
|
|
12
|
+
req: Request,
|
|
13
|
+
res: Response,
|
|
14
|
+
next: NextFunction,
|
|
15
|
+
): void {
|
|
16
|
+
const user = req.user;
|
|
17
|
+
|
|
18
|
+
if (!user) {
|
|
19
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const adminEmails = (env.ADMIN_EMAILS ?? "")
|
|
24
|
+
.split(",")
|
|
25
|
+
.map((e) => e.trim().toLowerCase())
|
|
26
|
+
.filter(Boolean);
|
|
27
|
+
|
|
28
|
+
if (!adminEmails.includes(user.email.toLowerCase())) {
|
|
29
|
+
res.status(403).json({ error: "Forbidden: admin access required" });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
next();
|
|
34
|
+
}
|