@sonicjs-cms/core 2.16.1 → 2.17.1
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/{app-D9L3mrC-.d.cts → app-C9esKLmh.d.cts} +2 -0
- package/dist/{app-D9L3mrC-.d.ts → app-C9esKLmh.d.ts} +2 -0
- package/dist/{chunk-7HHIZQNE.cjs → chunk-3TVMUQWG.cjs} +155 -17
- package/dist/chunk-3TVMUQWG.cjs.map +1 -0
- package/dist/{chunk-U6FOL6EO.cjs → chunk-47HKH3D6.cjs} +34 -6
- package/dist/chunk-47HKH3D6.cjs.map +1 -0
- package/dist/{chunk-V76ERLX6.cjs → chunk-5EBTBD2Z.cjs} +3 -3
- package/dist/{chunk-V76ERLX6.cjs.map → chunk-5EBTBD2Z.cjs.map} +1 -1
- package/dist/{chunk-MZS33LLH.cjs → chunk-5ITJB5ZT.cjs} +354 -180
- package/dist/chunk-5ITJB5ZT.cjs.map +1 -0
- package/dist/{chunk-JF5RQXPN.js → chunk-7D7SI5P7.js} +3 -3
- package/dist/{chunk-JF5RQXPN.js.map → chunk-7D7SI5P7.js.map} +1 -1
- package/dist/{chunk-W33MHOPA.js → chunk-EUFBU4T4.js} +34 -6
- package/dist/chunk-EUFBU4T4.js.map +1 -0
- package/dist/{chunk-HU4MN74Q.cjs → chunk-I6444XLU.cjs} +2 -2
- package/dist/{chunk-HU4MN74Q.cjs.map → chunk-I6444XLU.cjs.map} +1 -1
- package/dist/{chunk-KYAF33AF.js → chunk-P5IDHMOL.js} +149 -14
- package/dist/chunk-P5IDHMOL.js.map +1 -0
- package/dist/{chunk-TBJY2FF7.js → chunk-QFWHAFEO.js} +22 -2
- package/dist/chunk-QFWHAFEO.js.map +1 -0
- package/dist/{chunk-PUZMLXOJ.js → chunk-QZBZEUZF.js} +2 -2
- package/dist/{chunk-PUZMLXOJ.js.map → chunk-QZBZEUZF.js.map} +1 -1
- package/dist/{chunk-BAMJVG33.js → chunk-UDUHP4PA.js} +229 -55
- package/dist/chunk-UDUHP4PA.js.map +1 -0
- package/dist/{chunk-NZWFCUDA.cjs → chunk-WAEQXGCX.cjs} +22 -2
- package/dist/chunk-WAEQXGCX.cjs.map +1 -0
- package/dist/index.cjs +194 -186
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -22
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +41 -29
- package/dist/middleware.d.cts +38 -4
- package/dist/middleware.d.ts +38 -4
- package/dist/middleware.js +3 -3
- package/dist/migrations-3TVS3HU5.js +4 -0
- package/dist/{migrations-WCEBO5QQ.js.map → migrations-3TVS3HU5.js.map} +1 -1
- package/dist/migrations-VQ4UX4M4.cjs +13 -0
- package/dist/{migrations-MYQI2KAJ.cjs.map → migrations-VQ4UX4M4.cjs.map} +1 -1
- package/dist/routes.cjs +29 -29
- package/dist/routes.d.cts +1 -1
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +6 -6
- package/dist/services.cjs +39 -39
- package/dist/services.d.cts +12 -0
- package/dist/services.d.ts +12 -0
- package/dist/services.js +3 -3
- package/dist/utils.cjs +11 -11
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7HHIZQNE.cjs.map +0 -1
- package/dist/chunk-BAMJVG33.js.map +0 -1
- package/dist/chunk-KYAF33AF.js.map +0 -1
- package/dist/chunk-MZS33LLH.cjs.map +0 -1
- package/dist/chunk-NZWFCUDA.cjs.map +0 -1
- package/dist/chunk-TBJY2FF7.js.map +0 -1
- package/dist/chunk-U6FOL6EO.cjs.map +0 -1
- package/dist/chunk-W33MHOPA.js.map +0 -1
- package/dist/migrations-MYQI2KAJ.cjs +0 -13
- package/dist/migrations-WCEBO5QQ.js +0 -4
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
3
|
+
var chunkWAEQXGCX_cjs = require('./chunk-WAEQXGCX.cjs');
|
|
4
|
+
var chunk3TVMUQWG_cjs = require('./chunk-3TVMUQWG.cjs');
|
|
5
|
+
var chunk47HKH3D6_cjs = require('./chunk-47HKH3D6.cjs');
|
|
6
|
+
var chunkI6444XLU_cjs = require('./chunk-I6444XLU.cjs');
|
|
7
7
|
var chunkOHYBNCVL_cjs = require('./chunk-OHYBNCVL.cjs');
|
|
8
8
|
var chunkUYJ6TJHX_cjs = require('./chunk-UYJ6TJHX.cjs');
|
|
9
9
|
var chunk635JAMSE_cjs = require('./chunk-635JAMSE.cjs');
|
|
10
|
-
var
|
|
10
|
+
var chunk5EBTBD2Z_cjs = require('./chunk-5EBTBD2Z.cjs');
|
|
11
11
|
var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
|
|
12
12
|
var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
|
|
13
13
|
var hono = require('hono');
|
|
@@ -189,7 +189,7 @@ apiContentCrudRoutes.get("/:id", async (c) => {
|
|
|
189
189
|
}, 500);
|
|
190
190
|
}
|
|
191
191
|
});
|
|
192
|
-
apiContentCrudRoutes.post("/",
|
|
192
|
+
apiContentCrudRoutes.post("/", chunk3TVMUQWG_cjs.requireAuth(), chunk3TVMUQWG_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
193
193
|
try {
|
|
194
194
|
const db = c.env.DB;
|
|
195
195
|
const user = c.get("user");
|
|
@@ -230,7 +230,7 @@ apiContentCrudRoutes.post("/", chunk7HHIZQNE_cjs.requireAuth(), chunk7HHIZQNE_cj
|
|
|
230
230
|
now,
|
|
231
231
|
now
|
|
232
232
|
).run();
|
|
233
|
-
const cache =
|
|
233
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.api);
|
|
234
234
|
await cache.invalidate(`content:list:${collectionId}:*`);
|
|
235
235
|
await cache.invalidate("content-filtered:*");
|
|
236
236
|
const getStmt = db.prepare("SELECT * FROM content WHERE id = ?");
|
|
@@ -255,7 +255,7 @@ apiContentCrudRoutes.post("/", chunk7HHIZQNE_cjs.requireAuth(), chunk7HHIZQNE_cj
|
|
|
255
255
|
}, 500);
|
|
256
256
|
}
|
|
257
257
|
});
|
|
258
|
-
apiContentCrudRoutes.put("/:id",
|
|
258
|
+
apiContentCrudRoutes.put("/:id", chunk3TVMUQWG_cjs.requireAuth(), chunk3TVMUQWG_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
259
259
|
try {
|
|
260
260
|
const id = c.req.param("id");
|
|
261
261
|
const db = c.env.DB;
|
|
@@ -293,7 +293,7 @@ apiContentCrudRoutes.put("/:id", chunk7HHIZQNE_cjs.requireAuth(), chunk7HHIZQNE_
|
|
|
293
293
|
WHERE id = ?
|
|
294
294
|
`);
|
|
295
295
|
await updateStmt.bind(...params).run();
|
|
296
|
-
const cache =
|
|
296
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.api);
|
|
297
297
|
await cache.delete(cache.generateKey("content", id));
|
|
298
298
|
await cache.invalidate(`content:list:${existing.collection_id}:*`);
|
|
299
299
|
await cache.invalidate("content-filtered:*");
|
|
@@ -319,7 +319,7 @@ apiContentCrudRoutes.put("/:id", chunk7HHIZQNE_cjs.requireAuth(), chunk7HHIZQNE_
|
|
|
319
319
|
}, 500);
|
|
320
320
|
}
|
|
321
321
|
});
|
|
322
|
-
apiContentCrudRoutes.delete("/:id",
|
|
322
|
+
apiContentCrudRoutes.delete("/:id", chunk3TVMUQWG_cjs.requireAuth(), chunk3TVMUQWG_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
323
323
|
try {
|
|
324
324
|
const id = c.req.param("id");
|
|
325
325
|
const db = c.env.DB;
|
|
@@ -330,7 +330,7 @@ apiContentCrudRoutes.delete("/:id", chunk7HHIZQNE_cjs.requireAuth(), chunk7HHIZQ
|
|
|
330
330
|
}
|
|
331
331
|
const deleteStmt = db.prepare("DELETE FROM content WHERE id = ?");
|
|
332
332
|
await deleteStmt.bind(id).run();
|
|
333
|
-
const cache =
|
|
333
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.api);
|
|
334
334
|
await cache.delete(cache.generateKey("content", id));
|
|
335
335
|
await cache.invalidate(`content:list:${existing.collection_id}:*`);
|
|
336
336
|
await cache.invalidate("content-filtered:*");
|
|
@@ -355,7 +355,7 @@ apiRoutes.use("*", async (c, next) => {
|
|
|
355
355
|
c.header("X-Response-Time", `${totalTime}ms`);
|
|
356
356
|
});
|
|
357
357
|
apiRoutes.use("*", async (c, next) => {
|
|
358
|
-
const cacheEnabled = await
|
|
358
|
+
const cacheEnabled = await chunk3TVMUQWG_cjs.isPluginActive(c.env.DB, "core-cache");
|
|
359
359
|
c.set("cacheEnabled", cacheEnabled);
|
|
360
360
|
await next();
|
|
361
361
|
});
|
|
@@ -792,7 +792,7 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
792
792
|
try {
|
|
793
793
|
const db = c.env.DB;
|
|
794
794
|
const cacheEnabled = c.get("cacheEnabled");
|
|
795
|
-
const cache =
|
|
795
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.api);
|
|
796
796
|
const cacheKey = cache.generateKey("collections", "all");
|
|
797
797
|
if (cacheEnabled) {
|
|
798
798
|
const cacheResult = await cache.getWithSource(cacheKey);
|
|
@@ -846,7 +846,7 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
846
846
|
return c.json({ error: "Failed to fetch collections" }, 500);
|
|
847
847
|
}
|
|
848
848
|
});
|
|
849
|
-
apiRoutes.get("/content",
|
|
849
|
+
apiRoutes.get("/content", chunk3TVMUQWG_cjs.optionalAuth(), async (c) => {
|
|
850
850
|
const executionStart = Date.now();
|
|
851
851
|
try {
|
|
852
852
|
const db = c.env.DB;
|
|
@@ -869,13 +869,13 @@ apiRoutes.get("/content", chunk7HHIZQNE_cjs.optionalAuth(), async (c) => {
|
|
|
869
869
|
});
|
|
870
870
|
}
|
|
871
871
|
}
|
|
872
|
-
const filter =
|
|
872
|
+
const filter = chunk5EBTBD2Z_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
|
|
873
873
|
const normalizedFilter = normalizePublicContentFilter(filter, c.get("user")?.role);
|
|
874
874
|
if (!normalizedFilter.limit) {
|
|
875
875
|
normalizedFilter.limit = 50;
|
|
876
876
|
}
|
|
877
877
|
normalizedFilter.limit = Math.min(normalizedFilter.limit, 1e3);
|
|
878
|
-
const builder3 = new
|
|
878
|
+
const builder3 = new chunk5EBTBD2Z_cjs.QueryFilterBuilder();
|
|
879
879
|
const queryResult = builder3.build("content", normalizedFilter);
|
|
880
880
|
if (queryResult.errors.length > 0) {
|
|
881
881
|
return c.json({
|
|
@@ -884,7 +884,7 @@ apiRoutes.get("/content", chunk7HHIZQNE_cjs.optionalAuth(), async (c) => {
|
|
|
884
884
|
}, 400);
|
|
885
885
|
}
|
|
886
886
|
const cacheEnabled = c.get("cacheEnabled");
|
|
887
|
-
const cache =
|
|
887
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.api);
|
|
888
888
|
const cacheKey = cache.generateKey("content-filtered", JSON.stringify({ filter: normalizedFilter, query: queryResult.sql }));
|
|
889
889
|
if (cacheEnabled) {
|
|
890
890
|
const cacheResult = await cache.getWithSource(cacheKey);
|
|
@@ -947,7 +947,7 @@ apiRoutes.get("/content", chunk7HHIZQNE_cjs.optionalAuth(), async (c) => {
|
|
|
947
947
|
}, 500);
|
|
948
948
|
}
|
|
949
949
|
});
|
|
950
|
-
apiRoutes.get("/collections/:collection/content",
|
|
950
|
+
apiRoutes.get("/collections/:collection/content", chunk3TVMUQWG_cjs.optionalAuth(), async (c) => {
|
|
951
951
|
const executionStart = Date.now();
|
|
952
952
|
try {
|
|
953
953
|
const collection = c.req.param("collection");
|
|
@@ -958,7 +958,7 @@ apiRoutes.get("/collections/:collection/content", chunk7HHIZQNE_cjs.optionalAuth
|
|
|
958
958
|
if (!collectionResult) {
|
|
959
959
|
return c.json({ error: "Collection not found" }, 404);
|
|
960
960
|
}
|
|
961
|
-
const filter =
|
|
961
|
+
const filter = chunk5EBTBD2Z_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
|
|
962
962
|
const normalizedFilter = normalizePublicContentFilter(filter, c.get("user")?.role);
|
|
963
963
|
if (!normalizedFilter.where) {
|
|
964
964
|
normalizedFilter.where = { and: [] };
|
|
@@ -975,7 +975,7 @@ apiRoutes.get("/collections/:collection/content", chunk7HHIZQNE_cjs.optionalAuth
|
|
|
975
975
|
normalizedFilter.limit = 50;
|
|
976
976
|
}
|
|
977
977
|
normalizedFilter.limit = Math.min(normalizedFilter.limit, 1e3);
|
|
978
|
-
const builder3 = new
|
|
978
|
+
const builder3 = new chunk5EBTBD2Z_cjs.QueryFilterBuilder();
|
|
979
979
|
const queryResult = builder3.build("content", normalizedFilter);
|
|
980
980
|
if (queryResult.errors.length > 0) {
|
|
981
981
|
return c.json({
|
|
@@ -984,7 +984,7 @@ apiRoutes.get("/collections/:collection/content", chunk7HHIZQNE_cjs.optionalAuth
|
|
|
984
984
|
}, 400);
|
|
985
985
|
}
|
|
986
986
|
const cacheEnabled = c.get("cacheEnabled");
|
|
987
|
-
const cache =
|
|
987
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.api);
|
|
988
988
|
const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter: normalizedFilter, query: queryResult.sql })}`);
|
|
989
989
|
if (cacheEnabled) {
|
|
990
990
|
const cacheResult = await cache.getWithSource(cacheKey);
|
|
@@ -1096,7 +1096,7 @@ var fileValidationSchema = zod.z.object({
|
|
|
1096
1096
|
// 50MB max
|
|
1097
1097
|
});
|
|
1098
1098
|
var apiMediaRoutes = new hono.Hono();
|
|
1099
|
-
apiMediaRoutes.use("*",
|
|
1099
|
+
apiMediaRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
1100
1100
|
apiMediaRoutes.post("/upload", async (c) => {
|
|
1101
1101
|
try {
|
|
1102
1102
|
const user = c.get("user");
|
|
@@ -1840,8 +1840,8 @@ apiSystemRoutes.get("/env", (c) => {
|
|
|
1840
1840
|
});
|
|
1841
1841
|
var api_system_default = apiSystemRoutes;
|
|
1842
1842
|
var adminApiRoutes = new hono.Hono();
|
|
1843
|
-
adminApiRoutes.use("*",
|
|
1844
|
-
adminApiRoutes.use("*",
|
|
1843
|
+
adminApiRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
1844
|
+
adminApiRoutes.use("*", chunk3TVMUQWG_cjs.requireRole(["admin", "editor"]));
|
|
1845
1845
|
adminApiRoutes.get("/stats", async (c) => {
|
|
1846
1846
|
try {
|
|
1847
1847
|
const db = c.env.DB;
|
|
@@ -2353,7 +2353,7 @@ adminApiRoutes.delete("/collections/:id", async (c) => {
|
|
|
2353
2353
|
});
|
|
2354
2354
|
adminApiRoutes.get("/migrations/status", async (c) => {
|
|
2355
2355
|
try {
|
|
2356
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
2356
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-VQ4UX4M4.cjs');
|
|
2357
2357
|
const db = c.env.DB;
|
|
2358
2358
|
const migrationService = new MigrationService2(db);
|
|
2359
2359
|
const status = await migrationService.getMigrationStatus();
|
|
@@ -2378,7 +2378,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
|
|
|
2378
2378
|
error: "Unauthorized. Admin access required."
|
|
2379
2379
|
}, 403);
|
|
2380
2380
|
}
|
|
2381
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
2381
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-VQ4UX4M4.cjs');
|
|
2382
2382
|
const db = c.env.DB;
|
|
2383
2383
|
const migrationService = new MigrationService2(db);
|
|
2384
2384
|
const result = await migrationService.runPendingMigrations();
|
|
@@ -2400,7 +2400,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
|
|
|
2400
2400
|
});
|
|
2401
2401
|
adminApiRoutes.get("/migrations/validate", async (c) => {
|
|
2402
2402
|
try {
|
|
2403
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
2403
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-VQ4UX4M4.cjs');
|
|
2404
2404
|
const db = c.env.DB;
|
|
2405
2405
|
const migrationService = new MigrationService2(db);
|
|
2406
2406
|
const validation = await migrationService.validateSchema();
|
|
@@ -5150,16 +5150,17 @@ var userProfilesPlugin = createUserProfilesPlugin();
|
|
|
5150
5150
|
|
|
5151
5151
|
// src/routes/auth.ts
|
|
5152
5152
|
var JWT_SECRET_FALLBACK = "your-super-secret-jwt-key-change-in-production";
|
|
5153
|
-
async function setCsrfCookie(c) {
|
|
5153
|
+
async function setCsrfCookie(c, maxAge) {
|
|
5154
5154
|
const secret = c.env?.JWT_SECRET || JWT_SECRET_FALLBACK;
|
|
5155
5155
|
const isDev = c.env?.ENVIRONMENT === "development" || !c.env?.ENVIRONMENT;
|
|
5156
|
-
const csrfToken = await
|
|
5156
|
+
const csrfToken = await chunk3TVMUQWG_cjs.generateCsrfToken(secret);
|
|
5157
|
+
const cookieMaxAge = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(c.env?.DB, c.env);
|
|
5157
5158
|
cookie.setCookie(c, "csrf_token", csrfToken, {
|
|
5158
5159
|
httpOnly: false,
|
|
5159
5160
|
secure: !isDev,
|
|
5160
5161
|
sameSite: "Strict",
|
|
5161
5162
|
path: "/",
|
|
5162
|
-
maxAge:
|
|
5163
|
+
maxAge: cookieMaxAge
|
|
5163
5164
|
});
|
|
5164
5165
|
}
|
|
5165
5166
|
function clearCsrfCookie(c) {
|
|
@@ -5210,7 +5211,7 @@ var loginSchema = zod.z.object({
|
|
|
5210
5211
|
});
|
|
5211
5212
|
authRoutes.post(
|
|
5212
5213
|
"/register",
|
|
5213
|
-
|
|
5214
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
|
|
5214
5215
|
async (c) => {
|
|
5215
5216
|
try {
|
|
5216
5217
|
const db = c.env.DB;
|
|
@@ -5247,7 +5248,7 @@ authRoutes.post(
|
|
|
5247
5248
|
if (existingUser) {
|
|
5248
5249
|
return c.json({ error: "User with this email or username already exists" }, 400);
|
|
5249
5250
|
}
|
|
5250
|
-
const passwordHash = await
|
|
5251
|
+
const passwordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
5251
5252
|
const userId = crypto.randomUUID();
|
|
5252
5253
|
const now = /* @__PURE__ */ new Date();
|
|
5253
5254
|
await db.prepare(`
|
|
@@ -5281,13 +5282,13 @@ authRoutes.post(
|
|
|
5281
5282
|
await saveCustomData(db, userId, sanitized);
|
|
5282
5283
|
}
|
|
5283
5284
|
}
|
|
5284
|
-
const
|
|
5285
|
+
const tokenTtl = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
5286
|
+
const token = await chunk3TVMUQWG_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET, tokenTtl);
|
|
5285
5287
|
cookie.setCookie(c, "auth_token", token, {
|
|
5286
5288
|
httpOnly: true,
|
|
5287
5289
|
secure: true,
|
|
5288
5290
|
sameSite: "Strict",
|
|
5289
|
-
maxAge:
|
|
5290
|
-
// 24 hours
|
|
5291
|
+
maxAge: tokenTtl
|
|
5291
5292
|
});
|
|
5292
5293
|
await setCsrfCookie(c);
|
|
5293
5294
|
return c.json({
|
|
@@ -5315,7 +5316,7 @@ authRoutes.post(
|
|
|
5315
5316
|
);
|
|
5316
5317
|
authRoutes.post(
|
|
5317
5318
|
"/login",
|
|
5318
|
-
|
|
5319
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
|
|
5319
5320
|
async (c) => {
|
|
5320
5321
|
try {
|
|
5321
5322
|
const body = await c.req.json();
|
|
@@ -5326,7 +5327,7 @@ authRoutes.post(
|
|
|
5326
5327
|
const { email, password } = validation.data;
|
|
5327
5328
|
const db = c.env.DB;
|
|
5328
5329
|
const normalizedEmail = email.toLowerCase();
|
|
5329
|
-
const cache =
|
|
5330
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.user);
|
|
5330
5331
|
let user = await cache.get(cache.generateKey("user", `email:${normalizedEmail}`));
|
|
5331
5332
|
if (!user) {
|
|
5332
5333
|
user = await db.prepare("SELECT * FROM users WHERE email = ? AND is_active = 1").bind(normalizedEmail).first();
|
|
@@ -5338,25 +5339,25 @@ authRoutes.post(
|
|
|
5338
5339
|
if (!user) {
|
|
5339
5340
|
return c.json({ error: "Invalid email or password" }, 401);
|
|
5340
5341
|
}
|
|
5341
|
-
const isValidPassword = await
|
|
5342
|
+
const isValidPassword = await chunk3TVMUQWG_cjs.AuthManager.verifyPassword(password, user.password_hash);
|
|
5342
5343
|
if (!isValidPassword) {
|
|
5343
5344
|
return c.json({ error: "Invalid email or password" }, 401);
|
|
5344
5345
|
}
|
|
5345
|
-
if (
|
|
5346
|
+
if (chunk3TVMUQWG_cjs.AuthManager.isLegacyHash(user.password_hash)) {
|
|
5346
5347
|
try {
|
|
5347
|
-
const newHash = await
|
|
5348
|
+
const newHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
5348
5349
|
await db.prepare("UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?").bind(newHash, Date.now(), user.id).run();
|
|
5349
5350
|
} catch (rehashError) {
|
|
5350
5351
|
console.error("Password rehash failed (non-fatal):", rehashError);
|
|
5351
5352
|
}
|
|
5352
5353
|
}
|
|
5353
|
-
const
|
|
5354
|
+
const tokenTtl = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
5355
|
+
const token = await chunk3TVMUQWG_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
|
|
5354
5356
|
cookie.setCookie(c, "auth_token", token, {
|
|
5355
5357
|
httpOnly: true,
|
|
5356
5358
|
secure: true,
|
|
5357
5359
|
sameSite: "Strict",
|
|
5358
|
-
maxAge:
|
|
5359
|
-
// 24 hours
|
|
5360
|
+
maxAge: tokenTtl
|
|
5360
5361
|
});
|
|
5361
5362
|
await setCsrfCookie(c);
|
|
5362
5363
|
await db.prepare("UPDATE users SET last_login_at = ? WHERE id = ?").bind((/* @__PURE__ */ new Date()).getTime(), user.id).run();
|
|
@@ -5403,7 +5404,7 @@ authRoutes.get("/logout", (c) => {
|
|
|
5403
5404
|
clearCsrfCookie(c);
|
|
5404
5405
|
return c.redirect("/auth/login?message=You have been logged out successfully");
|
|
5405
5406
|
});
|
|
5406
|
-
authRoutes.get("/me",
|
|
5407
|
+
authRoutes.get("/me", chunk3TVMUQWG_cjs.requireAuth(), async (c) => {
|
|
5407
5408
|
try {
|
|
5408
5409
|
const user = c.get("user");
|
|
5409
5410
|
if (!user) {
|
|
@@ -5420,30 +5421,48 @@ authRoutes.get("/me", chunk7HHIZQNE_cjs.requireAuth(), async (c) => {
|
|
|
5420
5421
|
return c.json({ error: "Failed to get user" }, 500);
|
|
5421
5422
|
}
|
|
5422
5423
|
});
|
|
5423
|
-
authRoutes.post(
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5424
|
+
authRoutes.post(
|
|
5425
|
+
"/refresh",
|
|
5426
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 60, windowMs: 60 * 1e3, keyPrefix: "refresh" }),
|
|
5427
|
+
async (c) => {
|
|
5428
|
+
try {
|
|
5429
|
+
let token = c.req.header("Authorization")?.replace("Bearer ", "");
|
|
5430
|
+
if (!token) token = cookie.getCookie(c, "auth_token");
|
|
5431
|
+
if (!token) {
|
|
5432
|
+
return c.json({ error: "Authentication required" }, 401);
|
|
5433
|
+
}
|
|
5434
|
+
const db = c.env.DB;
|
|
5435
|
+
const grace = await chunk3TVMUQWG_cjs.getJwtRefreshGraceSecondsFromDb(db, c.env);
|
|
5436
|
+
const payload = await chunk3TVMUQWG_cjs.AuthManager.verifyToken(token, c.env.JWT_SECRET, grace);
|
|
5437
|
+
if (!payload) {
|
|
5438
|
+
return c.json({ error: "Invalid or expired token" }, 401);
|
|
5439
|
+
}
|
|
5440
|
+
const row = await db.prepare("SELECT id, email, role, is_active FROM users WHERE id = ?").bind(payload.userId).first();
|
|
5441
|
+
if (!row || !row.is_active) {
|
|
5442
|
+
return c.json({ error: "User is not active" }, 401);
|
|
5443
|
+
}
|
|
5444
|
+
const tokenTtl = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(db, c.env);
|
|
5445
|
+
const newToken = await chunk3TVMUQWG_cjs.AuthManager.generateToken(row.id, row.email, row.role, c.env.JWT_SECRET, tokenTtl);
|
|
5446
|
+
cookie.setCookie(c, "auth_token", newToken, {
|
|
5447
|
+
httpOnly: true,
|
|
5448
|
+
secure: true,
|
|
5449
|
+
sameSite: "Strict",
|
|
5450
|
+
maxAge: tokenTtl
|
|
5451
|
+
});
|
|
5452
|
+
await setCsrfCookie(c);
|
|
5453
|
+
return c.json({
|
|
5454
|
+
token: newToken,
|
|
5455
|
+
expiresIn: tokenTtl
|
|
5456
|
+
});
|
|
5457
|
+
} catch (error) {
|
|
5458
|
+
console.error("Token refresh error:", error);
|
|
5459
|
+
return c.json({ error: "Token refresh failed" }, 500);
|
|
5428
5460
|
}
|
|
5429
|
-
const token = await chunk7HHIZQNE_cjs.AuthManager.generateToken(user.userId, user.email, user.role, c.env.JWT_SECRET);
|
|
5430
|
-
cookie.setCookie(c, "auth_token", token, {
|
|
5431
|
-
httpOnly: true,
|
|
5432
|
-
secure: true,
|
|
5433
|
-
sameSite: "Strict",
|
|
5434
|
-
maxAge: 60 * 60 * 24
|
|
5435
|
-
// 24 hours
|
|
5436
|
-
});
|
|
5437
|
-
await setCsrfCookie(c);
|
|
5438
|
-
return c.json({ token });
|
|
5439
|
-
} catch (error) {
|
|
5440
|
-
console.error("Token refresh error:", error);
|
|
5441
|
-
return c.json({ error: "Token refresh failed" }, 500);
|
|
5442
5461
|
}
|
|
5443
|
-
|
|
5462
|
+
);
|
|
5444
5463
|
authRoutes.post(
|
|
5445
5464
|
"/register/form",
|
|
5446
|
-
|
|
5465
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
|
|
5447
5466
|
async (c) => {
|
|
5448
5467
|
try {
|
|
5449
5468
|
const db = c.env.DB;
|
|
@@ -5490,7 +5509,7 @@ authRoutes.post(
|
|
|
5490
5509
|
</div>
|
|
5491
5510
|
`);
|
|
5492
5511
|
}
|
|
5493
|
-
const passwordHash = await
|
|
5512
|
+
const passwordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
5494
5513
|
const role = isFirstUser ? "admin" : "viewer";
|
|
5495
5514
|
const userId = crypto.randomUUID();
|
|
5496
5515
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -5525,14 +5544,14 @@ authRoutes.post(
|
|
|
5525
5544
|
await saveCustomData(db, userId, sanitized);
|
|
5526
5545
|
}
|
|
5527
5546
|
}
|
|
5528
|
-
const
|
|
5547
|
+
const tokenTtl = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
5548
|
+
const token = await chunk3TVMUQWG_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET, tokenTtl);
|
|
5529
5549
|
cookie.setCookie(c, "auth_token", token, {
|
|
5530
5550
|
httpOnly: true,
|
|
5531
5551
|
secure: false,
|
|
5532
5552
|
// Set to true in production with HTTPS
|
|
5533
5553
|
sameSite: "Strict",
|
|
5534
|
-
maxAge:
|
|
5535
|
-
// 24 hours
|
|
5554
|
+
maxAge: tokenTtl
|
|
5536
5555
|
});
|
|
5537
5556
|
await setCsrfCookie(c);
|
|
5538
5557
|
const redirectUrl = role === "admin" ? "/admin/dashboard" : "/admin/dashboard";
|
|
@@ -5558,7 +5577,7 @@ authRoutes.post(
|
|
|
5558
5577
|
);
|
|
5559
5578
|
authRoutes.post(
|
|
5560
5579
|
"/login/form",
|
|
5561
|
-
|
|
5580
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
|
|
5562
5581
|
async (c) => {
|
|
5563
5582
|
try {
|
|
5564
5583
|
const formData = await c.req.formData();
|
|
@@ -5582,7 +5601,7 @@ authRoutes.post(
|
|
|
5582
5601
|
</div>
|
|
5583
5602
|
`);
|
|
5584
5603
|
}
|
|
5585
|
-
const isValidPassword = await
|
|
5604
|
+
const isValidPassword = await chunk3TVMUQWG_cjs.AuthManager.verifyPassword(password, user.password_hash);
|
|
5586
5605
|
if (!isValidPassword) {
|
|
5587
5606
|
return c.html(html.html`
|
|
5588
5607
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
|
|
@@ -5590,22 +5609,22 @@ authRoutes.post(
|
|
|
5590
5609
|
</div>
|
|
5591
5610
|
`);
|
|
5592
5611
|
}
|
|
5593
|
-
if (
|
|
5612
|
+
if (chunk3TVMUQWG_cjs.AuthManager.isLegacyHash(user.password_hash)) {
|
|
5594
5613
|
try {
|
|
5595
|
-
const newHash = await
|
|
5614
|
+
const newHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
5596
5615
|
await db.prepare("UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?").bind(newHash, Date.now(), user.id).run();
|
|
5597
5616
|
} catch (rehashError) {
|
|
5598
5617
|
console.error("Password rehash failed (non-fatal):", rehashError);
|
|
5599
5618
|
}
|
|
5600
5619
|
}
|
|
5601
|
-
const
|
|
5620
|
+
const tokenTtl = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
5621
|
+
const token = await chunk3TVMUQWG_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
|
|
5602
5622
|
cookie.setCookie(c, "auth_token", token, {
|
|
5603
5623
|
httpOnly: true,
|
|
5604
5624
|
secure: false,
|
|
5605
5625
|
// Set to true in production with HTTPS
|
|
5606
5626
|
sameSite: "Strict",
|
|
5607
|
-
maxAge:
|
|
5608
|
-
// 24 hours
|
|
5627
|
+
maxAge: tokenTtl
|
|
5609
5628
|
});
|
|
5610
5629
|
await setCsrfCookie(c);
|
|
5611
5630
|
await db.prepare("UPDATE users SET last_login_at = ? WHERE id = ?").bind((/* @__PURE__ */ new Date()).getTime(), user.id).run();
|
|
@@ -5640,7 +5659,7 @@ authRoutes.post(
|
|
|
5640
5659
|
);
|
|
5641
5660
|
authRoutes.post(
|
|
5642
5661
|
"/seed-admin",
|
|
5643
|
-
|
|
5662
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 10, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
|
|
5644
5663
|
async (c) => {
|
|
5645
5664
|
try {
|
|
5646
5665
|
const db = c.env.DB;
|
|
@@ -5662,7 +5681,7 @@ authRoutes.post(
|
|
|
5662
5681
|
`).run();
|
|
5663
5682
|
const existingAdmin = await db.prepare("SELECT id FROM users WHERE email = ? OR username = ?").bind("admin@sonicjs.com", "admin").first();
|
|
5664
5683
|
if (existingAdmin) {
|
|
5665
|
-
const passwordHash2 = await
|
|
5684
|
+
const passwordHash2 = await chunk3TVMUQWG_cjs.AuthManager.hashPassword("sonicjs!");
|
|
5666
5685
|
await db.prepare("UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?").bind(passwordHash2, Date.now(), existingAdmin.id).run();
|
|
5667
5686
|
return c.json({
|
|
5668
5687
|
message: "Admin user already exists (password updated)",
|
|
@@ -5674,7 +5693,7 @@ authRoutes.post(
|
|
|
5674
5693
|
}
|
|
5675
5694
|
});
|
|
5676
5695
|
}
|
|
5677
|
-
const passwordHash = await
|
|
5696
|
+
const passwordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword("sonicjs!");
|
|
5678
5697
|
const userId = "admin-user-id";
|
|
5679
5698
|
const now = Date.now();
|
|
5680
5699
|
const adminEmail = "admin@sonicjs.com".toLowerCase();
|
|
@@ -5895,7 +5914,7 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
5895
5914
|
if (existingUsername) {
|
|
5896
5915
|
return c.json({ error: "Username is already taken" }, 400);
|
|
5897
5916
|
}
|
|
5898
|
-
const passwordHash = await
|
|
5917
|
+
const passwordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
5899
5918
|
const updateStmt = db.prepare(`
|
|
5900
5919
|
UPDATE users SET
|
|
5901
5920
|
username = ?,
|
|
@@ -5914,13 +5933,13 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
5914
5933
|
Date.now(),
|
|
5915
5934
|
invitedUser.id
|
|
5916
5935
|
).run();
|
|
5917
|
-
const
|
|
5936
|
+
const tokenTtl = await chunk3TVMUQWG_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
5937
|
+
const authToken = await chunk3TVMUQWG_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET, tokenTtl);
|
|
5918
5938
|
cookie.setCookie(c, "auth_token", authToken, {
|
|
5919
5939
|
httpOnly: true,
|
|
5920
5940
|
secure: true,
|
|
5921
5941
|
sameSite: "Strict",
|
|
5922
|
-
maxAge:
|
|
5923
|
-
// 24 hours
|
|
5942
|
+
maxAge: tokenTtl
|
|
5924
5943
|
});
|
|
5925
5944
|
await setCsrfCookie(c);
|
|
5926
5945
|
return c.redirect("/admin/dashboard?welcome=true");
|
|
@@ -5931,7 +5950,7 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
5931
5950
|
});
|
|
5932
5951
|
authRoutes.post(
|
|
5933
5952
|
"/request-password-reset",
|
|
5934
|
-
|
|
5953
|
+
chunk3TVMUQWG_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
|
|
5935
5954
|
async (c) => {
|
|
5936
5955
|
try {
|
|
5937
5956
|
const formData = await c.req.formData();
|
|
@@ -6149,7 +6168,7 @@ authRoutes.post("/reset-password", async (c) => {
|
|
|
6149
6168
|
if (Date.now() > user.password_reset_expires) {
|
|
6150
6169
|
return c.json({ error: "Reset token has expired" }, 400);
|
|
6151
6170
|
}
|
|
6152
|
-
const newPasswordHash = await
|
|
6171
|
+
const newPasswordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
6153
6172
|
try {
|
|
6154
6173
|
const historyStmt = db.prepare(`
|
|
6155
6174
|
INSERT INTO password_history (id, user_id, password_hash, created_at)
|
|
@@ -9525,9 +9544,9 @@ function parseFieldValue(field, formData, options = {}) {
|
|
|
9525
9544
|
const { skipValidation = false } = options;
|
|
9526
9545
|
const value = formData.get(field.field_name);
|
|
9527
9546
|
const errors = [];
|
|
9528
|
-
const blocksConfig =
|
|
9547
|
+
const blocksConfig = chunk5EBTBD2Z_cjs.getBlocksFieldConfig(field.field_options);
|
|
9529
9548
|
if (blocksConfig) {
|
|
9530
|
-
const parsed =
|
|
9549
|
+
const parsed = chunk5EBTBD2Z_cjs.parseBlocksValue(value, blocksConfig);
|
|
9531
9550
|
if (!skipValidation && field.is_required && parsed.value.length === 0) {
|
|
9532
9551
|
parsed.errors.push(`${field.field_label} is required`);
|
|
9533
9552
|
}
|
|
@@ -9637,9 +9656,9 @@ function extractFieldData(fields, formData, options = {}) {
|
|
|
9637
9656
|
}
|
|
9638
9657
|
return { data, errors };
|
|
9639
9658
|
}
|
|
9640
|
-
adminContentRoutes.use("*",
|
|
9659
|
+
adminContentRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
9641
9660
|
async function getCollectionFields(db, collectionId) {
|
|
9642
|
-
const cache =
|
|
9661
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.collection);
|
|
9643
9662
|
return cache.getOrSet(
|
|
9644
9663
|
cache.generateKey("fields", collectionId),
|
|
9645
9664
|
async () => {
|
|
@@ -9688,7 +9707,7 @@ async function getCollectionFields(db, collectionId) {
|
|
|
9688
9707
|
);
|
|
9689
9708
|
}
|
|
9690
9709
|
async function getCollection(db, collectionId) {
|
|
9691
|
-
const cache =
|
|
9710
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.collection);
|
|
9692
9711
|
return cache.getOrSet(
|
|
9693
9712
|
cache.generateKey("collection", collectionId),
|
|
9694
9713
|
async () => {
|
|
@@ -9914,21 +9933,21 @@ adminContentRoutes.get("/new", async (c) => {
|
|
|
9914
9933
|
const tinymceEnabled = await isPluginActive2(db, "tinymce-plugin");
|
|
9915
9934
|
let tinymceSettings;
|
|
9916
9935
|
if (tinymceEnabled) {
|
|
9917
|
-
const pluginService = new
|
|
9936
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
9918
9937
|
const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
|
|
9919
9938
|
tinymceSettings = tinymcePlugin2?.settings;
|
|
9920
9939
|
}
|
|
9921
9940
|
const quillEnabled = await isPluginActive2(db, "quill-editor");
|
|
9922
9941
|
let quillSettings;
|
|
9923
9942
|
if (quillEnabled) {
|
|
9924
|
-
const pluginService = new
|
|
9943
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
9925
9944
|
const quillPlugin = await pluginService.getPlugin("quill-editor");
|
|
9926
9945
|
quillSettings = quillPlugin?.settings;
|
|
9927
9946
|
}
|
|
9928
9947
|
const mdxeditorEnabled = await isPluginActive2(db, "easy-mdx");
|
|
9929
9948
|
let mdxeditorSettings;
|
|
9930
9949
|
if (mdxeditorEnabled) {
|
|
9931
|
-
const pluginService = new
|
|
9950
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
9932
9951
|
const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
|
|
9933
9952
|
mdxeditorSettings = mdxeditorPlugin?.settings;
|
|
9934
9953
|
}
|
|
@@ -9978,7 +9997,7 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
9978
9997
|
const db = c.env.DB;
|
|
9979
9998
|
const url = new URL(c.req.url);
|
|
9980
9999
|
const referrerParams = url.searchParams.get("ref") || "";
|
|
9981
|
-
const cache =
|
|
10000
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.content);
|
|
9982
10001
|
const content = await cache.getOrSet(
|
|
9983
10002
|
cache.generateKey("content", id),
|
|
9984
10003
|
async () => {
|
|
@@ -10019,21 +10038,21 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
10019
10038
|
const tinymceEnabled = await isPluginActive2(db, "tinymce-plugin");
|
|
10020
10039
|
let tinymceSettings;
|
|
10021
10040
|
if (tinymceEnabled) {
|
|
10022
|
-
const pluginService = new
|
|
10041
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
10023
10042
|
const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
|
|
10024
10043
|
tinymceSettings = tinymcePlugin2?.settings;
|
|
10025
10044
|
}
|
|
10026
10045
|
const quillEnabled = await isPluginActive2(db, "quill-editor");
|
|
10027
10046
|
let quillSettings;
|
|
10028
10047
|
if (quillEnabled) {
|
|
10029
|
-
const pluginService = new
|
|
10048
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
10030
10049
|
const quillPlugin = await pluginService.getPlugin("quill-editor");
|
|
10031
10050
|
quillSettings = quillPlugin?.settings;
|
|
10032
10051
|
}
|
|
10033
10052
|
const mdxeditorEnabled = await isPluginActive2(db, "easy-mdx");
|
|
10034
10053
|
let mdxeditorSettings;
|
|
10035
10054
|
if (mdxeditorEnabled) {
|
|
10036
|
-
const pluginService = new
|
|
10055
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
10037
10056
|
const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
|
|
10038
10057
|
mdxeditorSettings = mdxeditorPlugin?.settings;
|
|
10039
10058
|
}
|
|
@@ -10154,7 +10173,7 @@ adminContentRoutes.post("/", async (c) => {
|
|
|
10154
10173
|
now,
|
|
10155
10174
|
now
|
|
10156
10175
|
).run();
|
|
10157
|
-
const cache =
|
|
10176
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.content);
|
|
10158
10177
|
await cache.invalidate(`content:list:${collectionId}:*`);
|
|
10159
10178
|
const versionStmt = db.prepare(`
|
|
10160
10179
|
INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)
|
|
@@ -10273,7 +10292,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
10273
10292
|
now,
|
|
10274
10293
|
id
|
|
10275
10294
|
).run();
|
|
10276
|
-
const cache =
|
|
10295
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.content);
|
|
10277
10296
|
await cache.delete(cache.generateKey("content", id));
|
|
10278
10297
|
await cache.invalidate(`content:list:${existingContent.collection_id}:*`);
|
|
10279
10298
|
const existingData = JSON.parse(existingContent.data || "{}");
|
|
@@ -10328,7 +10347,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
10328
10347
|
`);
|
|
10329
10348
|
}
|
|
10330
10349
|
});
|
|
10331
|
-
adminContentRoutes.post("/preview",
|
|
10350
|
+
adminContentRoutes.post("/preview", chunk3TVMUQWG_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
10332
10351
|
try {
|
|
10333
10352
|
const formData = await c.req.formData();
|
|
10334
10353
|
const collectionId = formData.get("collection_id");
|
|
@@ -10550,7 +10569,7 @@ adminContentRoutes.post("/bulk-action", async (c) => {
|
|
|
10550
10569
|
} else {
|
|
10551
10570
|
return c.json({ success: false, error: "Invalid action" });
|
|
10552
10571
|
}
|
|
10553
|
-
const cache =
|
|
10572
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.content);
|
|
10554
10573
|
for (const contentId of ids) {
|
|
10555
10574
|
await cache.delete(cache.generateKey("content", contentId));
|
|
10556
10575
|
}
|
|
@@ -10578,7 +10597,7 @@ adminContentRoutes.delete("/:id", async (c) => {
|
|
|
10578
10597
|
WHERE id = ?
|
|
10579
10598
|
`);
|
|
10580
10599
|
await deleteStmt.bind(now, id).run();
|
|
10581
|
-
const cache =
|
|
10600
|
+
const cache = chunkWAEQXGCX_cjs.getCacheService(chunkWAEQXGCX_cjs.CACHE_CONFIGS.content);
|
|
10582
10601
|
await cache.delete(cache.generateKey("content", id));
|
|
10583
10602
|
await cache.invalidate("content:list:*");
|
|
10584
10603
|
return c.html(`
|
|
@@ -10706,7 +10725,7 @@ adminContentRoutes.post("/:id/restore/:version", async (c) => {
|
|
|
10706
10725
|
return c.json({ success: false, error: "Failed to restore version" });
|
|
10707
10726
|
}
|
|
10708
10727
|
});
|
|
10709
|
-
adminContentRoutes.get("/:id/version/:version/preview",
|
|
10728
|
+
adminContentRoutes.get("/:id/version/:version/preview", chunk3TVMUQWG_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
10710
10729
|
try {
|
|
10711
10730
|
const id = c.req.param("id");
|
|
10712
10731
|
const version = parseInt(c.req.param("version") || "0");
|
|
@@ -11629,7 +11648,6 @@ function renderUserEditPage(data) {
|
|
|
11629
11648
|
type="text"
|
|
11630
11649
|
name="first_name"
|
|
11631
11650
|
value="${chunkMNWKYY5E_cjs.escapeHtml(data.userToEdit.firstName || "")}"
|
|
11632
|
-
required
|
|
11633
11651
|
class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
|
|
11634
11652
|
/>
|
|
11635
11653
|
</div>
|
|
@@ -11640,7 +11658,6 @@ function renderUserEditPage(data) {
|
|
|
11640
11658
|
type="text"
|
|
11641
11659
|
name="last_name"
|
|
11642
11660
|
value="${chunkMNWKYY5E_cjs.escapeHtml(data.userToEdit.lastName || "")}"
|
|
11643
|
-
required
|
|
11644
11661
|
class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
|
|
11645
11662
|
/>
|
|
11646
11663
|
</div>
|
|
@@ -12707,14 +12724,14 @@ function renderUsersListPage(data) {
|
|
|
12707
12724
|
|
|
12708
12725
|
// src/routes/admin-users.ts
|
|
12709
12726
|
var userRoutes = new hono.Hono();
|
|
12710
|
-
userRoutes.use("*",
|
|
12711
|
-
userRoutes.use("/users/*",
|
|
12712
|
-
userRoutes.use("/users",
|
|
12713
|
-
userRoutes.use("/invite-user",
|
|
12714
|
-
userRoutes.use("/resend-invitation/*",
|
|
12715
|
-
userRoutes.use("/cancel-invitation/*",
|
|
12716
|
-
userRoutes.use("/activity-logs",
|
|
12717
|
-
userRoutes.use("/activity-logs/*",
|
|
12727
|
+
userRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
12728
|
+
userRoutes.use("/users/*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12729
|
+
userRoutes.use("/users", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12730
|
+
userRoutes.use("/invite-user", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12731
|
+
userRoutes.use("/resend-invitation/*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12732
|
+
userRoutes.use("/cancel-invitation/*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12733
|
+
userRoutes.use("/activity-logs", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12734
|
+
userRoutes.use("/activity-logs/*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
12718
12735
|
userRoutes.get("/", (c) => {
|
|
12719
12736
|
return c.redirect("/admin/dashboard");
|
|
12720
12737
|
});
|
|
@@ -12884,7 +12901,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
12884
12901
|
}
|
|
12885
12902
|
await saveCustomData(db, user.userId, sanitized);
|
|
12886
12903
|
}
|
|
12887
|
-
await
|
|
12904
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
12888
12905
|
db,
|
|
12889
12906
|
user.userId,
|
|
12890
12907
|
"profile.update",
|
|
@@ -12947,7 +12964,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
12947
12964
|
SELECT first_name, last_name FROM users WHERE id = ?
|
|
12948
12965
|
`);
|
|
12949
12966
|
const userData = await userStmt.bind(user.userId).first();
|
|
12950
|
-
await
|
|
12967
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
12951
12968
|
db,
|
|
12952
12969
|
user.userId,
|
|
12953
12970
|
"profile.avatar_update",
|
|
@@ -13018,7 +13035,7 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
13018
13035
|
dismissible: true
|
|
13019
13036
|
}));
|
|
13020
13037
|
}
|
|
13021
|
-
const validPassword = await
|
|
13038
|
+
const validPassword = await chunk3TVMUQWG_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
|
|
13022
13039
|
if (!validPassword) {
|
|
13023
13040
|
return c.html(renderAlert2({
|
|
13024
13041
|
type: "error",
|
|
@@ -13026,7 +13043,7 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
13026
13043
|
dismissible: true
|
|
13027
13044
|
}));
|
|
13028
13045
|
}
|
|
13029
|
-
const newPasswordHash = await
|
|
13046
|
+
const newPasswordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(newPassword);
|
|
13030
13047
|
const historyStmt = db.prepare(`
|
|
13031
13048
|
INSERT INTO password_history (id, user_id, password_hash, created_at)
|
|
13032
13049
|
VALUES (?, ?, ?, ?)
|
|
@@ -13042,7 +13059,7 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
13042
13059
|
WHERE id = ?
|
|
13043
13060
|
`);
|
|
13044
13061
|
await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
|
|
13045
|
-
await
|
|
13062
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13046
13063
|
db,
|
|
13047
13064
|
user.userId,
|
|
13048
13065
|
"profile.password_change",
|
|
@@ -13109,7 +13126,7 @@ userRoutes.get("/users", async (c) => {
|
|
|
13109
13126
|
`);
|
|
13110
13127
|
const countResult = await countStmt.bind(...params).first();
|
|
13111
13128
|
const totalUsers = countResult?.total || 0;
|
|
13112
|
-
await
|
|
13129
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13113
13130
|
db,
|
|
13114
13131
|
user.userId,
|
|
13115
13132
|
"users.list_view",
|
|
@@ -13267,7 +13284,7 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
13267
13284
|
dismissible: true
|
|
13268
13285
|
}));
|
|
13269
13286
|
}
|
|
13270
|
-
const passwordHash = await
|
|
13287
|
+
const passwordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(password);
|
|
13271
13288
|
const userId = crypto.randomUUID();
|
|
13272
13289
|
const createStmt = db.prepare(`
|
|
13273
13290
|
INSERT INTO users (
|
|
@@ -13290,7 +13307,7 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
13290
13307
|
Date.now(),
|
|
13291
13308
|
Date.now()
|
|
13292
13309
|
).run();
|
|
13293
|
-
await
|
|
13310
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13294
13311
|
db,
|
|
13295
13312
|
user.userId,
|
|
13296
13313
|
"user!.create",
|
|
@@ -13329,7 +13346,7 @@ userRoutes.get("/users/:id", async (c) => {
|
|
|
13329
13346
|
if (!userRecord) {
|
|
13330
13347
|
return c.json({ error: "User not found" }, 404);
|
|
13331
13348
|
}
|
|
13332
|
-
await
|
|
13349
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13333
13350
|
db,
|
|
13334
13351
|
user.userId,
|
|
13335
13352
|
"user!.view",
|
|
@@ -13481,10 +13498,10 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
13481
13498
|
const merged = { ...existingCustom, ...sanitized };
|
|
13482
13499
|
customDataJson = JSON.stringify(merged);
|
|
13483
13500
|
}
|
|
13484
|
-
if (!
|
|
13501
|
+
if (!username || !email) {
|
|
13485
13502
|
return c.html(renderAlert2({
|
|
13486
13503
|
type: "error",
|
|
13487
|
-
message: "
|
|
13504
|
+
message: "Username and email are required.",
|
|
13488
13505
|
dismissible: true
|
|
13489
13506
|
}));
|
|
13490
13507
|
}
|
|
@@ -13555,7 +13572,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
13555
13572
|
userId
|
|
13556
13573
|
).run();
|
|
13557
13574
|
if (newPassword) {
|
|
13558
|
-
const passwordHash = await
|
|
13575
|
+
const passwordHash = await chunk3TVMUQWG_cjs.AuthManager.hashPassword(newPassword);
|
|
13559
13576
|
const updatePasswordStmt = db.prepare(`
|
|
13560
13577
|
UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?
|
|
13561
13578
|
`);
|
|
@@ -13609,7 +13626,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
13609
13626
|
).run();
|
|
13610
13627
|
}
|
|
13611
13628
|
}
|
|
13612
|
-
await
|
|
13629
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13613
13630
|
db,
|
|
13614
13631
|
user.userId,
|
|
13615
13632
|
"user.update",
|
|
@@ -13654,7 +13671,7 @@ userRoutes.post("/users/:id/toggle", async (c) => {
|
|
|
13654
13671
|
UPDATE users SET is_active = ?, updated_at = ? WHERE id = ?
|
|
13655
13672
|
`);
|
|
13656
13673
|
await toggleStmt.bind(active ? 1 : 0, Date.now(), userId).run();
|
|
13657
|
-
await
|
|
13674
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13658
13675
|
db,
|
|
13659
13676
|
user.userId,
|
|
13660
13677
|
active ? "user.activate" : "user.deactivate",
|
|
@@ -13695,7 +13712,7 @@ userRoutes.delete("/users/:id", async (c) => {
|
|
|
13695
13712
|
DELETE FROM users WHERE id = ?
|
|
13696
13713
|
`);
|
|
13697
13714
|
await deleteStmt.bind(userId).run();
|
|
13698
|
-
await
|
|
13715
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13699
13716
|
db,
|
|
13700
13717
|
user.userId,
|
|
13701
13718
|
"user!.hard_delete",
|
|
@@ -13714,7 +13731,7 @@ userRoutes.delete("/users/:id", async (c) => {
|
|
|
13714
13731
|
UPDATE users SET is_active = 0, updated_at = ? WHERE id = ?
|
|
13715
13732
|
`);
|
|
13716
13733
|
await deleteStmt.bind(Date.now(), userId).run();
|
|
13717
|
-
await
|
|
13734
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13718
13735
|
db,
|
|
13719
13736
|
user.userId,
|
|
13720
13737
|
"user!.soft_delete",
|
|
@@ -13780,7 +13797,7 @@ userRoutes.post("/invite-user", async (c) => {
|
|
|
13780
13797
|
Date.now(),
|
|
13781
13798
|
Date.now()
|
|
13782
13799
|
).run();
|
|
13783
|
-
await
|
|
13800
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13784
13801
|
db,
|
|
13785
13802
|
user.userId,
|
|
13786
13803
|
"user!.invite_sent",
|
|
@@ -13837,7 +13854,7 @@ userRoutes.post("/resend-invitation/:id", async (c) => {
|
|
|
13837
13854
|
Date.now(),
|
|
13838
13855
|
userId
|
|
13839
13856
|
).run();
|
|
13840
|
-
await
|
|
13857
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13841
13858
|
db,
|
|
13842
13859
|
user.userId,
|
|
13843
13860
|
"user!.invitation_resent",
|
|
@@ -13873,7 +13890,7 @@ userRoutes.delete("/cancel-invitation/:id", async (c) => {
|
|
|
13873
13890
|
}
|
|
13874
13891
|
const deleteStmt = db.prepare(`DELETE FROM users WHERE id = ?`);
|
|
13875
13892
|
await deleteStmt.bind(userId).run();
|
|
13876
|
-
await
|
|
13893
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13877
13894
|
db,
|
|
13878
13895
|
user.userId,
|
|
13879
13896
|
"user!.invitation_cancelled",
|
|
@@ -13956,7 +13973,7 @@ userRoutes.get("/activity-logs", async (c) => {
|
|
|
13956
13973
|
...log,
|
|
13957
13974
|
details: log.details ? JSON.parse(log.details) : null
|
|
13958
13975
|
}));
|
|
13959
|
-
await
|
|
13976
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
13960
13977
|
db,
|
|
13961
13978
|
user.userId,
|
|
13962
13979
|
"activity.logs_viewed",
|
|
@@ -14063,7 +14080,7 @@ userRoutes.get("/activity-logs/export", async (c) => {
|
|
|
14063
14080
|
csvRows.push(row.join(","));
|
|
14064
14081
|
}
|
|
14065
14082
|
const csvContent = csvRows.join("\n");
|
|
14066
|
-
await
|
|
14083
|
+
await chunk3TVMUQWG_cjs.logActivity(
|
|
14067
14084
|
db,
|
|
14068
14085
|
user.userId,
|
|
14069
14086
|
"activity.logs_exported",
|
|
@@ -15402,7 +15419,7 @@ var fileValidationSchema2 = zod.z.object({
|
|
|
15402
15419
|
// 50MB max
|
|
15403
15420
|
});
|
|
15404
15421
|
var adminMediaRoutes = new hono.Hono();
|
|
15405
|
-
adminMediaRoutes.use("*",
|
|
15422
|
+
adminMediaRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
15406
15423
|
adminMediaRoutes.get("/", async (c) => {
|
|
15407
15424
|
try {
|
|
15408
15425
|
const user = c.get("user");
|
|
@@ -15988,7 +16005,7 @@ adminMediaRoutes.put("/:id", async (c) => {
|
|
|
15988
16005
|
`);
|
|
15989
16006
|
}
|
|
15990
16007
|
});
|
|
15991
|
-
adminMediaRoutes.delete("/cleanup",
|
|
16008
|
+
adminMediaRoutes.delete("/cleanup", chunk3TVMUQWG_cjs.requireRole("admin"), async (c) => {
|
|
15992
16009
|
try {
|
|
15993
16010
|
const db = c.env.DB;
|
|
15994
16011
|
const allMediaStmt = db.prepare("SELECT id, r2_key, filename FROM media WHERE deleted_at IS NULL");
|
|
@@ -18213,8 +18230,8 @@ function renderEmailSettingsContent(plugin, settings) {
|
|
|
18213
18230
|
|
|
18214
18231
|
// src/routes/admin-plugins.ts
|
|
18215
18232
|
var adminPluginRoutes = new hono.Hono();
|
|
18216
|
-
adminPluginRoutes.use("*",
|
|
18217
|
-
var AVAILABLE_PLUGINS = Object.values(
|
|
18233
|
+
adminPluginRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
18234
|
+
var AVAILABLE_PLUGINS = Object.values(chunk47HKH3D6_cjs.PLUGIN_REGISTRY).map((p) => ({
|
|
18218
18235
|
id: p.id,
|
|
18219
18236
|
name: p.codeName,
|
|
18220
18237
|
display_name: p.displayName,
|
|
@@ -18234,7 +18251,7 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
18234
18251
|
if (user?.role !== "admin") {
|
|
18235
18252
|
return c.text("Access denied", 403);
|
|
18236
18253
|
}
|
|
18237
|
-
const pluginService = new
|
|
18254
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18238
18255
|
let installedPlugins = [];
|
|
18239
18256
|
let stats = { total: 0, active: 0, inactive: 0, errors: 0, uninstalled: 0 };
|
|
18240
18257
|
try {
|
|
@@ -18306,7 +18323,7 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
18306
18323
|
if (user?.role !== "admin") {
|
|
18307
18324
|
return c.redirect("/admin/plugins");
|
|
18308
18325
|
}
|
|
18309
|
-
const pluginService = new
|
|
18326
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18310
18327
|
const plugin = await pluginService.getPlugin(pluginId);
|
|
18311
18328
|
if (!plugin) {
|
|
18312
18329
|
return c.text("Plugin not found", 404);
|
|
@@ -18314,7 +18331,7 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
18314
18331
|
const activity = await pluginService.getPluginActivity(pluginId, 20);
|
|
18315
18332
|
let enrichedSettings = plugin.settings || {};
|
|
18316
18333
|
if (pluginId === "otp-login") {
|
|
18317
|
-
const settingsService = new
|
|
18334
|
+
const settingsService = new chunkWAEQXGCX_cjs.SettingsService(db);
|
|
18318
18335
|
const generalSettings = await settingsService.getGeneralSettings();
|
|
18319
18336
|
const siteName = generalSettings.siteName || "SonicJS";
|
|
18320
18337
|
const emailPlugin = await db.prepare(`
|
|
@@ -18382,7 +18399,7 @@ adminPluginRoutes.post("/:id/activate", async (c) => {
|
|
|
18382
18399
|
if (user?.role !== "admin") {
|
|
18383
18400
|
return c.json({ error: "Access denied" }, 403);
|
|
18384
18401
|
}
|
|
18385
|
-
const pluginService = new
|
|
18402
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18386
18403
|
await pluginService.activatePlugin(pluginId);
|
|
18387
18404
|
return c.json({ success: true });
|
|
18388
18405
|
} catch (error) {
|
|
@@ -18399,7 +18416,7 @@ adminPluginRoutes.post("/:id/deactivate", async (c) => {
|
|
|
18399
18416
|
if (user?.role !== "admin") {
|
|
18400
18417
|
return c.json({ error: "Access denied" }, 403);
|
|
18401
18418
|
}
|
|
18402
|
-
const pluginService = new
|
|
18419
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18403
18420
|
await pluginService.deactivatePlugin(pluginId);
|
|
18404
18421
|
return c.json({ success: true });
|
|
18405
18422
|
} catch (error) {
|
|
@@ -18416,8 +18433,8 @@ adminPluginRoutes.post("/install", async (c) => {
|
|
|
18416
18433
|
return c.json({ error: "Access denied" }, 403);
|
|
18417
18434
|
}
|
|
18418
18435
|
const body = await c.req.json();
|
|
18419
|
-
const pluginService = new
|
|
18420
|
-
const registryEntry =
|
|
18436
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18437
|
+
const registryEntry = chunk47HKH3D6_cjs.findPluginByCodeName(body.name) || chunk47HKH3D6_cjs.PLUGIN_REGISTRY[body.name] || chunk47HKH3D6_cjs.PLUGIN_REGISTRY[body.id];
|
|
18421
18438
|
if (!registryEntry) {
|
|
18422
18439
|
return c.json({ error: "Plugin not found in registry" }, 404);
|
|
18423
18440
|
}
|
|
@@ -18450,7 +18467,7 @@ adminPluginRoutes.post("/:id/uninstall", async (c) => {
|
|
|
18450
18467
|
if (user?.role !== "admin") {
|
|
18451
18468
|
return c.json({ error: "Access denied" }, 403);
|
|
18452
18469
|
}
|
|
18453
|
-
const pluginService = new
|
|
18470
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18454
18471
|
await pluginService.uninstallPlugin(pluginId);
|
|
18455
18472
|
return c.json({ success: true });
|
|
18456
18473
|
} catch (error) {
|
|
@@ -18468,7 +18485,7 @@ adminPluginRoutes.post("/:id/settings", async (c) => {
|
|
|
18468
18485
|
return c.json({ error: "Access denied" }, 403);
|
|
18469
18486
|
}
|
|
18470
18487
|
const settings = await c.req.json();
|
|
18471
|
-
const pluginService = new
|
|
18488
|
+
const pluginService = new chunk47HKH3D6_cjs.PluginService(db);
|
|
18472
18489
|
await pluginService.updatePluginSettings(pluginId, settings);
|
|
18473
18490
|
if (pluginId === "core-auth") {
|
|
18474
18491
|
try {
|
|
@@ -19276,11 +19293,11 @@ function renderLogConfigPage(data) {
|
|
|
19276
19293
|
|
|
19277
19294
|
// src/routes/admin-logs.ts
|
|
19278
19295
|
var adminLogsRoutes = new hono.Hono();
|
|
19279
|
-
adminLogsRoutes.use("*",
|
|
19296
|
+
adminLogsRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
19280
19297
|
adminLogsRoutes.get("/", async (c) => {
|
|
19281
19298
|
try {
|
|
19282
19299
|
const user = c.get("user");
|
|
19283
|
-
const logger =
|
|
19300
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19284
19301
|
const query = c.req.query();
|
|
19285
19302
|
const page = parseInt(query.page || "1");
|
|
19286
19303
|
const limit = parseInt(query.limit || "50");
|
|
@@ -19360,7 +19377,7 @@ adminLogsRoutes.get("/:id", async (c) => {
|
|
|
19360
19377
|
try {
|
|
19361
19378
|
const id = c.req.param("id");
|
|
19362
19379
|
const user = c.get("user");
|
|
19363
|
-
const logger =
|
|
19380
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19364
19381
|
const { logs } = await logger.getLogs({
|
|
19365
19382
|
limit: 1,
|
|
19366
19383
|
offset: 0,
|
|
@@ -19397,7 +19414,7 @@ adminLogsRoutes.get("/:id", async (c) => {
|
|
|
19397
19414
|
adminLogsRoutes.get("/config", async (c) => {
|
|
19398
19415
|
try {
|
|
19399
19416
|
const user = c.get("user");
|
|
19400
|
-
const logger =
|
|
19417
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19401
19418
|
const configs = await logger.getAllConfigs();
|
|
19402
19419
|
const pageData = {
|
|
19403
19420
|
configs,
|
|
@@ -19421,7 +19438,7 @@ adminLogsRoutes.post("/config/:category", async (c) => {
|
|
|
19421
19438
|
const level = formData.get("level");
|
|
19422
19439
|
const retention = parseInt(formData.get("retention"));
|
|
19423
19440
|
const maxSize = parseInt(formData.get("max_size"));
|
|
19424
|
-
const logger =
|
|
19441
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19425
19442
|
await logger.updateConfig(category, {
|
|
19426
19443
|
enabled,
|
|
19427
19444
|
level,
|
|
@@ -19450,7 +19467,7 @@ adminLogsRoutes.get("/export", async (c) => {
|
|
|
19450
19467
|
const category = query.category;
|
|
19451
19468
|
const startDate = query.start_date;
|
|
19452
19469
|
const endDate = query.end_date;
|
|
19453
|
-
const logger =
|
|
19470
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19454
19471
|
const filter = {
|
|
19455
19472
|
limit: 1e4,
|
|
19456
19473
|
// Export up to 10k logs
|
|
@@ -19531,7 +19548,7 @@ adminLogsRoutes.post("/cleanup", async (c) => {
|
|
|
19531
19548
|
error: "Unauthorized. Admin access required."
|
|
19532
19549
|
}, 403);
|
|
19533
19550
|
}
|
|
19534
|
-
const logger =
|
|
19551
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19535
19552
|
await logger.cleanupByRetention();
|
|
19536
19553
|
return c.html(html.html`
|
|
19537
19554
|
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
|
|
@@ -19553,7 +19570,7 @@ adminLogsRoutes.post("/search", async (c) => {
|
|
|
19553
19570
|
const search = formData.get("search");
|
|
19554
19571
|
const level = formData.get("level");
|
|
19555
19572
|
const category = formData.get("category");
|
|
19556
|
-
const logger =
|
|
19573
|
+
const logger = chunkWAEQXGCX_cjs.getLogger(c.env.DB);
|
|
19557
19574
|
const filter = {
|
|
19558
19575
|
limit: 20,
|
|
19559
19576
|
offset: 0,
|
|
@@ -21604,9 +21621,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
|
|
|
21604
21621
|
}
|
|
21605
21622
|
|
|
21606
21623
|
// src/routes/admin-dashboard.ts
|
|
21607
|
-
var VERSION =
|
|
21624
|
+
var VERSION = chunk5EBTBD2Z_cjs.getCoreVersion();
|
|
21608
21625
|
var router = new hono.Hono();
|
|
21609
|
-
router.use("*",
|
|
21626
|
+
router.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
21610
21627
|
router.get("/", async (c) => {
|
|
21611
21628
|
const user = c.get("user");
|
|
21612
21629
|
try {
|
|
@@ -23425,10 +23442,10 @@ function renderCollectionFormPage(data) {
|
|
|
23425
23442
|
|
|
23426
23443
|
// src/routes/admin-collections.ts
|
|
23427
23444
|
var adminCollectionsRoutes = new hono.Hono();
|
|
23428
|
-
adminCollectionsRoutes.use("*",
|
|
23429
|
-
adminCollectionsRoutes.post("*",
|
|
23430
|
-
adminCollectionsRoutes.put("*",
|
|
23431
|
-
adminCollectionsRoutes.delete("*",
|
|
23445
|
+
adminCollectionsRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
23446
|
+
adminCollectionsRoutes.post("*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
23447
|
+
adminCollectionsRoutes.put("*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
23448
|
+
adminCollectionsRoutes.delete("*", chunk3TVMUQWG_cjs.requireRole(["admin"]));
|
|
23432
23449
|
adminCollectionsRoutes.get("/", async (c) => {
|
|
23433
23450
|
try {
|
|
23434
23451
|
const user = c.get("user");
|
|
@@ -24241,6 +24258,43 @@ function renderSettingsPage(data) {
|
|
|
24241
24258
|
}
|
|
24242
24259
|
}
|
|
24243
24260
|
|
|
24261
|
+
async function saveSecuritySettings() {
|
|
24262
|
+
const formData = new FormData();
|
|
24263
|
+
const expiry = document.getElementById('jwtExpiresIn');
|
|
24264
|
+
const grace = document.getElementById('jwtRefreshGraceSeconds');
|
|
24265
|
+
if (expiry) formData.append('jwtExpiresIn', expiry.value);
|
|
24266
|
+
if (grace) formData.append('jwtRefreshGraceSeconds', grace.value);
|
|
24267
|
+
|
|
24268
|
+
const saveBtn = document.querySelector('button[onclick="saveSecuritySettings()"]');
|
|
24269
|
+
const originalText = saveBtn ? saveBtn.innerHTML : '';
|
|
24270
|
+
if (saveBtn) {
|
|
24271
|
+
saveBtn.innerHTML = '<svg class="animate-spin -ml-0.5 mr-1.5 h-5 w-5 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>Saving...';
|
|
24272
|
+
saveBtn.disabled = true;
|
|
24273
|
+
}
|
|
24274
|
+
|
|
24275
|
+
try {
|
|
24276
|
+
const response = await fetch('/admin/settings/security', {
|
|
24277
|
+
method: 'POST',
|
|
24278
|
+
body: formData
|
|
24279
|
+
});
|
|
24280
|
+
const result = await response.json();
|
|
24281
|
+
if (result.success) {
|
|
24282
|
+
showNotification(result.message || 'Security settings saved successfully!', 'success');
|
|
24283
|
+
} else {
|
|
24284
|
+
showNotification(result.error || 'Failed to save security settings', 'error');
|
|
24285
|
+
}
|
|
24286
|
+
} catch (error) {
|
|
24287
|
+
console.error('Error saving security settings:', error);
|
|
24288
|
+
showNotification('Failed to save security settings. Please try again.', 'error');
|
|
24289
|
+
} finally {
|
|
24290
|
+
if (saveBtn) {
|
|
24291
|
+
saveBtn.innerHTML = originalText;
|
|
24292
|
+
saveBtn.disabled = false;
|
|
24293
|
+
}
|
|
24294
|
+
}
|
|
24295
|
+
}
|
|
24296
|
+
window.saveSecuritySettings = saveSecuritySettings;
|
|
24297
|
+
|
|
24244
24298
|
// Migration functions
|
|
24245
24299
|
window.refreshMigrationStatus = async function() {
|
|
24246
24300
|
try {
|
|
@@ -24823,9 +24877,71 @@ function renderAppearanceSettings(settings) {
|
|
|
24823
24877
|
`;
|
|
24824
24878
|
}
|
|
24825
24879
|
function renderSecuritySettings(settings) {
|
|
24880
|
+
const jwtExpiresIn = settings?.jwtExpiresIn ?? "30d";
|
|
24881
|
+
const jwtRefreshGraceSeconds = typeof settings?.jwtRefreshGraceSeconds === "number" ? settings.jwtRefreshGraceSeconds : 60 * 60 * 24 * 7;
|
|
24826
24882
|
return `
|
|
24827
24883
|
<div class="space-y-6">
|
|
24828
|
-
<!--
|
|
24884
|
+
<!-- Session / JWT card (live) -->
|
|
24885
|
+
<div class="rounded-lg bg-white dark:bg-white/5 p-6 ring-1 ring-inset ring-zinc-950/5 dark:ring-white/10">
|
|
24886
|
+
<h3 class="text-lg/7 font-semibold text-zinc-950 dark:text-white">Session / JWT</h3>
|
|
24887
|
+
<p class="mt-1 text-sm/6 text-zinc-500 dark:text-zinc-400">
|
|
24888
|
+
Configure how long a signed-in session lasts and how long an expired token can still be refreshed.
|
|
24889
|
+
The <code class="text-xs">JWT_EXPIRES_IN</code> and <code class="text-xs">JWT_REFRESH_GRACE_SECONDS</code>
|
|
24890
|
+
environment variables, when set, override the values below.
|
|
24891
|
+
</p>
|
|
24892
|
+
|
|
24893
|
+
<div class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
24894
|
+
<div>
|
|
24895
|
+
<label for="jwtExpiresIn" class="block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2">
|
|
24896
|
+
JWT Expiration
|
|
24897
|
+
</label>
|
|
24898
|
+
<input
|
|
24899
|
+
type="text"
|
|
24900
|
+
id="jwtExpiresIn"
|
|
24901
|
+
name="jwtExpiresIn"
|
|
24902
|
+
value="${jwtExpiresIn}"
|
|
24903
|
+
placeholder="30d"
|
|
24904
|
+
class="w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm/6 text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400"
|
|
24905
|
+
/>
|
|
24906
|
+
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
|
24907
|
+
Accepts <code>30d</code>, <code>12h</code>, <code>3600s</code>, or bare seconds. Default: 30 days.
|
|
24908
|
+
</p>
|
|
24909
|
+
</div>
|
|
24910
|
+
|
|
24911
|
+
<div>
|
|
24912
|
+
<label for="jwtRefreshGraceSeconds" class="block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2">
|
|
24913
|
+
Refresh Grace Window (seconds)
|
|
24914
|
+
</label>
|
|
24915
|
+
<input
|
|
24916
|
+
type="number"
|
|
24917
|
+
id="jwtRefreshGraceSeconds"
|
|
24918
|
+
name="jwtRefreshGraceSeconds"
|
|
24919
|
+
value="${jwtRefreshGraceSeconds}"
|
|
24920
|
+
min="0"
|
|
24921
|
+
max="7776000"
|
|
24922
|
+
class="w-full rounded-lg bg-white dark:bg-white/5 px-3 py-2 text-sm/6 text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-400"
|
|
24923
|
+
/>
|
|
24924
|
+
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
|
24925
|
+
How long an expired token can still be exchanged at <code>/auth/refresh</code>. Default: 604800 (7 days).
|
|
24926
|
+
</p>
|
|
24927
|
+
</div>
|
|
24928
|
+
</div>
|
|
24929
|
+
|
|
24930
|
+
<div class="mt-6 pt-4 border-t border-zinc-950/5 dark:border-white/10 flex justify-end">
|
|
24931
|
+
<button
|
|
24932
|
+
type="button"
|
|
24933
|
+
onclick="saveSecuritySettings()"
|
|
24934
|
+
class="inline-flex items-center justify-center rounded-lg bg-zinc-950 dark:bg-white px-3.5 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors shadow-sm"
|
|
24935
|
+
>
|
|
24936
|
+
<svg class="-ml-0.5 mr-1.5 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
24937
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
24938
|
+
</svg>
|
|
24939
|
+
Save Session Settings
|
|
24940
|
+
</button>
|
|
24941
|
+
</div>
|
|
24942
|
+
</div>
|
|
24943
|
+
|
|
24944
|
+
<!-- WIP Notice for remaining fields -->
|
|
24829
24945
|
<div class="rounded-lg bg-blue-50 dark:bg-blue-950/20 p-6 ring-1 ring-inset ring-blue-600/20 dark:ring-blue-500/30">
|
|
24830
24946
|
<div class="flex items-start space-x-3">
|
|
24831
24947
|
<svg class="w-6 h-6 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
@@ -24834,7 +24950,7 @@ function renderSecuritySettings(settings) {
|
|
|
24834
24950
|
<div class="flex-1">
|
|
24835
24951
|
<h4 class="text-base/7 font-semibold text-blue-900 dark:text-blue-300">Work in Progress</h4>
|
|
24836
24952
|
<p class="mt-1 text-sm/6 text-blue-700 dark:text-blue-200">
|
|
24837
|
-
|
|
24953
|
+
The fields below are under development and provided for reference and design feedback only. Changes made here will not be saved.
|
|
24838
24954
|
</p>
|
|
24839
24955
|
</div>
|
|
24840
24956
|
</div>
|
|
@@ -25624,7 +25740,7 @@ function renderDatabaseToolsSettings(settings) {
|
|
|
25624
25740
|
|
|
25625
25741
|
// src/routes/admin-settings.ts
|
|
25626
25742
|
var adminSettingsRoutes = new hono.Hono();
|
|
25627
|
-
adminSettingsRoutes.use("*",
|
|
25743
|
+
adminSettingsRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
25628
25744
|
function getMockSettings(user) {
|
|
25629
25745
|
return {
|
|
25630
25746
|
general: {
|
|
@@ -25689,7 +25805,7 @@ adminSettingsRoutes.get("/", (c) => {
|
|
|
25689
25805
|
adminSettingsRoutes.get("/general", async (c) => {
|
|
25690
25806
|
const user = c.get("user");
|
|
25691
25807
|
const db = c.env.DB;
|
|
25692
|
-
const settingsService = new
|
|
25808
|
+
const settingsService = new chunkWAEQXGCX_cjs.SettingsService(db);
|
|
25693
25809
|
const generalSettings = await settingsService.getGeneralSettings(user?.email);
|
|
25694
25810
|
const mockSettings = getMockSettings(user);
|
|
25695
25811
|
mockSettings.general = generalSettings;
|
|
@@ -25719,15 +25835,24 @@ adminSettingsRoutes.get("/appearance", (c) => {
|
|
|
25719
25835
|
};
|
|
25720
25836
|
return c.html(renderSettingsPage(pageData));
|
|
25721
25837
|
});
|
|
25722
|
-
adminSettingsRoutes.get("/security", (c) => {
|
|
25838
|
+
adminSettingsRoutes.get("/security", async (c) => {
|
|
25723
25839
|
const user = c.get("user");
|
|
25840
|
+
const db = c.env.DB;
|
|
25841
|
+
const settingsService = new chunkWAEQXGCX_cjs.SettingsService(db);
|
|
25842
|
+
const persisted = await settingsService.getSecuritySettings();
|
|
25843
|
+
const mockSettings = getMockSettings(user);
|
|
25844
|
+
mockSettings.security = {
|
|
25845
|
+
...mockSettings.security,
|
|
25846
|
+
jwtExpiresIn: persisted.jwtExpiresIn,
|
|
25847
|
+
jwtRefreshGraceSeconds: persisted.jwtRefreshGraceSeconds
|
|
25848
|
+
};
|
|
25724
25849
|
const pageData = {
|
|
25725
25850
|
user: user ? {
|
|
25726
25851
|
name: user.email,
|
|
25727
25852
|
email: user.email,
|
|
25728
25853
|
role: user.role
|
|
25729
25854
|
} : void 0,
|
|
25730
|
-
settings:
|
|
25855
|
+
settings: mockSettings,
|
|
25731
25856
|
activeTab: "security",
|
|
25732
25857
|
version: c.get("appVersion")
|
|
25733
25858
|
};
|
|
@@ -25792,7 +25917,7 @@ adminSettingsRoutes.get("/database-tools", (c) => {
|
|
|
25792
25917
|
adminSettingsRoutes.get("/api/migrations/status", async (c) => {
|
|
25793
25918
|
try {
|
|
25794
25919
|
const db = c.env.DB;
|
|
25795
|
-
const migrationService = new
|
|
25920
|
+
const migrationService = new chunkI6444XLU_cjs.MigrationService(db);
|
|
25796
25921
|
const status = await migrationService.getMigrationStatus();
|
|
25797
25922
|
return c.json({
|
|
25798
25923
|
success: true,
|
|
@@ -25816,7 +25941,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
|
|
|
25816
25941
|
}, 403);
|
|
25817
25942
|
}
|
|
25818
25943
|
const db = c.env.DB;
|
|
25819
|
-
const migrationService = new
|
|
25944
|
+
const migrationService = new chunkI6444XLU_cjs.MigrationService(db);
|
|
25820
25945
|
const result = await migrationService.runPendingMigrations();
|
|
25821
25946
|
return c.json({
|
|
25822
25947
|
success: result.success,
|
|
@@ -25834,7 +25959,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
|
|
|
25834
25959
|
adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
|
|
25835
25960
|
try {
|
|
25836
25961
|
const db = c.env.DB;
|
|
25837
|
-
const migrationService = new
|
|
25962
|
+
const migrationService = new chunkI6444XLU_cjs.MigrationService(db);
|
|
25838
25963
|
const validation = await migrationService.validateSchema();
|
|
25839
25964
|
return c.json({
|
|
25840
25965
|
success: true,
|
|
@@ -26003,7 +26128,7 @@ adminSettingsRoutes.post("/general", async (c) => {
|
|
|
26003
26128
|
}
|
|
26004
26129
|
const formData = await c.req.formData();
|
|
26005
26130
|
const db = c.env.DB;
|
|
26006
|
-
const settingsService = new
|
|
26131
|
+
const settingsService = new chunkWAEQXGCX_cjs.SettingsService(db);
|
|
26007
26132
|
const settings = {
|
|
26008
26133
|
siteName: formData.get("siteName"),
|
|
26009
26134
|
siteDescription: formData.get("siteDescription"),
|
|
@@ -26038,6 +26163,55 @@ adminSettingsRoutes.post("/general", async (c) => {
|
|
|
26038
26163
|
}, 500);
|
|
26039
26164
|
}
|
|
26040
26165
|
});
|
|
26166
|
+
adminSettingsRoutes.post("/security", async (c) => {
|
|
26167
|
+
try {
|
|
26168
|
+
const user = c.get("user");
|
|
26169
|
+
if (!user || user.role !== "admin") {
|
|
26170
|
+
return c.json({
|
|
26171
|
+
success: false,
|
|
26172
|
+
error: "Unauthorized. Admin access required."
|
|
26173
|
+
}, 403);
|
|
26174
|
+
}
|
|
26175
|
+
const formData = await c.req.formData();
|
|
26176
|
+
const db = c.env.DB;
|
|
26177
|
+
const settingsService = new chunkWAEQXGCX_cjs.SettingsService(db);
|
|
26178
|
+
const jwtExpiresInRaw = formData.get("jwtExpiresIn")?.trim() || "";
|
|
26179
|
+
const graceRaw = formData.get("jwtRefreshGraceSeconds")?.trim() || "";
|
|
26180
|
+
if (!/^\d+(?:s|m|h|d)?$/i.test(jwtExpiresInRaw)) {
|
|
26181
|
+
return c.json({
|
|
26182
|
+
success: false,
|
|
26183
|
+
error: "JWT expiration must be a number optionally suffixed with s/m/h/d (e.g. 30d, 12h, 3600)."
|
|
26184
|
+
}, 400);
|
|
26185
|
+
}
|
|
26186
|
+
const graceSeconds = Number.parseInt(graceRaw, 10);
|
|
26187
|
+
if (!Number.isFinite(graceSeconds) || graceSeconds < 0 || graceSeconds > 60 * 60 * 24 * 90) {
|
|
26188
|
+
return c.json({
|
|
26189
|
+
success: false,
|
|
26190
|
+
error: "Refresh grace must be an integer between 0 and 7776000 seconds (90 days)."
|
|
26191
|
+
}, 400);
|
|
26192
|
+
}
|
|
26193
|
+
const success = await settingsService.saveSecuritySettings({
|
|
26194
|
+
jwtExpiresIn: jwtExpiresInRaw,
|
|
26195
|
+
jwtRefreshGraceSeconds: graceSeconds
|
|
26196
|
+
});
|
|
26197
|
+
if (success) {
|
|
26198
|
+
return c.json({
|
|
26199
|
+
success: true,
|
|
26200
|
+
message: "Security settings saved successfully!"
|
|
26201
|
+
});
|
|
26202
|
+
}
|
|
26203
|
+
return c.json({
|
|
26204
|
+
success: false,
|
|
26205
|
+
error: "Failed to save settings"
|
|
26206
|
+
}, 500);
|
|
26207
|
+
} catch (error) {
|
|
26208
|
+
console.error("Error saving security settings:", error);
|
|
26209
|
+
return c.json({
|
|
26210
|
+
success: false,
|
|
26211
|
+
error: "Failed to save settings. Please try again."
|
|
26212
|
+
}, 500);
|
|
26213
|
+
}
|
|
26214
|
+
});
|
|
26041
26215
|
adminSettingsRoutes.post("/", async (c) => {
|
|
26042
26216
|
return c.redirect("/admin/settings/general");
|
|
26043
26217
|
});
|
|
@@ -27724,7 +27898,7 @@ function renderFormCreatePage(data) {
|
|
|
27724
27898
|
|
|
27725
27899
|
// src/routes/admin-forms.ts
|
|
27726
27900
|
var adminFormsRoutes = new hono.Hono();
|
|
27727
|
-
adminFormsRoutes.use("*",
|
|
27901
|
+
adminFormsRoutes.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
27728
27902
|
adminFormsRoutes.get("/", async (c) => {
|
|
27729
27903
|
try {
|
|
27730
27904
|
const user = c.get("user");
|
|
@@ -28529,7 +28703,7 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
|
|
|
28529
28703
|
`).bind(now, form.id).run();
|
|
28530
28704
|
let contentId = null;
|
|
28531
28705
|
try {
|
|
28532
|
-
contentId = await
|
|
28706
|
+
contentId = await chunk47HKH3D6_cjs.createContentFromSubmission(
|
|
28533
28707
|
db,
|
|
28534
28708
|
sanitizedData,
|
|
28535
28709
|
{ id: form.id, name: form.name, display_name: form.display_name },
|
|
@@ -28703,7 +28877,7 @@ function renderAPIReferencePage(data) {
|
|
|
28703
28877
|
>
|
|
28704
28878
|
<option value="">All Categories</option>
|
|
28705
28879
|
${categories.map((category) => {
|
|
28706
|
-
const info =
|
|
28880
|
+
const info = chunkWAEQXGCX_cjs.CATEGORY_INFO[category];
|
|
28707
28881
|
const title = info ? info.title : category;
|
|
28708
28882
|
return `<option value="${category}">${title}</option>`;
|
|
28709
28883
|
}).join("\n ")}
|
|
@@ -28720,7 +28894,7 @@ function renderAPIReferencePage(data) {
|
|
|
28720
28894
|
<!-- API Categories -->
|
|
28721
28895
|
<div class="space-y-6">
|
|
28722
28896
|
${Object.entries(endpointsByCategory).map(([category, endpoints]) => {
|
|
28723
|
-
const info =
|
|
28897
|
+
const info = chunkWAEQXGCX_cjs.CATEGORY_INFO[category] || { title: category, description: "", icon: "📋" };
|
|
28724
28898
|
return `
|
|
28725
28899
|
<div class="api-category" data-category="${category}">
|
|
28726
28900
|
<div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden">
|
|
@@ -28897,14 +29071,14 @@ function renderAPIReferencePage(data) {
|
|
|
28897
29071
|
}
|
|
28898
29072
|
|
|
28899
29073
|
// src/routes/admin-api-reference.ts
|
|
28900
|
-
var VERSION2 =
|
|
29074
|
+
var VERSION2 = chunk5EBTBD2Z_cjs.getCoreVersion();
|
|
28901
29075
|
var router2 = new hono.Hono();
|
|
28902
|
-
router2.use("*",
|
|
29076
|
+
router2.use("*", chunk3TVMUQWG_cjs.requireAuth());
|
|
28903
29077
|
router2.get("/", async (c) => {
|
|
28904
29078
|
const user = c.get("user");
|
|
28905
29079
|
try {
|
|
28906
|
-
const app2 =
|
|
28907
|
-
const endpoints =
|
|
29080
|
+
const app2 = chunkWAEQXGCX_cjs.getAppInstance();
|
|
29081
|
+
const endpoints = chunkWAEQXGCX_cjs.buildRouteList(app2);
|
|
28908
29082
|
const pageData = {
|
|
28909
29083
|
endpoints,
|
|
28910
29084
|
user: user ? {
|
|
@@ -28990,5 +29164,5 @@ exports.router2 = router2;
|
|
|
28990
29164
|
exports.test_cleanup_default = test_cleanup_default;
|
|
28991
29165
|
exports.userProfilesPlugin = userProfilesPlugin;
|
|
28992
29166
|
exports.userRoutes = userRoutes;
|
|
28993
|
-
//# sourceMappingURL=chunk-
|
|
28994
|
-
//# sourceMappingURL=chunk-
|
|
29167
|
+
//# sourceMappingURL=chunk-5ITJB5ZT.cjs.map
|
|
29168
|
+
//# sourceMappingURL=chunk-5ITJB5ZT.cjs.map
|