studiocms 0.4.2 → 0.4.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/CHANGELOG.md +23 -0
- package/dist/client/apiClient.d.ts +881 -881
- package/frontend/pages/studiocms_api/_handlers/dashboard/create.ts +27 -5
- package/frontend/pages/studiocms_api/_handlers/dashboard/users.ts +6 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/secure.ts +17 -15
- package/package.json +17 -4
|
@@ -90,15 +90,37 @@ export const CreateHandlers = HttpApiBuilder.group(
|
|
|
90
90
|
return yield* new DashboardAPIError({ error: 'Unauthorized' });
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
const
|
|
94
|
-
sdk.resetTokenBucket.new(userId),
|
|
95
|
-
sdk.GET.users.byId(userId),
|
|
96
|
-
]);
|
|
93
|
+
const user = yield* sdk.GET.users.byId(userId);
|
|
97
94
|
|
|
98
|
-
if (!
|
|
95
|
+
if (!user) {
|
|
99
96
|
return yield* new DashboardAPIError({ error: 'User not found' });
|
|
100
97
|
}
|
|
101
98
|
|
|
99
|
+
const rank = user.permissionsData?.rank;
|
|
100
|
+
|
|
101
|
+
if (!rank) {
|
|
102
|
+
return yield* new DashboardAPIError({ error: 'User rank not found' });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!ValidRanks.has(rank) || rank === 'unknown') {
|
|
106
|
+
return yield* new DashboardAPIError({ error: 'Invalid rank' });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const callerPerm = availablePermissionRanks.indexOf(userData.permissionLevel);
|
|
110
|
+
const targetPerm = availablePermissionRanks.indexOf(rank);
|
|
111
|
+
|
|
112
|
+
if (targetPerm >= callerPerm) {
|
|
113
|
+
return yield* new DashboardAPIError({
|
|
114
|
+
error: 'Unauthorized: insufficient permissions to assign target rank',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const token = yield* sdk.resetTokenBucket.new(userId);
|
|
119
|
+
|
|
120
|
+
if (!token) {
|
|
121
|
+
return yield* new DashboardAPIError({ error: 'Failed to generate reset token' });
|
|
122
|
+
}
|
|
123
|
+
|
|
102
124
|
yield* notifier
|
|
103
125
|
.sendAdminNotification('user_updated', user.username)
|
|
104
126
|
.pipe(
|
|
@@ -277,6 +277,12 @@ export const UsersHandlers = HttpApiBuilder.group(StudioCMSDashboardApiSpec, 'us
|
|
|
277
277
|
});
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
if (id !== userData.user?.id && !userData.userPermissionLevel.isAdmin) {
|
|
281
|
+
return yield* new DashboardAPIError({
|
|
282
|
+
error: "Unauthorized: cannot modify another user's notification preferences",
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
280
286
|
const existingUser = yield* sdk.GET.users.byId(id);
|
|
281
287
|
|
|
282
288
|
if (!existingUser) {
|
|
@@ -1362,9 +1362,12 @@ export const RestApiSecureHandler = HttpApiBuilder.group(
|
|
|
1362
1362
|
});
|
|
1363
1363
|
}
|
|
1364
1364
|
|
|
1365
|
-
|
|
1365
|
+
const callerPerm = availablePermissionRanks.indexOf(rank);
|
|
1366
|
+
const targetPerm = availablePermissionRanks.indexOf(newUserRank);
|
|
1367
|
+
|
|
1368
|
+
if (targetPerm >= callerPerm) {
|
|
1366
1369
|
return yield* new RestAPIError({
|
|
1367
|
-
error: 'Unauthorized
|
|
1370
|
+
error: 'Unauthorized: insufficient permissions to assign target rank',
|
|
1368
1371
|
});
|
|
1369
1372
|
}
|
|
1370
1373
|
|
|
@@ -1372,12 +1375,6 @@ export const RestApiSecureHandler = HttpApiBuilder.group(
|
|
|
1372
1375
|
password = yield* sdk.UTIL.Generators.generateRandomPassword(12);
|
|
1373
1376
|
}
|
|
1374
1377
|
|
|
1375
|
-
if (rank === 'admin' && newUserRank === 'owner') {
|
|
1376
|
-
return yield* new RestAPIError({
|
|
1377
|
-
error: 'Unauthorized to create user with owner rank',
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
1378
|
const checkEmail = isValidEmail(email);
|
|
1382
1379
|
|
|
1383
1380
|
if (!checkEmail.success) {
|
|
@@ -1639,19 +1636,24 @@ export const RestApiSecureHandler = HttpApiBuilder.group(
|
|
|
1639
1636
|
})
|
|
1640
1637
|
);
|
|
1641
1638
|
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1639
|
+
const loggedInUserRankIndex = availablePermissionRanks.indexOf(user.rank);
|
|
1640
|
+
|
|
1641
|
+
data = data.filter((candidate) => {
|
|
1642
|
+
const candidateRankIndex = availablePermissionRanks.indexOf(candidate.rank);
|
|
1643
|
+
return loggedInUserRankIndex > candidateRankIndex;
|
|
1644
|
+
});
|
|
1645
1645
|
|
|
1646
1646
|
if (name) {
|
|
1647
|
-
data = data.filter((
|
|
1647
|
+
data = data.filter((candidate) =>
|
|
1648
|
+
candidate.name.toLowerCase().includes(name.toLowerCase())
|
|
1649
|
+
);
|
|
1648
1650
|
}
|
|
1649
1651
|
if (rank) {
|
|
1650
|
-
data = data.filter((
|
|
1652
|
+
data = data.filter((candidate) => candidate.rank === rank);
|
|
1651
1653
|
}
|
|
1652
1654
|
if (username) {
|
|
1653
|
-
data = data.filter((
|
|
1654
|
-
|
|
1655
|
+
data = data.filter((candidate) =>
|
|
1656
|
+
candidate.username.toLowerCase().includes(username.toLowerCase())
|
|
1655
1657
|
);
|
|
1656
1658
|
}
|
|
1657
1659
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "studiocms",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "A Community-Driven Astro native CMS. Built from the ground up by the Astro community.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "withstudiocms",
|
|
@@ -253,17 +253,17 @@
|
|
|
253
253
|
"tinyglobby": "^0.2.15",
|
|
254
254
|
"ultrahtml": "^1.6.0",
|
|
255
255
|
"web-vitals": "^5.1.0",
|
|
256
|
-
"@withstudiocms/api-spec": "^0.3.
|
|
256
|
+
"@withstudiocms/api-spec": "^0.3.2",
|
|
257
257
|
"@withstudiocms/internal_helpers": "^0.2.0",
|
|
258
258
|
"@withstudiocms/auth-kit": "^0.1.4",
|
|
259
259
|
"@withstudiocms/cli-kit": "^0.2.1",
|
|
260
260
|
"@withstudiocms/component-registry": "^0.1.4",
|
|
261
261
|
"@withstudiocms/config-utils": "^0.2.0",
|
|
262
|
-
"@withstudiocms/effect": "^0.4.
|
|
262
|
+
"@withstudiocms/effect": "^0.4.1",
|
|
263
263
|
"@withstudiocms/template-lang": "^0.1.0",
|
|
264
264
|
"@withstudiocms/kysely": "^0.2.1",
|
|
265
265
|
"@withstudiocms/sdk": "^0.3.0",
|
|
266
|
-
"effectify": "^0.
|
|
266
|
+
"effectify": "^0.2.0"
|
|
267
267
|
},
|
|
268
268
|
"devDependencies": {
|
|
269
269
|
"@types/mdast": "^4.0.4",
|
|
@@ -276,6 +276,7 @@
|
|
|
276
276
|
},
|
|
277
277
|
"peerDependencies": {
|
|
278
278
|
"@effect/platform": "^0.94.5",
|
|
279
|
+
"@effect/platform-node": "^0.104.1",
|
|
279
280
|
"@libsql/client": "^0.15.15",
|
|
280
281
|
"astro": "^5.12.9",
|
|
281
282
|
"effect": "^3.19.19",
|
|
@@ -283,9 +284,21 @@
|
|
|
283
284
|
"mysql2": "^3.18.0"
|
|
284
285
|
},
|
|
285
286
|
"peerDependenciesMeta": {
|
|
287
|
+
"@effect/platform": {
|
|
288
|
+
"optional": false
|
|
289
|
+
},
|
|
290
|
+
"@effect/platform-node": {
|
|
291
|
+
"optional": false
|
|
292
|
+
},
|
|
286
293
|
"@libsql/client": {
|
|
287
294
|
"optional": true
|
|
288
295
|
},
|
|
296
|
+
"astro": {
|
|
297
|
+
"optional": false
|
|
298
|
+
},
|
|
299
|
+
"effect": {
|
|
300
|
+
"optional": false
|
|
301
|
+
},
|
|
289
302
|
"pg": {
|
|
290
303
|
"optional": true
|
|
291
304
|
},
|