@sonicjs-cms/core 3.0.0-beta.2 → 3.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -49
- package/dist/admin-documents-form.template-DDSH6ROU.js +6 -0
- package/dist/{admin-documents-form.template-NLSI6Z42.js.map → admin-documents-form.template-DDSH6ROU.js.map} +1 -1
- package/dist/admin-documents-form.template-LSZKGA5J.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-WHJGSWWD.js.map → admin-documents-form.template-LSZKGA5J.cjs.map} +1 -1
- package/dist/{filter-bar.template-DlVYMk-T.d.ts → admin-layout-catalyst.template-DrwDUfsE.d.cts} +25 -1
- package/dist/{filter-bar.template-DlVYMk-T.d.cts → admin-layout-catalyst.template-DrwDUfsE.d.ts} +25 -1
- package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +21 -0
- package/dist/{admin-layout-catalyst.template-ZK5HD545.cjs.map → admin-layout-catalyst.template-KDHKVLXR.cjs.map} +1 -1
- package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +7 -0
- package/dist/{admin-documents-form.template-KN7JF66Q.cjs.map → admin-layout-catalyst.template-YQ4EMF2J.js.map} +1 -1
- package/dist/{app-Bo0X1OWX.d.ts → app-01M0dIwt.d.ts} +1 -1
- package/dist/{app-Do66yCcV.d.cts → app-aj39TGHB.d.cts} +1 -1
- package/dist/{chunk-ZEZ245PW.js → chunk-2XAQTPAE.js} +4 -236
- package/dist/chunk-2XAQTPAE.js.map +1 -0
- package/dist/{chunk-BDDABDAB.cjs → chunk-36Z3AKX3.cjs} +3 -239
- package/dist/chunk-36Z3AKX3.cjs.map +1 -0
- package/dist/{chunk-VXE42MYF.cjs → chunk-3E7IROND.cjs} +695 -428
- package/dist/chunk-3E7IROND.cjs.map +1 -0
- package/dist/{chunk-BLMTL57B.js → chunk-3TMTYJAJ.js} +26 -4
- package/dist/chunk-3TMTYJAJ.js.map +1 -0
- package/dist/{chunk-AAWNRBRB.cjs → chunk-4SHNHNRP.cjs} +95 -20
- package/dist/chunk-4SHNHNRP.cjs.map +1 -0
- package/dist/{chunk-QAYFOER6.cjs → chunk-5ARIHAGN.cjs} +285 -3
- package/dist/chunk-5ARIHAGN.cjs.map +1 -0
- package/dist/{chunk-XW56B23A.cjs → chunk-5RSB5SEK.cjs} +4 -4
- package/dist/{chunk-XW56B23A.cjs.map → chunk-5RSB5SEK.cjs.map} +1 -1
- package/dist/{chunk-VD2EA3WT.js → chunk-5UCMLBRQ.js} +328 -62
- package/dist/chunk-5UCMLBRQ.js.map +1 -0
- package/dist/{chunk-3TB6AT6X.js → chunk-5V62WT6M.js} +35 -4
- package/dist/chunk-5V62WT6M.js.map +1 -0
- package/dist/{chunk-LRZIAW7U.cjs → chunk-AQJEMVAY.cjs} +3 -3
- package/dist/chunk-AQJEMVAY.cjs.map +1 -0
- package/dist/{chunk-WULONYGB.cjs → chunk-CRGUD4KC.cjs} +9 -9
- package/dist/{chunk-WULONYGB.cjs.map → chunk-CRGUD4KC.cjs.map} +1 -1
- package/dist/{chunk-NLJVSER2.js → chunk-DSXEVMOM.js} +3 -2
- package/dist/chunk-DSXEVMOM.js.map +1 -0
- package/dist/{chunk-H2AXVCLS.cjs → chunk-DTGCXWWM.cjs} +141 -74
- package/dist/chunk-DTGCXWWM.cjs.map +1 -0
- package/dist/{chunk-NUKJ54GA.cjs → chunk-GMMCCIQO.cjs} +6 -6
- package/dist/{chunk-NUKJ54GA.cjs.map → chunk-GMMCCIQO.cjs.map} +1 -1
- package/dist/{chunk-6OUHGKFD.js → chunk-GMZ5TGYP.js} +3 -3
- package/dist/{chunk-6OUHGKFD.js.map → chunk-GMZ5TGYP.js.map} +1 -1
- package/dist/{chunk-6JQOUUOB.js → chunk-JQISFW6U.js} +3 -3
- package/dist/{chunk-6JQOUUOB.js.map → chunk-JQISFW6U.js.map} +1 -1
- package/dist/{chunk-NAVPFIG5.cjs → chunk-K623Q6WD.cjs} +35 -3
- package/dist/chunk-K623Q6WD.cjs.map +1 -0
- package/dist/{chunk-JEQ7FLOD.cjs → chunk-KIGVVO6N.cjs} +16 -10
- package/dist/chunk-KIGVVO6N.cjs.map +1 -0
- package/dist/{chunk-2CB4KY7I.cjs → chunk-LTZ5WYOK.cjs} +29 -7
- package/dist/chunk-LTZ5WYOK.cjs.map +1 -0
- package/dist/{chunk-YHSQVQXX.js → chunk-MYQ7KZUQ.js} +135 -68
- package/dist/chunk-MYQ7KZUQ.js.map +1 -0
- package/dist/{chunk-DNQCEKUK.cjs → chunk-N32OWET6.cjs} +5 -5
- package/dist/{chunk-DNQCEKUK.cjs.map → chunk-N32OWET6.cjs.map} +1 -1
- package/dist/{chunk-HDWE5FRJ.js → chunk-OBA2RYZN.js} +3 -3
- package/dist/{chunk-HDWE5FRJ.js.map → chunk-OBA2RYZN.js.map} +1 -1
- package/dist/{chunk-MVIZJOO5.cjs → chunk-PXNTCCPE.cjs} +8 -8
- package/dist/{chunk-MVIZJOO5.cjs.map → chunk-PXNTCCPE.cjs.map} +1 -1
- package/dist/{chunk-ZGGXCFR6.js → chunk-RDH6PUOP.js} +282 -4
- package/dist/chunk-RDH6PUOP.js.map +1 -0
- package/dist/{chunk-EF2NQUIQ.js → chunk-RMRJGMDE.js} +3 -3
- package/dist/{chunk-EF2NQUIQ.js.map → chunk-RMRJGMDE.js.map} +1 -1
- package/dist/{chunk-IVPRUGTY.js → chunk-SOZUG52O.js} +4 -4
- package/dist/{chunk-IVPRUGTY.js.map → chunk-SOZUG52O.js.map} +1 -1
- package/dist/{chunk-DSA4UX5B.cjs → chunk-TQG5FNNR.cjs} +3 -2
- package/dist/chunk-TQG5FNNR.cjs.map +1 -0
- package/dist/{chunk-GCDZZNIN.js → chunk-UWUP2VMT.js} +16 -10
- package/dist/chunk-UWUP2VMT.js.map +1 -0
- package/dist/{chunk-IESEVHXL.js → chunk-VVYVFCML.js} +12 -3
- package/dist/chunk-VVYVFCML.js.map +1 -0
- package/dist/{chunk-NMPEMSU4.js → chunk-W53J3BJ2.js} +3 -3
- package/dist/chunk-W53J3BJ2.js.map +1 -0
- package/dist/{chunk-RZ6H7OZK.js → chunk-WCA4VENG.js} +87 -12
- package/dist/chunk-WCA4VENG.js.map +1 -0
- package/dist/{chunk-HIKBY7MS.cjs → chunk-XWVDSM2L.cjs} +12 -3
- package/dist/chunk-XWVDSM2L.cjs.map +1 -0
- package/dist/{collection-config-JgHOpFCG.d.ts → collection-config-BTzAvKt2.d.cts} +25 -0
- package/dist/{collection-config-JgHOpFCG.d.cts → collection-config-BTzAvKt2.d.ts} +25 -0
- package/dist/config-6FB2BXMP.js +6 -0
- package/dist/{config-HFXANXCC.js.map → config-6FB2BXMP.js.map} +1 -1
- package/dist/config-OCH7S4WK.cjs +19 -0
- package/dist/{config-ON6FNMYX.cjs.map → config-OCH7S4WK.cjs.map} +1 -1
- package/dist/{define-plugin-BzNHc1ZI.d.ts → define-plugin-BYIey6sp.d.ts} +1 -1
- package/dist/{define-plugin-IWDKYaVm.d.cts → define-plugin-DsKiGu1q.d.cts} +1 -1
- package/dist/document-projection-4HG75S5S.js +4 -0
- package/dist/{document-projection-YYMC6I4U.js.map → document-projection-4HG75S5S.js.map} +1 -1
- package/dist/document-projection-JQHSTSFD.cjs +13 -0
- package/dist/{document-projection-TDWRJX3Z.cjs.map → document-projection-JQHSTSFD.cjs.map} +1 -1
- package/dist/index.cjs +928 -378
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +200 -12
- package/dist/index.d.ts +200 -12
- package/dist/index.js +612 -75
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +37 -34
- package/dist/middleware.d.cts +2 -2
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.js +8 -5
- package/dist/migrations-HZJ6U6SX.js +4 -0
- package/dist/{migrations-WCAVBD7C.js.map → migrations-HZJ6U6SX.js.map} +1 -1
- package/dist/migrations-VQAFXMU7.cjs +13 -0
- package/dist/{migrations-NJJWQUKK.cjs.map → migrations-VQAFXMU7.cjs.map} +1 -1
- package/dist/{plugin-bootstrap-B8ThJU21.d.cts → plugin-bootstrap-BHWQ2df8.d.cts} +1 -1
- package/dist/{plugin-bootstrap-qu8hJgUt.d.ts → plugin-bootstrap-Bj4fxX1q.d.ts} +1 -1
- package/dist/plugins.cjs +40 -40
- package/dist/plugins.d.cts +2 -2
- package/dist/plugins.d.ts +2 -2
- package/dist/plugins.js +3 -3
- package/dist/rbac-7QZ4JZ2E.cjs +14 -0
- package/dist/{rbac-VONLJJKB.cjs.map → rbac-7QZ4JZ2E.cjs.map} +1 -1
- package/dist/rbac-Y43IEQOP.js +5 -0
- package/dist/{rbac-O73MFKDA.js.map → rbac-Y43IEQOP.js.map} +1 -1
- package/dist/routes.cjs +34 -34
- package/dist/routes.d.cts +2 -2
- package/dist/routes.d.ts +2 -2
- package/dist/routes.js +14 -14
- package/dist/services.cjs +42 -42
- package/dist/services.d.cts +16 -3
- package/dist/services.d.ts +16 -3
- package/dist/services.js +3 -3
- package/dist/{telemetry-B9vIV4wh.d.cts → telemetry-Cku1ax74.d.cts} +1 -1
- package/dist/{telemetry-B9vIV4wh.d.ts → telemetry-Cku1ax74.d.ts} +1 -1
- package/dist/templates.cjs +17 -17
- package/dist/templates.d.cts +2 -24
- package/dist/templates.d.ts +2 -24
- package/dist/templates.js +3 -3
- package/dist/{types-Dea1eNxU.d.ts → types-DT7XN5TX.d.cts} +1 -1
- package/dist/{types-Dea1eNxU.d.cts → types-DT7XN5TX.d.ts} +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.ts +2 -2
- package/dist/utils.cjs +8 -8
- package/dist/utils.d.cts +2 -2
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +2 -2
- package/package.json +1 -1
- package/dist/admin-documents-form.template-KN7JF66Q.cjs +0 -19
- package/dist/admin-documents-form.template-NLSI6Z42.js +0 -6
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js +0 -7
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs +0 -17
- package/dist/chunk-2CB4KY7I.cjs.map +0 -1
- package/dist/chunk-3TB6AT6X.js.map +0 -1
- package/dist/chunk-AAWNRBRB.cjs.map +0 -1
- package/dist/chunk-BDDABDAB.cjs.map +0 -1
- package/dist/chunk-BLMTL57B.js.map +0 -1
- package/dist/chunk-DSA4UX5B.cjs.map +0 -1
- package/dist/chunk-GCDZZNIN.js.map +0 -1
- package/dist/chunk-H2AXVCLS.cjs.map +0 -1
- package/dist/chunk-HIKBY7MS.cjs.map +0 -1
- package/dist/chunk-IESEVHXL.js.map +0 -1
- package/dist/chunk-JEQ7FLOD.cjs.map +0 -1
- package/dist/chunk-LRZIAW7U.cjs.map +0 -1
- package/dist/chunk-NAVPFIG5.cjs.map +0 -1
- package/dist/chunk-NLJVSER2.js.map +0 -1
- package/dist/chunk-NMPEMSU4.js.map +0 -1
- package/dist/chunk-QAYFOER6.cjs.map +0 -1
- package/dist/chunk-RZ6H7OZK.js.map +0 -1
- package/dist/chunk-VD2EA3WT.js.map +0 -1
- package/dist/chunk-VXE42MYF.cjs.map +0 -1
- package/dist/chunk-YHSQVQXX.js.map +0 -1
- package/dist/chunk-ZEZ245PW.js.map +0 -1
- package/dist/chunk-ZGGXCFR6.js.map +0 -1
- package/dist/config-HFXANXCC.js +0 -6
- package/dist/config-ON6FNMYX.cjs +0 -19
- package/dist/document-projection-TDWRJX3Z.cjs +0 -13
- package/dist/document-projection-YYMC6I4U.js +0 -4
- package/dist/migrations-NJJWQUKK.cjs +0 -13
- package/dist/migrations-WCAVBD7C.js +0 -4
- package/dist/rbac-O73MFKDA.js +0 -5
- package/dist/rbac-VONLJJKB.cjs +0 -14
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
3
|
+
var chunkXWVDSM2L_cjs = require('./chunk-XWVDSM2L.cjs');
|
|
4
|
+
var chunkN32OWET6_cjs = require('./chunk-N32OWET6.cjs');
|
|
5
|
+
var chunk36Z3AKX3_cjs = require('./chunk-36Z3AKX3.cjs');
|
|
6
|
+
var chunk4SHNHNRP_cjs = require('./chunk-4SHNHNRP.cjs');
|
|
7
|
+
var chunkLTZ5WYOK_cjs = require('./chunk-LTZ5WYOK.cjs');
|
|
8
|
+
var chunkKIGVVO6N_cjs = require('./chunk-KIGVVO6N.cjs');
|
|
9
|
+
var chunk5ARIHAGN_cjs = require('./chunk-5ARIHAGN.cjs');
|
|
10
|
+
var chunkTQG5FNNR_cjs = require('./chunk-TQG5FNNR.cjs');
|
|
11
|
+
var chunkPXNTCCPE_cjs = require('./chunk-PXNTCCPE.cjs');
|
|
12
|
+
var chunkK623Q6WD_cjs = require('./chunk-K623Q6WD.cjs');
|
|
13
|
+
var chunk5RSB5SEK_cjs = require('./chunk-5RSB5SEK.cjs');
|
|
14
14
|
var chunkJ6JTWD2A_cjs = require('./chunk-J6JTWD2A.cjs');
|
|
15
15
|
var chunkIXUHXTHW_cjs = require('./chunk-IXUHXTHW.cjs');
|
|
16
16
|
var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
|
|
17
|
-
var
|
|
17
|
+
var chunkAQJEMVAY_cjs = require('./chunk-AQJEMVAY.cjs');
|
|
18
18
|
var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
|
|
19
19
|
var hono = require('hono');
|
|
20
20
|
var zod = require('zod');
|
|
21
|
-
var cors = require('hono/cors');
|
|
22
21
|
var cookie = require('hono/cookie');
|
|
23
22
|
var html = require('hono/html');
|
|
24
23
|
|
|
@@ -27,6 +26,7 @@ var DocumentPermissionsService = class {
|
|
|
27
26
|
constructor(db) {
|
|
28
27
|
this.db = db;
|
|
29
28
|
}
|
|
29
|
+
db;
|
|
30
30
|
// Deny wins. Overrides beat base grants. Empty ACL falls back to base grants.
|
|
31
31
|
async isAllowed(principalSet, rootId, permission, typeSettings, tenantId) {
|
|
32
32
|
const overrides = await this.getDocumentPermissions(rootId, principalSet, permission, tenantId);
|
|
@@ -74,7 +74,7 @@ var DocumentPermissionsService = class {
|
|
|
74
74
|
async grantPermission(opts) {
|
|
75
75
|
const { tenantId, rootId, principalType, principalId, permission, effect = "allow", createdBy } = opts;
|
|
76
76
|
const now = Math.floor(Date.now() / 1e3);
|
|
77
|
-
const id =
|
|
77
|
+
const id = chunkKIGVVO6N_cjs.nanoid();
|
|
78
78
|
await this.db.prepare(
|
|
79
79
|
`INSERT INTO document_permissions (id, tenant_id, root_id, principal_type, principal_id, permission, effect, inherited, created_at, created_by)
|
|
80
80
|
VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?)
|
|
@@ -135,6 +135,8 @@ var DocumentRepository = class {
|
|
|
135
135
|
this.tenantId = tenantId;
|
|
136
136
|
this.permissions = new DocumentPermissionsService(db);
|
|
137
137
|
}
|
|
138
|
+
db;
|
|
139
|
+
tenantId;
|
|
138
140
|
permissions;
|
|
139
141
|
// ─── Reads ───────────────────────────────────────────────────────────────
|
|
140
142
|
async getById(id) {
|
|
@@ -257,7 +259,7 @@ function getDocumentRequestContext(c) {
|
|
|
257
259
|
|
|
258
260
|
// src/routes/api-documents.ts
|
|
259
261
|
async function aclAllowsRead(db, tenantId, principalSet, row, preloadedType) {
|
|
260
|
-
const docType = preloadedType ?? await new
|
|
262
|
+
const docType = preloadedType ?? await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
261
263
|
if (!docType) return false;
|
|
262
264
|
return new DocumentRepository(db, tenantId).isAllowed(principalSet, row.root_id, "read", docType.settings);
|
|
263
265
|
}
|
|
@@ -275,7 +277,7 @@ apiDocumentsRoutes.get("/", async (c) => {
|
|
|
275
277
|
if (!typeId) {
|
|
276
278
|
return c.json({ error: "type query parameter is required" }, 400);
|
|
277
279
|
}
|
|
278
|
-
const registry = new
|
|
280
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
279
281
|
const docType = await registry.findById(typeId);
|
|
280
282
|
if (!docType || !docType.isActive) {
|
|
281
283
|
return c.json({ error: "Unknown document type" }, 400);
|
|
@@ -357,7 +359,7 @@ apiDocumentsRoutes.get("/root/:rootId", async (c) => {
|
|
|
357
359
|
AND (expires_at IS NULL OR expires_at > ?) LIMIT 1`
|
|
358
360
|
).bind(rootId, now, now).first();
|
|
359
361
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
360
|
-
const docType = await new
|
|
362
|
+
const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
361
363
|
const effTenant = effectiveTenantForType(tenantId, docType?.settings);
|
|
362
364
|
if (row.tenant_id !== effTenant) return c.json({ error: "Not found" }, 404);
|
|
363
365
|
if (!await aclAllowsRead(db, effTenant, principalSet, row, docType)) {
|
|
@@ -393,7 +395,7 @@ apiDocumentsRoutes.get("/:id", async (c) => {
|
|
|
393
395
|
AND (expires_at IS NULL OR expires_at > ?) LIMIT 1`
|
|
394
396
|
).bind(id, now, now).first();
|
|
395
397
|
if (!row) return c.json({ error: "Not found" }, 404);
|
|
396
|
-
const docType = await new
|
|
398
|
+
const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
397
399
|
const effTenant = effectiveTenantForType(tenantId, docType?.settings);
|
|
398
400
|
if (row.tenant_id !== effTenant) return c.json({ error: "Not found" }, 404);
|
|
399
401
|
if (!await aclAllowsRead(db, effTenant, principalSet, row, docType)) {
|
|
@@ -463,17 +465,17 @@ async function resolveDocScope(c, db, by, opts = {}) {
|
|
|
463
465
|
const draft = opts.currentDraftOnly ? " AND is_current_draft = 1" : "";
|
|
464
466
|
const row = await db.prepare(`SELECT type_id, root_id, tenant_id FROM documents WHERE ${col} = ?${draft} LIMIT 1`).bind(val).first();
|
|
465
467
|
if (!row) return null;
|
|
466
|
-
const docType = await new
|
|
468
|
+
const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(row.type_id);
|
|
467
469
|
const tenantId = effectiveTenantForType(getRequestTenant(c), docType?.settings);
|
|
468
470
|
if (row.tenant_id !== tenantId) return null;
|
|
469
471
|
return { typeId: row.type_id, rootId: row.root_id, tenantId, docType };
|
|
470
472
|
}
|
|
471
473
|
var adminDocumentsRoutes = new hono.Hono();
|
|
472
|
-
adminDocumentsRoutes.use("*",
|
|
473
|
-
adminDocumentsRoutes.use("*",
|
|
474
|
+
adminDocumentsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
475
|
+
adminDocumentsRoutes.use("*", chunk4SHNHNRP_cjs.requireRole(["admin", "editor"]));
|
|
474
476
|
adminDocumentsRoutes.get("/types", async (c) => {
|
|
475
477
|
try {
|
|
476
|
-
const registry = new
|
|
478
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(c.env.DB);
|
|
477
479
|
const types = await registry.findAll();
|
|
478
480
|
return c.json({ data: types });
|
|
479
481
|
} catch (error) {
|
|
@@ -501,7 +503,7 @@ adminDocumentsRoutes.get("/", async (c) => {
|
|
|
501
503
|
if (!typeId) {
|
|
502
504
|
return c.json({ error: "type query parameter is required" }, 400);
|
|
503
505
|
}
|
|
504
|
-
const registry = new
|
|
506
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
505
507
|
const docType = await registry.findById(typeId);
|
|
506
508
|
if (!docType || !docType.isActive) {
|
|
507
509
|
return c.json({ error: "Unknown document type" }, 400);
|
|
@@ -612,7 +614,7 @@ adminDocumentsRoutes.post("/", async (c) => {
|
|
|
612
614
|
const input = validation.data;
|
|
613
615
|
const db = c.env.DB;
|
|
614
616
|
const user = c.get("user");
|
|
615
|
-
const registry = new
|
|
617
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
616
618
|
const docType = await registry.findById(input.typeId);
|
|
617
619
|
if (!docType || !docType.isActive) {
|
|
618
620
|
return c.json({ error: "Unknown document type" }, 400);
|
|
@@ -620,7 +622,7 @@ adminDocumentsRoutes.post("/", async (c) => {
|
|
|
620
622
|
const createDenied = await denyIfNotAllowed(c, db, "", "create", docType.settings);
|
|
621
623
|
if (createDenied) return createDenied;
|
|
622
624
|
const tenantId = effectiveTenantForType(getRequestTenant(c), docType.settings);
|
|
623
|
-
const svc = new
|
|
625
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
624
626
|
queryableFields: docType.queryableFields,
|
|
625
627
|
typeSchemaVersion: docType.schemaVersion,
|
|
626
628
|
maxVersionsPerRoot: docType.settings.maxVersionsPerRoot,
|
|
@@ -658,7 +660,7 @@ adminDocumentsRoutes.put("/:rootId", async (c) => {
|
|
|
658
660
|
const docType = scope.docType;
|
|
659
661
|
const updateDenied = await denyIfNotAllowed(c, db, rootId, "update", docType?.settings, scope.tenantId);
|
|
660
662
|
if (updateDenied) return updateDenied;
|
|
661
|
-
const svc = new
|
|
663
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
662
664
|
queryableFields: docType?.queryableFields ?? [],
|
|
663
665
|
typeSchemaVersion: docType?.schemaVersion,
|
|
664
666
|
maxVersionsPerRoot: docType?.settings.maxVersionsPerRoot,
|
|
@@ -683,7 +685,7 @@ adminDocumentsRoutes.post("/:id/publish", async (c) => {
|
|
|
683
685
|
const docType = scope.docType;
|
|
684
686
|
const publishDenied = await denyIfNotAllowed(c, db, scope.rootId, "publish", docType?.settings, scope.tenantId);
|
|
685
687
|
if (publishDenied) return publishDenied;
|
|
686
|
-
const svc = new
|
|
688
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
687
689
|
queryableFields: docType?.queryableFields ?? [],
|
|
688
690
|
typeSchemaVersion: docType?.schemaVersion,
|
|
689
691
|
tenantId: scope.tenantId,
|
|
@@ -706,7 +708,7 @@ adminDocumentsRoutes.post("/:id/unpublish", async (c) => {
|
|
|
706
708
|
const docType = scope.docType;
|
|
707
709
|
const unpublishDenied = await denyIfNotAllowed(c, db, scope.rootId, "publish", docType?.settings, scope.tenantId);
|
|
708
710
|
if (unpublishDenied) return unpublishDenied;
|
|
709
|
-
const svc = new
|
|
711
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
710
712
|
queryableFields: docType?.queryableFields ?? [],
|
|
711
713
|
tenantId: scope.tenantId
|
|
712
714
|
});
|
|
@@ -728,7 +730,7 @@ adminDocumentsRoutes.delete("/:id", async (c) => {
|
|
|
728
730
|
const docType = scope.docType;
|
|
729
731
|
const deleteDenied = await denyIfNotAllowed(c, db, scope.rootId, "delete", docType?.settings, scope.tenantId);
|
|
730
732
|
if (deleteDenied) return deleteDenied;
|
|
731
|
-
const svc = new
|
|
733
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, { queryableFields: docType?.queryableFields ?? [], tenantId: scope.tenantId });
|
|
732
734
|
if (docType?.settings.pii) {
|
|
733
735
|
if (scope.rootId) await svc.erase(scope.rootId, scope.tenantId);
|
|
734
736
|
} else {
|
|
@@ -744,13 +746,13 @@ adminDocumentsRoutes.post("/types/:typeId/reindex", async (c) => {
|
|
|
744
746
|
try {
|
|
745
747
|
const { typeId } = c.req.param();
|
|
746
748
|
const db = c.env.DB;
|
|
747
|
-
const registry = new
|
|
749
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
748
750
|
const docType = await registry.findById(typeId);
|
|
749
751
|
if (!docType) return c.json({ error: "Unknown document type" }, 400);
|
|
750
752
|
const reindexTenant = effectiveTenantForType(getRequestTenant(c), docType.settings);
|
|
751
753
|
const reindexDenied = await denyIfNotAllowed(c, db, "", "manage", docType.settings, reindexTenant);
|
|
752
754
|
if (reindexDenied) return reindexDenied;
|
|
753
|
-
const { DocumentProjection } = await import('./document-projection-
|
|
755
|
+
const { DocumentProjection } = await import('./document-projection-JQHSTSFD.cjs');
|
|
754
756
|
const projection = new DocumentProjection(db);
|
|
755
757
|
const rebuilt = await projection.reindexType(typeId, reindexTenant, docType.queryableFields);
|
|
756
758
|
return c.json({ rebuilt });
|
|
@@ -898,13 +900,13 @@ async function resolveContentVariables(contentData, db) {
|
|
|
898
900
|
// src/routes/api-content-crud.ts
|
|
899
901
|
var apiContentCrudRoutes = new hono.Hono();
|
|
900
902
|
async function resolveDocBacking(db, collectionIdOrName) {
|
|
901
|
-
const registry =
|
|
903
|
+
const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
|
|
902
904
|
const record = registry.getBySlugOrName(collectionIdOrName) ?? registry.getById(collectionIdOrName);
|
|
903
905
|
if (record) {
|
|
904
|
-
const docType2 = await new
|
|
906
|
+
const docType2 = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(record.name);
|
|
905
907
|
return docType2 ? { coll: { id: record.id, name: record.name }, docType: docType2 } : null;
|
|
906
908
|
}
|
|
907
|
-
const docType = await new
|
|
909
|
+
const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(collectionIdOrName);
|
|
908
910
|
if (docType) {
|
|
909
911
|
return { coll: { id: collectionIdOrName, name: collectionIdOrName }, docType };
|
|
910
912
|
}
|
|
@@ -947,7 +949,7 @@ apiContentCrudRoutes.get("/check-slug", async (c) => {
|
|
|
947
949
|
}, 500);
|
|
948
950
|
}
|
|
949
951
|
});
|
|
950
|
-
apiContentCrudRoutes.get("/:id",
|
|
952
|
+
apiContentCrudRoutes.get("/:id", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
|
|
951
953
|
try {
|
|
952
954
|
const id = c.req.param("id");
|
|
953
955
|
const db = c.env.DB;
|
|
@@ -957,7 +959,7 @@ apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
|
|
|
957
959
|
).bind(id, getRequestTenant(c)).first();
|
|
958
960
|
let transformedContent;
|
|
959
961
|
if (docRow) {
|
|
960
|
-
const coll =
|
|
962
|
+
const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
961
963
|
transformedContent = {
|
|
962
964
|
id: docRow.root_id,
|
|
963
965
|
title: docRow.title,
|
|
@@ -966,8 +968,8 @@ apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
|
|
|
966
968
|
collectionId: coll?.id ?? docRow.type_id,
|
|
967
969
|
data: docRow.data ? JSON.parse(docRow.data) : {},
|
|
968
970
|
// D29: document timestamps are SECONDS; legacy `content` API contract is MILLISECONDS.
|
|
969
|
-
created_at:
|
|
970
|
-
updated_at:
|
|
971
|
+
created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.created_at),
|
|
972
|
+
updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.updated_at)
|
|
971
973
|
};
|
|
972
974
|
} else {
|
|
973
975
|
return c.json({ error: "Content not found" }, 404);
|
|
@@ -991,7 +993,7 @@ apiContentCrudRoutes.get("/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
|
|
|
991
993
|
}, 500);
|
|
992
994
|
}
|
|
993
995
|
});
|
|
994
|
-
apiContentCrudRoutes.post("/",
|
|
996
|
+
apiContentCrudRoutes.post("/", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
995
997
|
try {
|
|
996
998
|
const db = c.env.DB;
|
|
997
999
|
const user = c.get("user");
|
|
@@ -1025,7 +1027,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
|
|
|
1025
1027
|
return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
|
|
1026
1028
|
}
|
|
1027
1029
|
const tenantId = getRequestTenant(c);
|
|
1028
|
-
const svc = new
|
|
1030
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
1029
1031
|
queryableFields: backing.docType.queryableFields ?? [],
|
|
1030
1032
|
typeSchemaVersion: backing.docType.schemaVersion ?? 1,
|
|
1031
1033
|
maxVersionsPerRoot: backing.docType.settings?.maxVersionsPerRoot ?? 50,
|
|
@@ -1044,7 +1046,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
|
|
|
1044
1046
|
}),
|
|
1045
1047
|
user?.userId
|
|
1046
1048
|
);
|
|
1047
|
-
const cache =
|
|
1049
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1048
1050
|
await cache.invalidate("content-filtered:*");
|
|
1049
1051
|
await cache.invalidate("collection-content-filtered:*");
|
|
1050
1052
|
dispatchHookEvent(
|
|
@@ -1054,7 +1056,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
|
|
|
1054
1056
|
"fire-and-forget"
|
|
1055
1057
|
);
|
|
1056
1058
|
return c.json({
|
|
1057
|
-
data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at:
|
|
1059
|
+
data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.createdAt), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.updatedAt) }
|
|
1058
1060
|
}, 201);
|
|
1059
1061
|
}
|
|
1060
1062
|
return c.json({ error: "Collection is not document-backed" }, 400);
|
|
@@ -1066,7 +1068,7 @@ apiContentCrudRoutes.post("/", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
|
|
|
1066
1068
|
}, 500);
|
|
1067
1069
|
}
|
|
1068
1070
|
});
|
|
1069
|
-
apiContentCrudRoutes.put("/:id",
|
|
1071
|
+
apiContentCrudRoutes.put("/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
1070
1072
|
try {
|
|
1071
1073
|
const id = c.req.param("id");
|
|
1072
1074
|
const db = c.env.DB;
|
|
@@ -1088,8 +1090,8 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
|
|
|
1088
1090
|
} catch (err) {
|
|
1089
1091
|
return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
|
|
1090
1092
|
}
|
|
1091
|
-
const docType = await new
|
|
1092
|
-
const svc = new
|
|
1093
|
+
const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
|
|
1094
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
1093
1095
|
queryableFields: docType?.queryableFields ?? [],
|
|
1094
1096
|
typeSchemaVersion: docType?.schemaVersion ?? 1,
|
|
1095
1097
|
maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50,
|
|
@@ -1108,10 +1110,10 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
|
|
|
1108
1110
|
} else if (body.status === "draft" && pub) {
|
|
1109
1111
|
await svc.unpublish(pub.id);
|
|
1110
1112
|
}
|
|
1111
|
-
const cache =
|
|
1113
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1112
1114
|
await cache.invalidate("content-filtered:*");
|
|
1113
1115
|
await cache.invalidate("collection-content-filtered:*");
|
|
1114
|
-
const coll =
|
|
1116
|
+
const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
1115
1117
|
const saved = await db.prepare("SELECT * FROM documents WHERE id = ?").bind(newDraft.id).first();
|
|
1116
1118
|
const savedData = saved?.data ? JSON.parse(saved.data) : {};
|
|
1117
1119
|
dispatchHookEvent(c, "content:after:update", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
|
|
@@ -1120,7 +1122,7 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
|
|
|
1120
1122
|
dispatchHookEvent(c, "content:after:publish", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
|
|
1121
1123
|
}
|
|
1122
1124
|
return c.json({
|
|
1123
|
-
data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at:
|
|
1125
|
+
data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.created_at), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.updated_at) }
|
|
1124
1126
|
});
|
|
1125
1127
|
}
|
|
1126
1128
|
return c.json({ error: "Content not found" }, 404);
|
|
@@ -1132,7 +1134,7 @@ apiContentCrudRoutes.put("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_
|
|
|
1132
1134
|
}, 500);
|
|
1133
1135
|
}
|
|
1134
1136
|
});
|
|
1135
|
-
apiContentCrudRoutes.delete("/:id",
|
|
1137
|
+
apiContentCrudRoutes.delete("/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
1136
1138
|
try {
|
|
1137
1139
|
const id = c.req.param("id");
|
|
1138
1140
|
const db = c.env.DB;
|
|
@@ -1148,7 +1150,7 @@ apiContentCrudRoutes.delete("/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRB
|
|
|
1148
1150
|
}
|
|
1149
1151
|
const now = Math.floor(Date.now() / 1e3);
|
|
1150
1152
|
await db.prepare("UPDATE documents SET deleted_at = ?, updated_at = ? WHERE root_id = ? AND tenant_id = ?").bind(now, now, id, tenantId).run();
|
|
1151
|
-
const cache =
|
|
1153
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1152
1154
|
await cache.invalidate("content-filtered:*");
|
|
1153
1155
|
await cache.invalidate("collection-content-filtered:*");
|
|
1154
1156
|
dispatchHookEvent(c, "content:after:delete", { collection: docRow.type_id, id, data: {}, user: actor }, "fire-and-forget");
|
|
@@ -1245,8 +1247,8 @@ function mapDocRowToContent(row, collectionId) {
|
|
|
1245
1247
|
collectionId,
|
|
1246
1248
|
data: row.data ? JSON.parse(row.data) : {},
|
|
1247
1249
|
// D29: document timestamps are SECONDS; the legacy `content` API contract is MILLISECONDS.
|
|
1248
|
-
created_at:
|
|
1249
|
-
updated_at:
|
|
1250
|
+
created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(row.created_at),
|
|
1251
|
+
updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(row.updated_at)
|
|
1250
1252
|
};
|
|
1251
1253
|
}
|
|
1252
1254
|
var apiRoutes = new hono.Hono();
|
|
@@ -1258,20 +1260,10 @@ apiRoutes.use("*", async (c, next) => {
|
|
|
1258
1260
|
c.header("X-Response-Time", `${totalTime}ms`);
|
|
1259
1261
|
});
|
|
1260
1262
|
apiRoutes.use("*", async (c, next) => {
|
|
1261
|
-
const cacheEnabled = await
|
|
1263
|
+
const cacheEnabled = await chunk4SHNHNRP_cjs.isPluginActive(c.env.DB, "core-cache");
|
|
1262
1264
|
c.set("cacheEnabled", cacheEnabled);
|
|
1263
1265
|
await next();
|
|
1264
1266
|
});
|
|
1265
|
-
apiRoutes.use("*", cors.cors({
|
|
1266
|
-
origin: (origin, c) => {
|
|
1267
|
-
const allowed = c.env?.CORS_ORIGINS;
|
|
1268
|
-
if (!allowed) return null;
|
|
1269
|
-
const list = allowed.split(",").map((s) => s.trim());
|
|
1270
|
-
return list.includes(origin) ? origin : null;
|
|
1271
|
-
},
|
|
1272
|
-
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
1273
|
-
allowHeaders: ["Content-Type", "Authorization", "X-API-Key"]
|
|
1274
|
-
}));
|
|
1275
1267
|
function addTimingMeta(c, meta = {}, executionStartTime) {
|
|
1276
1268
|
const totalTime = Date.now() - c.get("startTime");
|
|
1277
1269
|
const executionTime = executionStartTime ? Date.now() - executionStartTime : void 0;
|
|
@@ -1291,7 +1283,7 @@ apiRoutes.get("/", (c) => {
|
|
|
1291
1283
|
openapi: "3.0.0",
|
|
1292
1284
|
info: {
|
|
1293
1285
|
title: "SonicJS AI API",
|
|
1294
|
-
version:
|
|
1286
|
+
version: chunkAQJEMVAY_cjs.getCoreVersion(),
|
|
1295
1287
|
description: "RESTful API for SonicJS headless CMS - a modern, AI-powered content management system built on Cloudflare Workers",
|
|
1296
1288
|
contact: {
|
|
1297
1289
|
name: "SonicJS Support",
|
|
@@ -1695,7 +1687,7 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
1695
1687
|
try {
|
|
1696
1688
|
const db = c.env.DB;
|
|
1697
1689
|
const cacheEnabled = c.get("cacheEnabled");
|
|
1698
|
-
const cache =
|
|
1690
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1699
1691
|
const cacheKey = cache.generateKey("collections", "all");
|
|
1700
1692
|
if (cacheEnabled) {
|
|
1701
1693
|
const cacheResult = await cache.getWithSource(cacheKey);
|
|
@@ -1721,8 +1713,8 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
1721
1713
|
}
|
|
1722
1714
|
c.header("X-Cache-Status", "MISS");
|
|
1723
1715
|
c.header("X-Cache-Source", "registry");
|
|
1724
|
-
const records =
|
|
1725
|
-
const transformedResults = records.map(
|
|
1716
|
+
const records = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
|
|
1717
|
+
const transformedResults = records.map(chunk5ARIHAGN_cjs.collectionRecordToRow);
|
|
1726
1718
|
const responseData = {
|
|
1727
1719
|
data: transformedResults,
|
|
1728
1720
|
meta: addTimingMeta(c, {
|
|
@@ -1743,7 +1735,7 @@ apiRoutes.get("/collections", async (c) => {
|
|
|
1743
1735
|
return c.json({ error: "Failed to fetch collections" }, 500);
|
|
1744
1736
|
}
|
|
1745
1737
|
});
|
|
1746
|
-
apiRoutes.get("/content",
|
|
1738
|
+
apiRoutes.get("/content", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
|
|
1747
1739
|
const executionStart = Date.now();
|
|
1748
1740
|
try {
|
|
1749
1741
|
const db = c.env.DB;
|
|
@@ -1752,7 +1744,7 @@ apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
|
|
|
1752
1744
|
const collIdByName = /* @__PURE__ */ new Map();
|
|
1753
1745
|
let typeId;
|
|
1754
1746
|
let typeIds;
|
|
1755
|
-
const registry =
|
|
1747
|
+
const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
|
|
1756
1748
|
if (queryParams.collection) {
|
|
1757
1749
|
const collectionName = queryParams.collection;
|
|
1758
1750
|
const record = registry.getByName(collectionName);
|
|
@@ -1795,7 +1787,7 @@ apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
|
|
|
1795
1787
|
}, 400);
|
|
1796
1788
|
}
|
|
1797
1789
|
const cacheEnabled = c.get("cacheEnabled");
|
|
1798
|
-
const cache =
|
|
1790
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1799
1791
|
const cacheKey = cache.generateKey("content-filtered", JSON.stringify({ filter: normalizedFilter, query: queryResult.sql }));
|
|
1800
1792
|
if (cacheEnabled) {
|
|
1801
1793
|
const cacheResult = await cache.getWithSource(cacheKey);
|
|
@@ -1851,13 +1843,13 @@ apiRoutes.get("/content", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
|
|
|
1851
1843
|
}, 500);
|
|
1852
1844
|
}
|
|
1853
1845
|
});
|
|
1854
|
-
apiRoutes.get("/collections/:collection/content",
|
|
1846
|
+
apiRoutes.get("/collections/:collection/content", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
|
|
1855
1847
|
const executionStart = Date.now();
|
|
1856
1848
|
try {
|
|
1857
1849
|
const collection = c.req.param("collection");
|
|
1858
1850
|
const db = c.env.DB;
|
|
1859
1851
|
const queryParams = c.req.query();
|
|
1860
|
-
const record =
|
|
1852
|
+
const record = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
1861
1853
|
if (!record || record.isActive === false) {
|
|
1862
1854
|
return c.json({ error: "Collection not found" }, 404);
|
|
1863
1855
|
}
|
|
@@ -1879,7 +1871,7 @@ apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth
|
|
|
1879
1871
|
}, 400);
|
|
1880
1872
|
}
|
|
1881
1873
|
const cacheEnabled = c.get("cacheEnabled");
|
|
1882
|
-
const cache =
|
|
1874
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1883
1875
|
const includeCollection = queryParams.include?.split(",").map((s) => s.trim()).includes("collection");
|
|
1884
1876
|
const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter: normalizedFilter, query: queryResult.sql, includeCollection })}`);
|
|
1885
1877
|
if (cacheEnabled) {
|
|
@@ -1913,7 +1905,7 @@ apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth
|
|
|
1913
1905
|
const responseData = {
|
|
1914
1906
|
data: transformedResults,
|
|
1915
1907
|
meta: addTimingMeta(c, {
|
|
1916
|
-
...includeCollection ? { collection:
|
|
1908
|
+
...includeCollection ? { collection: chunk5ARIHAGN_cjs.collectionRecordToRow(record) } : {},
|
|
1917
1909
|
count: results.length,
|
|
1918
1910
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1919
1911
|
// D44: echo the caller's filter with the access policy applied (status=published forced for
|
|
@@ -1938,13 +1930,13 @@ apiRoutes.get("/collections/:collection/content", chunkAAWNRBRB_cjs.optionalAuth
|
|
|
1938
1930
|
}
|
|
1939
1931
|
});
|
|
1940
1932
|
apiRoutes.route("/content", api_content_crud_default);
|
|
1941
|
-
apiRoutes.get("/:collection",
|
|
1933
|
+
apiRoutes.get("/:collection", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
|
|
1942
1934
|
const executionStart = Date.now();
|
|
1943
1935
|
try {
|
|
1944
1936
|
const collection = c.req.param("collection");
|
|
1945
1937
|
const db = c.env.DB;
|
|
1946
1938
|
const queryParams = c.req.query();
|
|
1947
|
-
const record =
|
|
1939
|
+
const record = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
1948
1940
|
if (!record || record.isActive === false) {
|
|
1949
1941
|
return c.json({ error: "Collection not found" }, 404);
|
|
1950
1942
|
}
|
|
@@ -1963,7 +1955,7 @@ apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
|
|
|
1963
1955
|
const collectionCache = record.cache;
|
|
1964
1956
|
const collectionCacheDisabled = collectionCache?.enabled === false;
|
|
1965
1957
|
const cacheEnabled = c.get("cacheEnabled") && !collectionCacheDisabled;
|
|
1966
|
-
const cache =
|
|
1958
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
1967
1959
|
const includeCollection = queryParams.include?.split(",").map((s) => s.trim()).includes("collection");
|
|
1968
1960
|
const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter: normalizedFilter, query: queryResult.sql, includeCollection })}`);
|
|
1969
1961
|
if (cacheEnabled) {
|
|
@@ -1984,7 +1976,7 @@ apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
|
|
|
1984
1976
|
const responseData = {
|
|
1985
1977
|
data: transformedResults,
|
|
1986
1978
|
meta: addTimingMeta(c, {
|
|
1987
|
-
...includeCollection ? { collection:
|
|
1979
|
+
...includeCollection ? { collection: chunk5ARIHAGN_cjs.collectionRecordToRow(record) } : {},
|
|
1988
1980
|
count: results.length,
|
|
1989
1981
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1990
1982
|
filter: normalizePublicContentFilter(filter, role),
|
|
@@ -2002,12 +1994,12 @@ apiRoutes.get("/:collection", chunkAAWNRBRB_cjs.optionalAuth(), async (c) => {
|
|
|
2002
1994
|
return c.json({ error: "Failed to fetch content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2003
1995
|
}
|
|
2004
1996
|
});
|
|
2005
|
-
apiRoutes.get("/:collection/:id",
|
|
1997
|
+
apiRoutes.get("/:collection/:id", chunk4SHNHNRP_cjs.optionalAuth(), async (c) => {
|
|
2006
1998
|
try {
|
|
2007
1999
|
const collection = c.req.param("collection");
|
|
2008
2000
|
const id = c.req.param("id");
|
|
2009
2001
|
const db = c.env.DB;
|
|
2010
|
-
const record =
|
|
2002
|
+
const record = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
2011
2003
|
if (!record || record.isActive === false) {
|
|
2012
2004
|
return c.json({ error: "Collection not found" }, 404);
|
|
2013
2005
|
}
|
|
@@ -2016,7 +2008,7 @@ apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
|
|
|
2016
2008
|
privileged ? "SELECT * FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL" : "SELECT * FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND is_published = 1 AND deleted_at IS NULL"
|
|
2017
2009
|
).bind(id, record.name).first();
|
|
2018
2010
|
if (!docRow) return c.json({ error: "Content not found" }, 404);
|
|
2019
|
-
const coll =
|
|
2011
|
+
const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
2020
2012
|
const transformedContent = {
|
|
2021
2013
|
id: docRow.root_id,
|
|
2022
2014
|
title: docRow.title,
|
|
@@ -2024,8 +2016,8 @@ apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
|
|
|
2024
2016
|
status: docRow.status,
|
|
2025
2017
|
collectionId: coll?.id ?? docRow.type_id,
|
|
2026
2018
|
data: docRow.data ? JSON.parse(docRow.data) : {},
|
|
2027
|
-
created_at:
|
|
2028
|
-
updated_at:
|
|
2019
|
+
created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.created_at),
|
|
2020
|
+
updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(docRow.updated_at)
|
|
2029
2021
|
};
|
|
2030
2022
|
dispatchHookEvent(c, "content:read", { collection: docRow.type_id, id: docRow.root_id, data: transformedContent.data }, "fire-and-forget");
|
|
2031
2023
|
return c.json({ data: transformedContent });
|
|
@@ -2034,7 +2026,7 @@ apiRoutes.get("/:collection/:id", chunkAAWNRBRB_cjs.optionalAuth(), async (c) =>
|
|
|
2034
2026
|
return c.json({ error: "Failed to fetch content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2035
2027
|
}
|
|
2036
2028
|
});
|
|
2037
|
-
apiRoutes.post("/:collection",
|
|
2029
|
+
apiRoutes.post("/:collection", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
2038
2030
|
try {
|
|
2039
2031
|
const collection = c.req.param("collection");
|
|
2040
2032
|
const db = c.env.DB;
|
|
@@ -2055,26 +2047,26 @@ apiRoutes.post("/:collection", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB_cj
|
|
|
2055
2047
|
} catch (err) {
|
|
2056
2048
|
return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
|
|
2057
2049
|
}
|
|
2058
|
-
const svc = new
|
|
2050
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, { queryableFields: backing.docType.queryableFields ?? [], typeSchemaVersion: backing.docType.schemaVersion ?? 1, maxVersionsPerRoot: backing.docType.settings?.maxVersionsPerRoot ?? 50, tenantId: "default", versioning: backing.docType.settings?.versioning ?? false });
|
|
2059
2051
|
const doc = await svc.create(createDocumentSchema.parse({ typeId: backing.coll.name, tenantId: "default", locale: "default", title, slug: finalSlug, data: hookData, publishOnCreate: (status || "draft") === "published" }), user?.userId);
|
|
2060
|
-
const cache =
|
|
2052
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
2061
2053
|
await cache.invalidate("content-filtered:*");
|
|
2062
2054
|
await cache.invalidate("collection-content-filtered:*");
|
|
2063
2055
|
dispatchHookEvent(c, "content:after:create", { collection: backing.coll.name, id: doc.rootId, data: doc.data ?? {}, user: actor }, "fire-and-forget");
|
|
2064
|
-
return c.json({ data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at:
|
|
2056
|
+
return c.json({ data: { id: doc.rootId, title: doc.title, slug: doc.slug, status: doc.status, collectionId: backing.coll.id, data: doc.data, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.createdAt), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(doc.updatedAt) } }, 201);
|
|
2065
2057
|
} catch (error) {
|
|
2066
2058
|
console.error("Error creating content:", error);
|
|
2067
2059
|
return c.json({ error: "Failed to create content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2068
2060
|
}
|
|
2069
2061
|
});
|
|
2070
|
-
apiRoutes.put("/:collection/:id",
|
|
2062
|
+
apiRoutes.put("/:collection/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
2071
2063
|
try {
|
|
2072
2064
|
const collection = c.req.param("collection");
|
|
2073
2065
|
const id = c.req.param("id");
|
|
2074
2066
|
const db = c.env.DB;
|
|
2075
2067
|
const user = c.get("user");
|
|
2076
2068
|
const body = await c.req.json();
|
|
2077
|
-
const collRecord =
|
|
2069
|
+
const collRecord = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
2078
2070
|
const typeName = collRecord?.name ?? collection;
|
|
2079
2071
|
const docRow = await db.prepare("SELECT root_id, type_id FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL").bind(id, typeName).first();
|
|
2080
2072
|
if (!docRow) return c.json({ error: "Content not found" }, 404);
|
|
@@ -2086,8 +2078,8 @@ apiRoutes.put("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB
|
|
|
2086
2078
|
} catch (err) {
|
|
2087
2079
|
return c.json({ error: "Write cancelled by plugin", details: String(err) }, 400);
|
|
2088
2080
|
}
|
|
2089
|
-
const docType = await new
|
|
2090
|
-
const svc = new
|
|
2081
|
+
const docType = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(docRow.type_id);
|
|
2082
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, { queryableFields: docType?.queryableFields ?? [], typeSchemaVersion: docType?.schemaVersion ?? 1, maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50, tenantId: "default", versioning: docType?.settings?.versioning ?? false });
|
|
2091
2083
|
const input = {};
|
|
2092
2084
|
if (body.title !== void 0) input.title = body.title;
|
|
2093
2085
|
if (body.slug !== void 0) input.slug = slugify(body.slug);
|
|
@@ -2100,28 +2092,28 @@ apiRoutes.put("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNRBRB
|
|
|
2100
2092
|
} else if (body.status === "draft" && pub) {
|
|
2101
2093
|
await svc.unpublish(pub.id);
|
|
2102
2094
|
}
|
|
2103
|
-
const cache =
|
|
2095
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
2104
2096
|
await cache.invalidate("content-filtered:*");
|
|
2105
2097
|
await cache.invalidate("collection-content-filtered:*");
|
|
2106
|
-
const coll =
|
|
2098
|
+
const coll = chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(docRow.type_id);
|
|
2107
2099
|
const saved = await db.prepare("SELECT * FROM documents WHERE id = ?").bind(newDraft.id).first();
|
|
2108
2100
|
const savedData = saved?.data ? JSON.parse(saved.data) : {};
|
|
2109
2101
|
dispatchHookEvent(c, "content:after:update", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
|
|
2110
2102
|
const nowPublished = body.status === "published" || body.status === void 0 && wasPublished;
|
|
2111
2103
|
if (nowPublished && !wasPublished) dispatchHookEvent(c, "content:after:publish", { collection: docRow.type_id, id, data: savedData, user: actor }, "fire-and-forget");
|
|
2112
|
-
return c.json({ data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at:
|
|
2104
|
+
return c.json({ data: { id: saved.root_id, title: saved.title, slug: saved.slug, status: saved.status, collectionId: coll?.id ?? docRow.type_id, data: savedData, created_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.created_at), updated_at: chunkLTZ5WYOK_cjs.documentSecondsToMs(saved.updated_at) } });
|
|
2113
2105
|
} catch (error) {
|
|
2114
2106
|
console.error("Error updating content:", error);
|
|
2115
2107
|
return c.json({ error: "Failed to update content", details: error instanceof Error ? error.message : String(error) }, 500);
|
|
2116
2108
|
}
|
|
2117
2109
|
});
|
|
2118
|
-
apiRoutes.delete("/:collection/:id",
|
|
2110
|
+
apiRoutes.delete("/:collection/:id", chunk4SHNHNRP_cjs.requireAuth(), chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
2119
2111
|
try {
|
|
2120
2112
|
const collection = c.req.param("collection");
|
|
2121
2113
|
const id = c.req.param("id");
|
|
2122
2114
|
const db = c.env.DB;
|
|
2123
2115
|
const user = c.get("user");
|
|
2124
|
-
const collRecord =
|
|
2116
|
+
const collRecord = chunk5ARIHAGN_cjs.getCollectionRegistry().getBySlugOrName(collection);
|
|
2125
2117
|
const typeName = collRecord?.name ?? collection;
|
|
2126
2118
|
const docRow = await db.prepare("SELECT type_id FROM documents WHERE root_id = ? AND type_id = ? AND tenant_id = 'default' AND deleted_at IS NULL LIMIT 1").bind(id, typeName).first();
|
|
2127
2119
|
if (!docRow) return c.json({ error: "Content not found" }, 404);
|
|
@@ -2133,7 +2125,7 @@ apiRoutes.delete("/:collection/:id", chunkAAWNRBRB_cjs.requireAuth(), chunkAAWNR
|
|
|
2133
2125
|
}
|
|
2134
2126
|
const now = Math.floor(Date.now() / 1e3);
|
|
2135
2127
|
await db.prepare("UPDATE documents SET deleted_at = ?, updated_at = ? WHERE root_id = ? AND tenant_id = 'default'").bind(now, now, id).run();
|
|
2136
|
-
const cache =
|
|
2128
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
2137
2129
|
await cache.invalidate("content-filtered:*");
|
|
2138
2130
|
await cache.invalidate("collection-content-filtered:*");
|
|
2139
2131
|
dispatchHookEvent(c, "content:after:delete", { collection: docRow.type_id, id, data: {}, user: actor }, "fire-and-forget");
|
|
@@ -2204,9 +2196,11 @@ var MediaDocumentService = class {
|
|
|
2204
2196
|
this.db = db;
|
|
2205
2197
|
this.tenantId = tenantId;
|
|
2206
2198
|
}
|
|
2199
|
+
db;
|
|
2200
|
+
tenantId;
|
|
2207
2201
|
/** Create a media_asset document from R2 upload metadata. Published-on-create (immediately usable). */
|
|
2208
2202
|
async createFromUpload(meta, createdBy) {
|
|
2209
|
-
const svc = new
|
|
2203
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(this.db, { queryableFields: MEDIA_QUERYABLE, tenantId: this.tenantId, maxVersionsPerRoot: 5 });
|
|
2210
2204
|
return svc.create(
|
|
2211
2205
|
createDocumentSchema.parse({
|
|
2212
2206
|
typeId: "media_asset",
|
|
@@ -2279,7 +2273,7 @@ var MediaDocumentService = class {
|
|
|
2279
2273
|
}
|
|
2280
2274
|
/** Update alt/caption/tags on a media_asset document (saveDraft + publish atomically). */
|
|
2281
2275
|
async updateMetadata(rootId, meta, updatedBy) {
|
|
2282
|
-
const svc = new
|
|
2276
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(this.db, { queryableFields: MEDIA_QUERYABLE, tenantId: this.tenantId, maxVersionsPerRoot: 5 });
|
|
2283
2277
|
const newDraft = await svc.saveDraft(rootId, { data: meta }, updatedBy);
|
|
2284
2278
|
return svc.publish(newDraft.id, updatedBy);
|
|
2285
2279
|
}
|
|
@@ -2336,7 +2330,7 @@ var fileValidationSchema = zod.z.object({
|
|
|
2336
2330
|
// 50MB max
|
|
2337
2331
|
});
|
|
2338
2332
|
var apiMediaRoutes = new hono.Hono();
|
|
2339
|
-
apiMediaRoutes.use("*",
|
|
2333
|
+
apiMediaRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
2340
2334
|
apiMediaRoutes.post("/upload", async (c) => {
|
|
2341
2335
|
try {
|
|
2342
2336
|
const user = c.get("user");
|
|
@@ -3034,7 +3028,7 @@ apiSystemRoutes.get("/info", (c) => {
|
|
|
3034
3028
|
apiSystemRoutes.get("/stats", async (c) => {
|
|
3035
3029
|
try {
|
|
3036
3030
|
const db = c.env.DB;
|
|
3037
|
-
const typeIds =
|
|
3031
|
+
const typeIds = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => r.name);
|
|
3038
3032
|
let contentStats = null;
|
|
3039
3033
|
if (typeIds.length > 0) {
|
|
3040
3034
|
const placeholders = typeIds.map(() => "?").join(",");
|
|
@@ -3109,12 +3103,12 @@ apiSystemRoutes.get("/env", (c) => {
|
|
|
3109
3103
|
});
|
|
3110
3104
|
var api_system_default = apiSystemRoutes;
|
|
3111
3105
|
var adminApiRoutes = new hono.Hono();
|
|
3112
|
-
adminApiRoutes.use("*",
|
|
3113
|
-
adminApiRoutes.use("*",
|
|
3106
|
+
adminApiRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
3107
|
+
adminApiRoutes.use("*", chunk4SHNHNRP_cjs.requireRole(["admin", "editor"]));
|
|
3114
3108
|
adminApiRoutes.get("/stats", async (c) => {
|
|
3115
3109
|
try {
|
|
3116
3110
|
const db = c.env.DB;
|
|
3117
|
-
const userCollections =
|
|
3111
|
+
const userCollections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
|
|
3118
3112
|
const collectionsCount = userCollections.length;
|
|
3119
3113
|
let contentCount = 0;
|
|
3120
3114
|
if (userCollections.length > 0) {
|
|
@@ -3205,7 +3199,7 @@ adminApiRoutes.get("/collections", async (c) => {
|
|
|
3205
3199
|
try {
|
|
3206
3200
|
const search = c.req.query("search") || "";
|
|
3207
3201
|
const includeInactive = c.req.query("includeInactive") === "true";
|
|
3208
|
-
let records =
|
|
3202
|
+
let records = chunk5ARIHAGN_cjs.getCollectionRegistry().list().filter((r) => !r.internal);
|
|
3209
3203
|
if (!includeInactive) records = records.filter((r) => r.isActive !== false);
|
|
3210
3204
|
if (search) {
|
|
3211
3205
|
const needle = search.toLowerCase();
|
|
@@ -3237,7 +3231,7 @@ adminApiRoutes.get("/collections", async (c) => {
|
|
|
3237
3231
|
adminApiRoutes.get("/collections/:id", async (c) => {
|
|
3238
3232
|
try {
|
|
3239
3233
|
const id = c.req.param("id");
|
|
3240
|
-
const registry =
|
|
3234
|
+
const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
|
|
3241
3235
|
const record = registry.getById(id) ?? registry.getByName(id);
|
|
3242
3236
|
if (!record) {
|
|
3243
3237
|
return c.json({ error: "Collection not found" }, 404);
|
|
@@ -3287,7 +3281,7 @@ adminApiRoutes.get("/references", async (c) => {
|
|
|
3287
3281
|
if (collectionParams.length === 0) {
|
|
3288
3282
|
return c.json({ error: "Collection is required" }, 400);
|
|
3289
3283
|
}
|
|
3290
|
-
const registry =
|
|
3284
|
+
const registry = chunk5ARIHAGN_cjs.getCollectionRegistry();
|
|
3291
3285
|
const matched = collectionParams.map((param) => registry.getById(param) ?? registry.getByName(param)).filter((r) => !!r);
|
|
3292
3286
|
const seen = /* @__PURE__ */ new Set();
|
|
3293
3287
|
const collections = matched.filter((r) => {
|
|
@@ -3402,7 +3396,7 @@ adminApiRoutes.patch("/collections/:id", collectionsReadOnly);
|
|
|
3402
3396
|
adminApiRoutes.delete("/collections/:id", collectionsReadOnly);
|
|
3403
3397
|
adminApiRoutes.get("/migrations/status", async (c) => {
|
|
3404
3398
|
try {
|
|
3405
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
3399
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-VQAFXMU7.cjs');
|
|
3406
3400
|
const db = c.env.DB;
|
|
3407
3401
|
const migrationService = new MigrationService2(db);
|
|
3408
3402
|
const status = await migrationService.getMigrationStatus();
|
|
@@ -3445,7 +3439,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
|
|
|
3445
3439
|
});
|
|
3446
3440
|
adminApiRoutes.get("/migrations/validate", async (c) => {
|
|
3447
3441
|
try {
|
|
3448
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
3442
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-VQAFXMU7.cjs');
|
|
3449
3443
|
const db = c.env.DB;
|
|
3450
3444
|
const migrationService = new MigrationService2(db);
|
|
3451
3445
|
const validation = await migrationService.validateSchema();
|
|
@@ -3595,8 +3589,8 @@ function renderLoginPage(data, demoLoginActive = false) {
|
|
|
3595
3589
|
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
|
3596
3590
|
<div class="bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10">
|
|
3597
3591
|
<!-- Alerts -->
|
|
3598
|
-
${data.error ? `<div class="mb-6">${
|
|
3599
|
-
${data.message ? `<div class="mb-6">${
|
|
3592
|
+
${data.error ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
|
|
3593
|
+
${data.message ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.message })}</div>` : ""}
|
|
3600
3594
|
|
|
3601
3595
|
<!-- Form Response (HTMX target) -->
|
|
3602
3596
|
<div id="form-response" class="mb-6"></div>
|
|
@@ -3604,7 +3598,7 @@ function renderLoginPage(data, demoLoginActive = false) {
|
|
|
3604
3598
|
<!-- Form -->
|
|
3605
3599
|
<form
|
|
3606
3600
|
id="login-form"
|
|
3607
|
-
hx-post="/auth/login/form"
|
|
3601
|
+
hx-post="/auth/login/form${data.redirect ? `?redirect=${encodeURIComponent(data.redirect)}` : ""}"
|
|
3608
3602
|
hx-target="#form-response"
|
|
3609
3603
|
hx-swap="innerHTML"
|
|
3610
3604
|
class="space-y-6"
|
|
@@ -3760,7 +3754,7 @@ function renderRegisterPage(data) {
|
|
|
3760
3754
|
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
|
3761
3755
|
<div class="bg-zinc-900 shadow-sm ring-1 ring-white/10 rounded-xl px-6 py-8 sm:px-10">
|
|
3762
3756
|
<!-- Alerts -->
|
|
3763
|
-
${data.error ? `<div class="mb-6">${
|
|
3757
|
+
${data.error ? `<div class="mb-6">${chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error })}</div>` : ""}
|
|
3764
3758
|
|
|
3765
3759
|
<!-- Form -->
|
|
3766
3760
|
<form
|
|
@@ -3860,7 +3854,7 @@ function renderRegisterPage(data) {
|
|
|
3860
3854
|
}
|
|
3861
3855
|
|
|
3862
3856
|
// src/services/email/email-service-singleton.ts
|
|
3863
|
-
var singleton =
|
|
3857
|
+
var singleton = chunk5RSB5SEK_cjs.createServiceSingleton("EmailService");
|
|
3864
3858
|
function setEmailService(service2) {
|
|
3865
3859
|
singleton.set(service2);
|
|
3866
3860
|
}
|
|
@@ -3904,7 +3898,7 @@ function emptyProfile() {
|
|
|
3904
3898
|
return { custom: {} };
|
|
3905
3899
|
}
|
|
3906
3900
|
function service(db) {
|
|
3907
|
-
return new
|
|
3901
|
+
return new chunkLTZ5WYOK_cjs.DocumentsService(db, { tenantId: "default", maxVersionsPerRoot: 1, queryableFields: [] });
|
|
3908
3902
|
}
|
|
3909
3903
|
async function readProfileData(db, userId) {
|
|
3910
3904
|
const row = await db.prepare(
|
|
@@ -4668,7 +4662,7 @@ function getLexicalInitScript(settings = {}) {
|
|
|
4668
4662
|
</script>
|
|
4669
4663
|
`;
|
|
4670
4664
|
}
|
|
4671
|
-
var lexicalEditorPlugin =
|
|
4665
|
+
var lexicalEditorPlugin = chunk5RSB5SEK_cjs.definePlugin({
|
|
4672
4666
|
id: "lexical-editor",
|
|
4673
4667
|
version: "1.0.0",
|
|
4674
4668
|
name: "Lexical Editor",
|
|
@@ -5592,6 +5586,79 @@ function renderDynamicField(field, options = {}) {
|
|
|
5592
5586
|
`;
|
|
5593
5587
|
break;
|
|
5594
5588
|
}
|
|
5589
|
+
case "json": {
|
|
5590
|
+
const jsonParsedValue = value !== null && value !== void 0 && typeof value !== "string" ? value : typeof value === "string" && value !== "" ? (() => {
|
|
5591
|
+
try {
|
|
5592
|
+
return JSON.parse(value);
|
|
5593
|
+
} catch {
|
|
5594
|
+
return value;
|
|
5595
|
+
}
|
|
5596
|
+
})() : null;
|
|
5597
|
+
const jsonDisplayValue = jsonParsedValue !== null && typeof jsonParsedValue !== "string" ? JSON.stringify(jsonParsedValue, null, 2) : typeof jsonParsedValue === "string" ? jsonParsedValue : "";
|
|
5598
|
+
const viewerId = `${fieldId}-viewer`;
|
|
5599
|
+
const textareaId = `${fieldId}-textarea`;
|
|
5600
|
+
const jsonDataAttr = escapeHtml2(JSON.stringify(jsonParsedValue ?? null));
|
|
5601
|
+
const isEmpty = jsonParsedValue === null || jsonDisplayValue === "";
|
|
5602
|
+
if (disabled) {
|
|
5603
|
+
fieldHTML = `
|
|
5604
|
+
<div
|
|
5605
|
+
id="${viewerId}"
|
|
5606
|
+
class="json-viewer-host rounded-lg px-3 py-2 text-xs bg-white dark:bg-zinc-800 shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 min-h-[2.5rem] overflow-auto"
|
|
5607
|
+
data-json-viewer
|
|
5608
|
+
data-json="${jsonDataAttr}"
|
|
5609
|
+
data-open="${opts.open ?? 2}"
|
|
5610
|
+
>${isEmpty ? '<span class="text-zinc-400 dark:text-zinc-500 italic">empty</span>' : ""}</div>
|
|
5611
|
+
${getJsonViewerScript()}
|
|
5612
|
+
`;
|
|
5613
|
+
} else {
|
|
5614
|
+
fieldHTML = `
|
|
5615
|
+
<div class="json-field-wrapper space-y-2">
|
|
5616
|
+
<div class="flex items-center justify-end">
|
|
5617
|
+
<button
|
|
5618
|
+
type="button"
|
|
5619
|
+
id="${fieldId}-toggle"
|
|
5620
|
+
class="text-xs text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200 underline transition-colors"
|
|
5621
|
+
data-json-toggle
|
|
5622
|
+
data-viewer="${viewerId}"
|
|
5623
|
+
data-textarea="${textareaId}"
|
|
5624
|
+
data-hidden-input="${fieldId}"
|
|
5625
|
+
>Edit JSON</button>
|
|
5626
|
+
</div>
|
|
5627
|
+
|
|
5628
|
+
<div
|
|
5629
|
+
id="${viewerId}"
|
|
5630
|
+
class="json-viewer-host rounded-lg px-3 py-2 text-xs bg-white dark:bg-zinc-800 shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 min-h-[2.5rem] overflow-auto"
|
|
5631
|
+
data-json-viewer
|
|
5632
|
+
data-json="${jsonDataAttr}"
|
|
5633
|
+
data-open="${opts.open ?? 2}"
|
|
5634
|
+
>${isEmpty ? '<span class="text-zinc-400 dark:text-zinc-500 italic">empty \u2014 click "Edit JSON" to add data</span>' : ""}</div>
|
|
5635
|
+
|
|
5636
|
+
<textarea
|
|
5637
|
+
id="${textareaId}"
|
|
5638
|
+
rows="${opts.rows || 8}"
|
|
5639
|
+
placeholder="${opts.placeholder || "{}"}"
|
|
5640
|
+
class="${baseClasses} ${errorClasses} resize-y font-mono text-xs hidden"
|
|
5641
|
+
aria-label="${escapeHtml2(field.field_label)}"
|
|
5642
|
+
data-json-edit-area
|
|
5643
|
+
data-viewer="${viewerId}"
|
|
5644
|
+
data-hidden-input="${fieldId}"
|
|
5645
|
+
>${escapeHtml2(jsonDisplayValue)}</textarea>
|
|
5646
|
+
|
|
5647
|
+
<input
|
|
5648
|
+
type="hidden"
|
|
5649
|
+
id="${fieldId}"
|
|
5650
|
+
name="${fieldName}"
|
|
5651
|
+
value="${escapeHtml2(jsonDisplayValue)}"
|
|
5652
|
+
${required}
|
|
5653
|
+
>
|
|
5654
|
+
|
|
5655
|
+
<div id="${fieldId}-json-error" class="text-xs text-pink-500 dark:text-pink-400 hidden"></div>
|
|
5656
|
+
</div>
|
|
5657
|
+
${getJsonViewerScript()}
|
|
5658
|
+
`;
|
|
5659
|
+
}
|
|
5660
|
+
break;
|
|
5661
|
+
}
|
|
5595
5662
|
default:
|
|
5596
5663
|
fieldHTML = `
|
|
5597
5664
|
<input
|
|
@@ -6088,6 +6155,120 @@ function normalizeBlockField(fieldConfig, fieldName) {
|
|
|
6088
6155
|
options
|
|
6089
6156
|
};
|
|
6090
6157
|
}
|
|
6158
|
+
function getJsonViewerScript() {
|
|
6159
|
+
return `
|
|
6160
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/json-formatter-js@2.5.23/dist/json-formatter.min.css" id="json-formatter-css" onload="this.removeAttribute('onload')" onerror="">
|
|
6161
|
+
<script>
|
|
6162
|
+
(function() {
|
|
6163
|
+
var JS_URL = 'https://cdn.jsdelivr.net/npm/json-formatter-js@2.5.23/dist/json-formatter.umd.min.js';
|
|
6164
|
+
|
|
6165
|
+
function isDark() {
|
|
6166
|
+
return document.documentElement.classList.contains('dark') ||
|
|
6167
|
+
document.documentElement.dataset.theme === 'dark' ||
|
|
6168
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
6169
|
+
}
|
|
6170
|
+
|
|
6171
|
+
function initViewer(el) {
|
|
6172
|
+
var raw = el.dataset.json;
|
|
6173
|
+
var open = parseInt(el.dataset.open || '2', 10);
|
|
6174
|
+
if (!raw || raw === 'null') return;
|
|
6175
|
+
var data;
|
|
6176
|
+
try { data = JSON.parse(raw); } catch(e) { el.textContent = raw; return; }
|
|
6177
|
+
var fmt = new JSONFormatter(data, open, {
|
|
6178
|
+
hoverPreviewEnabled: true,
|
|
6179
|
+
hoverPreviewArrayCount: 5,
|
|
6180
|
+
hoverPreviewFieldCount: 5,
|
|
6181
|
+
theme: isDark() ? 'dark' : '',
|
|
6182
|
+
animateOpen: true,
|
|
6183
|
+
animateClose: true,
|
|
6184
|
+
});
|
|
6185
|
+
el.innerHTML = '';
|
|
6186
|
+
el.appendChild(fmt.render());
|
|
6187
|
+
}
|
|
6188
|
+
|
|
6189
|
+
function initAllViewers() {
|
|
6190
|
+
document.querySelectorAll('[data-json-viewer]').forEach(function(el) { initViewer(el); });
|
|
6191
|
+
}
|
|
6192
|
+
|
|
6193
|
+
function ensureLoaded(cb) {
|
|
6194
|
+
if (window.JSONFormatter) { cb(); return; }
|
|
6195
|
+
if (window.__jsonFormatterCallbacks) { window.__jsonFormatterCallbacks.push(cb); return; }
|
|
6196
|
+
window.__jsonFormatterCallbacks = [cb];
|
|
6197
|
+
var s = document.createElement('script');
|
|
6198
|
+
s.src = JS_URL;
|
|
6199
|
+
s.onload = function() {
|
|
6200
|
+
(window.__jsonFormatterCallbacks || []).forEach(function(fn) { fn(); });
|
|
6201
|
+
window.__jsonFormatterCallbacks = null;
|
|
6202
|
+
};
|
|
6203
|
+
document.head.appendChild(s);
|
|
6204
|
+
}
|
|
6205
|
+
|
|
6206
|
+
if (!window.__sonicJsonViewerInit) {
|
|
6207
|
+
window.__sonicJsonViewerInit = true;
|
|
6208
|
+
|
|
6209
|
+
// Toggle between viewer and edit textarea
|
|
6210
|
+
document.addEventListener('click', function(e) {
|
|
6211
|
+
var btn = e.target.closest('[data-json-toggle]');
|
|
6212
|
+
if (!btn) return;
|
|
6213
|
+
var viewerId = btn.dataset.viewer;
|
|
6214
|
+
var textareaId = btn.dataset.textarea;
|
|
6215
|
+
var hiddenId = btn.dataset.hiddenInput;
|
|
6216
|
+
var viewer = document.getElementById(viewerId);
|
|
6217
|
+
var textarea = document.getElementById(textareaId);
|
|
6218
|
+
var hidden = document.getElementById(hiddenId);
|
|
6219
|
+
var errorEl = hidden ? document.getElementById(hiddenId + '-json-error') : null;
|
|
6220
|
+
if (!viewer || !textarea) return;
|
|
6221
|
+
var isEditing = !textarea.classList.contains('hidden');
|
|
6222
|
+
if (isEditing) {
|
|
6223
|
+
// Switching back to viewer \u2014 validate + refresh
|
|
6224
|
+
var raw = textarea.value.trim();
|
|
6225
|
+
if (raw) {
|
|
6226
|
+
try {
|
|
6227
|
+
var parsed = JSON.parse(raw);
|
|
6228
|
+
if (hidden) hidden.value = raw;
|
|
6229
|
+
viewer.dataset.json = JSON.stringify(parsed);
|
|
6230
|
+
ensureLoaded(function() { initViewer(viewer); });
|
|
6231
|
+
if (errorEl) { errorEl.textContent = ''; errorEl.classList.add('hidden'); }
|
|
6232
|
+
} catch(ex) {
|
|
6233
|
+
if (errorEl) { errorEl.textContent = 'Invalid JSON: ' + ex.message; errorEl.classList.remove('hidden'); }
|
|
6234
|
+
return;
|
|
6235
|
+
}
|
|
6236
|
+
} else {
|
|
6237
|
+
if (hidden) hidden.value = '';
|
|
6238
|
+
viewer.innerHTML = '<span class="text-zinc-400 dark:text-zinc-500 italic">empty</span>';
|
|
6239
|
+
}
|
|
6240
|
+
textarea.classList.add('hidden');
|
|
6241
|
+
viewer.classList.remove('hidden');
|
|
6242
|
+
btn.textContent = 'Edit JSON';
|
|
6243
|
+
} else {
|
|
6244
|
+
// Switching to edit \u2014 populate textarea from hidden input
|
|
6245
|
+
if (hidden && hidden.value) {
|
|
6246
|
+
try {
|
|
6247
|
+
textarea.value = JSON.stringify(JSON.parse(hidden.value), null, 2);
|
|
6248
|
+
} catch(e) {
|
|
6249
|
+
textarea.value = hidden.value;
|
|
6250
|
+
}
|
|
6251
|
+
}
|
|
6252
|
+
viewer.classList.add('hidden');
|
|
6253
|
+
textarea.classList.remove('hidden');
|
|
6254
|
+
btn.textContent = 'Preview';
|
|
6255
|
+
}
|
|
6256
|
+
});
|
|
6257
|
+
}
|
|
6258
|
+
|
|
6259
|
+
function run() {
|
|
6260
|
+
ensureLoaded(initAllViewers);
|
|
6261
|
+
}
|
|
6262
|
+
|
|
6263
|
+
if (document.readyState === 'loading') {
|
|
6264
|
+
document.addEventListener('DOMContentLoaded', run);
|
|
6265
|
+
} else {
|
|
6266
|
+
run();
|
|
6267
|
+
}
|
|
6268
|
+
})();
|
|
6269
|
+
</script>
|
|
6270
|
+
`;
|
|
6271
|
+
}
|
|
6091
6272
|
function getStructuredFieldScript() {
|
|
6092
6273
|
return `
|
|
6093
6274
|
${getReadFieldValueScript()}
|
|
@@ -6887,7 +7068,7 @@ api.put("/:userId", async (c) => {
|
|
|
6887
7068
|
await saveCustomData(db, userId, sanitized);
|
|
6888
7069
|
return c.json({ success: true });
|
|
6889
7070
|
});
|
|
6890
|
-
var userProfilesPlugin =
|
|
7071
|
+
var userProfilesPlugin = chunk5RSB5SEK_cjs.definePlugin({
|
|
6891
7072
|
id: "user-profiles",
|
|
6892
7073
|
version: "1.0.0",
|
|
6893
7074
|
name: "User Profiles",
|
|
@@ -6925,8 +7106,8 @@ function renderPasswordResetEmail(resetLink, firstName) {
|
|
|
6925
7106
|
async function setCsrfCookie(c, maxAge) {
|
|
6926
7107
|
const secret = c.env?.JWT_SECRET || JWT_SECRET_FALLBACK;
|
|
6927
7108
|
const isDev = c.env?.ENVIRONMENT === "development" || !c.env?.ENVIRONMENT;
|
|
6928
|
-
const csrfToken = await
|
|
6929
|
-
const cookieMaxAge = await
|
|
7109
|
+
const csrfToken = await chunk4SHNHNRP_cjs.generateCsrfToken(secret);
|
|
7110
|
+
const cookieMaxAge = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env?.DB, c.env);
|
|
6930
7111
|
cookie.setCookie(c, "csrf_token", csrfToken, {
|
|
6931
7112
|
httpOnly: false,
|
|
6932
7113
|
secure: !isDev,
|
|
@@ -6948,10 +7129,12 @@ var authRoutes = new hono.Hono();
|
|
|
6948
7129
|
authRoutes.get("/login", async (c) => {
|
|
6949
7130
|
const error = c.req.query("error");
|
|
6950
7131
|
const message = c.req.query("message");
|
|
7132
|
+
const redirect = c.req.query("redirect");
|
|
6951
7133
|
const pageData = {
|
|
6952
7134
|
error: error || void 0,
|
|
6953
7135
|
message: message || void 0,
|
|
6954
|
-
version: c.get("appVersion")
|
|
7136
|
+
version: c.get("appVersion"),
|
|
7137
|
+
redirect: redirect && redirect.startsWith("/") ? redirect : void 0
|
|
6955
7138
|
};
|
|
6956
7139
|
const db = c.env.DB;
|
|
6957
7140
|
let demoLoginActive = false;
|
|
@@ -6964,9 +7147,9 @@ authRoutes.get("/login", async (c) => {
|
|
|
6964
7147
|
});
|
|
6965
7148
|
authRoutes.get("/register", async (c) => {
|
|
6966
7149
|
const db = c.env.DB;
|
|
6967
|
-
const isFirstUser = await
|
|
7150
|
+
const isFirstUser = await chunkXWVDSM2L_cjs.isFirstUserRegistration(db);
|
|
6968
7151
|
if (!isFirstUser) {
|
|
6969
|
-
const registrationEnabled = await
|
|
7152
|
+
const registrationEnabled = await chunkXWVDSM2L_cjs.isRegistrationEnabled(db);
|
|
6970
7153
|
if (!registrationEnabled) {
|
|
6971
7154
|
return c.redirect("/auth/login?error=Registration is currently disabled");
|
|
6972
7155
|
}
|
|
@@ -6983,13 +7166,13 @@ var loginSchema = zod.z.object({
|
|
|
6983
7166
|
});
|
|
6984
7167
|
authRoutes.post(
|
|
6985
7168
|
"/register",
|
|
6986
|
-
|
|
7169
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
|
|
6987
7170
|
async (c) => {
|
|
6988
7171
|
try {
|
|
6989
7172
|
const db = c.env.DB;
|
|
6990
|
-
const isFirstUser = await
|
|
7173
|
+
const isFirstUser = await chunkXWVDSM2L_cjs.isFirstUserRegistration(db);
|
|
6991
7174
|
if (!isFirstUser) {
|
|
6992
|
-
const registrationEnabled = await
|
|
7175
|
+
const registrationEnabled = await chunkXWVDSM2L_cjs.isRegistrationEnabled(db);
|
|
6993
7176
|
if (!registrationEnabled) {
|
|
6994
7177
|
return c.json({ error: "Registration is currently disabled" }, 403);
|
|
6995
7178
|
}
|
|
@@ -7000,7 +7183,7 @@ authRoutes.post(
|
|
|
7000
7183
|
} catch (parseError) {
|
|
7001
7184
|
return c.json({ error: "Invalid JSON in request body" }, 400);
|
|
7002
7185
|
}
|
|
7003
|
-
const validationSchema = await
|
|
7186
|
+
const validationSchema = await chunkXWVDSM2L_cjs.authValidationService.buildRegistrationSchema(db);
|
|
7004
7187
|
let validatedData;
|
|
7005
7188
|
try {
|
|
7006
7189
|
validatedData = await validationSchema.parseAsync(requestData);
|
|
@@ -7012,14 +7195,14 @@ authRoutes.post(
|
|
|
7012
7195
|
}
|
|
7013
7196
|
const email = validatedData.email;
|
|
7014
7197
|
const password = validatedData.password;
|
|
7015
|
-
const firstName = validatedData.firstName ||
|
|
7016
|
-
const lastName = validatedData.lastName ||
|
|
7198
|
+
const firstName = validatedData.firstName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("firstName", validatedData);
|
|
7199
|
+
const lastName = validatedData.lastName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("lastName", validatedData);
|
|
7017
7200
|
const normalizedEmail = email.toLowerCase();
|
|
7018
7201
|
const existingUser = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(normalizedEmail).first();
|
|
7019
7202
|
if (existingUser) {
|
|
7020
7203
|
return c.json({ error: "User with this email already exists" }, 400);
|
|
7021
7204
|
}
|
|
7022
|
-
const passwordHash = await
|
|
7205
|
+
const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
|
|
7023
7206
|
const userId = crypto.randomUUID();
|
|
7024
7207
|
const now = /* @__PURE__ */ new Date();
|
|
7025
7208
|
const nowSec = Math.floor(now.getTime() / 1e3);
|
|
@@ -7052,8 +7235,8 @@ authRoutes.post(
|
|
|
7052
7235
|
{ user: { id: userId, email: normalizedEmail, role: "viewer" } },
|
|
7053
7236
|
"fire-and-forget"
|
|
7054
7237
|
);
|
|
7055
|
-
const tokenTtl = await
|
|
7056
|
-
const token = await
|
|
7238
|
+
const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7239
|
+
const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer", c.env.JWT_SECRET, tokenTtl);
|
|
7057
7240
|
cookie.setCookie(c, "auth_token", token, {
|
|
7058
7241
|
httpOnly: true,
|
|
7059
7242
|
secure: true,
|
|
@@ -7085,7 +7268,7 @@ authRoutes.post(
|
|
|
7085
7268
|
);
|
|
7086
7269
|
authRoutes.post(
|
|
7087
7270
|
"/login",
|
|
7088
|
-
|
|
7271
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
|
|
7089
7272
|
async (c) => {
|
|
7090
7273
|
try {
|
|
7091
7274
|
const body = await c.req.json();
|
|
@@ -7095,7 +7278,7 @@ authRoutes.post(
|
|
|
7095
7278
|
}
|
|
7096
7279
|
const { email, password } = validation.data;
|
|
7097
7280
|
const normalizedEmail = email.toLowerCase();
|
|
7098
|
-
const { createAuth } = await import('./config-
|
|
7281
|
+
const { createAuth } = await import('./config-OCH7S4WK.cjs');
|
|
7099
7282
|
const auth = createAuth(c.env);
|
|
7100
7283
|
const baReq = new Request(new URL("/auth/sign-in/email", c.req.url).href, {
|
|
7101
7284
|
method: "POST",
|
|
@@ -7117,6 +7300,20 @@ authRoutes.post(
|
|
|
7117
7300
|
await setCsrfCookie(c);
|
|
7118
7301
|
const baBody = await baRes.json();
|
|
7119
7302
|
const user = baBody.user ?? {};
|
|
7303
|
+
const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7304
|
+
const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(
|
|
7305
|
+
user.id,
|
|
7306
|
+
user.email,
|
|
7307
|
+
user.role ?? "viewer",
|
|
7308
|
+
c.env.JWT_SECRET,
|
|
7309
|
+
tokenTtl
|
|
7310
|
+
);
|
|
7311
|
+
cookie.setCookie(c, "auth_token", token, {
|
|
7312
|
+
httpOnly: true,
|
|
7313
|
+
secure: true,
|
|
7314
|
+
sameSite: "Strict",
|
|
7315
|
+
maxAge: tokenTtl
|
|
7316
|
+
});
|
|
7120
7317
|
return c.json({
|
|
7121
7318
|
user: {
|
|
7122
7319
|
id: user.id,
|
|
@@ -7124,7 +7321,8 @@ authRoutes.post(
|
|
|
7124
7321
|
firstName: user.name?.split(" ")[0] ?? "",
|
|
7125
7322
|
lastName: user.name?.split(" ").slice(1).join(" ") ?? "",
|
|
7126
7323
|
role: user.role ?? "viewer"
|
|
7127
|
-
}
|
|
7324
|
+
},
|
|
7325
|
+
token
|
|
7128
7326
|
});
|
|
7129
7327
|
} catch (error) {
|
|
7130
7328
|
console.error("Login error:", error);
|
|
@@ -7134,7 +7332,7 @@ authRoutes.post(
|
|
|
7134
7332
|
);
|
|
7135
7333
|
authRoutes.post("/logout", async (c) => {
|
|
7136
7334
|
try {
|
|
7137
|
-
const { createAuth } = await import('./config-
|
|
7335
|
+
const { createAuth } = await import('./config-OCH7S4WK.cjs');
|
|
7138
7336
|
const auth = createAuth(c.env);
|
|
7139
7337
|
const baReq = new Request(new URL("/auth/sign-out", c.req.url).href, {
|
|
7140
7338
|
method: "POST",
|
|
@@ -7150,7 +7348,7 @@ authRoutes.post("/logout", async (c) => {
|
|
|
7150
7348
|
});
|
|
7151
7349
|
authRoutes.get("/logout", async (c) => {
|
|
7152
7350
|
try {
|
|
7153
|
-
const { createAuth } = await import('./config-
|
|
7351
|
+
const { createAuth } = await import('./config-OCH7S4WK.cjs');
|
|
7154
7352
|
const auth = createAuth(c.env);
|
|
7155
7353
|
const baReq = new Request(new URL("/auth/sign-out", c.req.url).href, {
|
|
7156
7354
|
method: "POST",
|
|
@@ -7164,7 +7362,7 @@ authRoutes.get("/logout", async (c) => {
|
|
|
7164
7362
|
clearCsrfCookie(c);
|
|
7165
7363
|
return c.redirect("/auth/login?message=You have been logged out successfully");
|
|
7166
7364
|
});
|
|
7167
|
-
authRoutes.get("/me",
|
|
7365
|
+
authRoutes.get("/me", chunk4SHNHNRP_cjs.requireAuth(), async (c) => {
|
|
7168
7366
|
try {
|
|
7169
7367
|
const user = c.get("user");
|
|
7170
7368
|
if (!user) {
|
|
@@ -7184,7 +7382,7 @@ authRoutes.get("/me", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
|
|
|
7184
7382
|
});
|
|
7185
7383
|
authRoutes.post(
|
|
7186
7384
|
"/refresh",
|
|
7187
|
-
|
|
7385
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 60, windowMs: 60 * 1e3, keyPrefix: "refresh" }),
|
|
7188
7386
|
async (c) => {
|
|
7189
7387
|
try {
|
|
7190
7388
|
let token = c.req.header("Authorization")?.replace("Bearer ", "");
|
|
@@ -7193,8 +7391,8 @@ authRoutes.post(
|
|
|
7193
7391
|
return c.json({ error: "Authentication required" }, 401);
|
|
7194
7392
|
}
|
|
7195
7393
|
const db = c.env.DB;
|
|
7196
|
-
const grace = await
|
|
7197
|
-
const payload = await
|
|
7394
|
+
const grace = await chunk4SHNHNRP_cjs.getJwtRefreshGraceSecondsFromDb(db, c.env);
|
|
7395
|
+
const payload = await chunk4SHNHNRP_cjs.AuthManager.verifyToken(token, c.env.JWT_SECRET, grace);
|
|
7198
7396
|
if (!payload) {
|
|
7199
7397
|
return c.json({ error: "Invalid or expired token" }, 401);
|
|
7200
7398
|
}
|
|
@@ -7202,8 +7400,8 @@ authRoutes.post(
|
|
|
7202
7400
|
if (!row || !row.is_active) {
|
|
7203
7401
|
return c.json({ error: "User is not active" }, 401);
|
|
7204
7402
|
}
|
|
7205
|
-
const tokenTtl = await
|
|
7206
|
-
const newToken = await
|
|
7403
|
+
const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(db, c.env);
|
|
7404
|
+
const newToken = await chunk4SHNHNRP_cjs.AuthManager.generateToken(row.id, row.email, row.role, c.env.JWT_SECRET, tokenTtl);
|
|
7207
7405
|
cookie.setCookie(c, "auth_token", newToken, {
|
|
7208
7406
|
httpOnly: true,
|
|
7209
7407
|
secure: true,
|
|
@@ -7223,13 +7421,13 @@ authRoutes.post(
|
|
|
7223
7421
|
);
|
|
7224
7422
|
authRoutes.post(
|
|
7225
7423
|
"/register/form",
|
|
7226
|
-
|
|
7424
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "register" }),
|
|
7227
7425
|
async (c) => {
|
|
7228
7426
|
try {
|
|
7229
7427
|
const db = c.env.DB;
|
|
7230
|
-
const isFirstUser = await
|
|
7428
|
+
const isFirstUser = await chunkXWVDSM2L_cjs.isFirstUserRegistration(db);
|
|
7231
7429
|
if (!isFirstUser) {
|
|
7232
|
-
const registrationEnabled = await
|
|
7430
|
+
const registrationEnabled = await chunkXWVDSM2L_cjs.isRegistrationEnabled(db);
|
|
7233
7431
|
if (!registrationEnabled) {
|
|
7234
7432
|
return c.html(html.html`
|
|
7235
7433
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
|
|
@@ -7247,7 +7445,7 @@ authRoutes.post(
|
|
|
7247
7445
|
};
|
|
7248
7446
|
const normalizedEmail = requestData.email?.toLowerCase();
|
|
7249
7447
|
requestData.email = normalizedEmail;
|
|
7250
|
-
const validationSchema = await
|
|
7448
|
+
const validationSchema = await chunkXWVDSM2L_cjs.authValidationService.buildRegistrationSchema(db);
|
|
7251
7449
|
const validation = await validationSchema.safeParseAsync(requestData);
|
|
7252
7450
|
if (!validation.success) {
|
|
7253
7451
|
return c.html(html.html`
|
|
@@ -7258,8 +7456,8 @@ authRoutes.post(
|
|
|
7258
7456
|
}
|
|
7259
7457
|
const validatedData = validation.data;
|
|
7260
7458
|
const password = validatedData.password;
|
|
7261
|
-
const firstName = validatedData.firstName ||
|
|
7262
|
-
const lastName = validatedData.lastName ||
|
|
7459
|
+
const firstName = validatedData.firstName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("firstName", validatedData);
|
|
7460
|
+
const lastName = validatedData.lastName || chunkXWVDSM2L_cjs.authValidationService.generateDefaultValue("lastName", validatedData);
|
|
7263
7461
|
const existingUser = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(normalizedEmail).first();
|
|
7264
7462
|
if (existingUser) {
|
|
7265
7463
|
return c.html(html.html`
|
|
@@ -7268,7 +7466,7 @@ authRoutes.post(
|
|
|
7268
7466
|
</div>
|
|
7269
7467
|
`);
|
|
7270
7468
|
}
|
|
7271
|
-
const passwordHash = await
|
|
7469
|
+
const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
|
|
7272
7470
|
const role = isFirstUser ? "admin" : "viewer";
|
|
7273
7471
|
const userId = crypto.randomUUID();
|
|
7274
7472
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -7302,7 +7500,7 @@ authRoutes.post(
|
|
|
7302
7500
|
await saveCustomData(db, userId, sanitized);
|
|
7303
7501
|
}
|
|
7304
7502
|
}
|
|
7305
|
-
const rbacService = new
|
|
7503
|
+
const rbacService = new chunkLTZ5WYOK_cjs.RbacService(db);
|
|
7306
7504
|
await rbacService.addUserRoleByName(userId, role);
|
|
7307
7505
|
dispatchHookEvent(
|
|
7308
7506
|
c,
|
|
@@ -7310,8 +7508,8 @@ authRoutes.post(
|
|
|
7310
7508
|
{ user: { id: userId, email: normalizedEmail, role } },
|
|
7311
7509
|
"fire-and-forget"
|
|
7312
7510
|
);
|
|
7313
|
-
const tokenTtl = await
|
|
7314
|
-
const token = await
|
|
7511
|
+
const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7512
|
+
const token = await chunk4SHNHNRP_cjs.AuthManager.generateToken(userId, normalizedEmail, role, c.env.JWT_SECRET, tokenTtl);
|
|
7315
7513
|
cookie.setCookie(c, "auth_token", token, {
|
|
7316
7514
|
httpOnly: true,
|
|
7317
7515
|
secure: false,
|
|
@@ -7343,7 +7541,7 @@ authRoutes.post(
|
|
|
7343
7541
|
);
|
|
7344
7542
|
authRoutes.post(
|
|
7345
7543
|
"/login/form",
|
|
7346
|
-
|
|
7544
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 30, windowMs: 60 * 1e3, keyPrefix: "login" }),
|
|
7347
7545
|
async (c) => {
|
|
7348
7546
|
try {
|
|
7349
7547
|
const formData = await c.req.formData();
|
|
@@ -7357,7 +7555,7 @@ authRoutes.post(
|
|
|
7357
7555
|
</div>
|
|
7358
7556
|
`);
|
|
7359
7557
|
}
|
|
7360
|
-
const { createAuth } = await import('./config-
|
|
7558
|
+
const { createAuth } = await import('./config-OCH7S4WK.cjs');
|
|
7361
7559
|
const auth = createAuth(c.env);
|
|
7362
7560
|
const baReq = new Request(new URL("/auth/sign-in/email", c.req.url).href, {
|
|
7363
7561
|
method: "POST",
|
|
@@ -7381,6 +7579,8 @@ authRoutes.post(
|
|
|
7381
7579
|
}
|
|
7382
7580
|
}
|
|
7383
7581
|
await setCsrfCookie(c);
|
|
7582
|
+
const rawRedirect = c.req.query("redirect");
|
|
7583
|
+
const redirectUrl = rawRedirect && rawRedirect.startsWith("/") ? rawRedirect : "/admin/content";
|
|
7384
7584
|
return c.html(html.html`
|
|
7385
7585
|
<div id="form-response">
|
|
7386
7586
|
<div class="rounded-lg bg-green-100 dark:bg-lime-500/10 p-4 ring-1 ring-green-400 dark:ring-lime-500/20">
|
|
@@ -7393,7 +7593,7 @@ authRoutes.post(
|
|
|
7393
7593
|
</div>
|
|
7394
7594
|
</div>
|
|
7395
7595
|
<script>
|
|
7396
|
-
setTimeout(() => { window.location.href = '
|
|
7596
|
+
setTimeout(() => { window.location.href = '${redirectUrl}'; }, 500);
|
|
7397
7597
|
</script>
|
|
7398
7598
|
</div>
|
|
7399
7599
|
</div>
|
|
@@ -7410,14 +7610,14 @@ authRoutes.post(
|
|
|
7410
7610
|
);
|
|
7411
7611
|
authRoutes.post(
|
|
7412
7612
|
"/seed-admin",
|
|
7413
|
-
|
|
7613
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 10, windowMs: 60 * 1e3, keyPrefix: "seed-admin" }),
|
|
7414
7614
|
async (c) => {
|
|
7415
7615
|
try {
|
|
7416
7616
|
const db = c.env.DB;
|
|
7417
|
-
const rbac = new
|
|
7617
|
+
const rbac = new chunkLTZ5WYOK_cjs.RbacService(db);
|
|
7418
7618
|
const results = [];
|
|
7419
7619
|
const upsertSeedUser = async (opts) => {
|
|
7420
|
-
const passwordHash = await
|
|
7620
|
+
const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(opts.password);
|
|
7421
7621
|
const nowMs = Date.now();
|
|
7422
7622
|
const nowSec = Math.floor(nowMs / 1e3);
|
|
7423
7623
|
const existing = await db.prepare("SELECT id FROM auth_user WHERE email = ?").bind(opts.email).first();
|
|
@@ -7642,7 +7842,7 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
7642
7842
|
if (invitationAge > maxAge) {
|
|
7643
7843
|
return c.json({ error: "Invitation has expired" }, 400);
|
|
7644
7844
|
}
|
|
7645
|
-
const passwordHash = await
|
|
7845
|
+
const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
|
|
7646
7846
|
const updateStmt = db.prepare(`
|
|
7647
7847
|
UPDATE auth_user SET
|
|
7648
7848
|
password_hash = ?,
|
|
@@ -7659,8 +7859,8 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
7659
7859
|
Date.now(),
|
|
7660
7860
|
invitedUser.id
|
|
7661
7861
|
).run();
|
|
7662
|
-
const tokenTtl = await
|
|
7663
|
-
const authToken = await
|
|
7862
|
+
const tokenTtl = await chunk4SHNHNRP_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
7863
|
+
const authToken = await chunk4SHNHNRP_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role, c.env.JWT_SECRET, tokenTtl);
|
|
7664
7864
|
cookie.setCookie(c, "auth_token", authToken, {
|
|
7665
7865
|
httpOnly: true,
|
|
7666
7866
|
secure: true,
|
|
@@ -7676,7 +7876,7 @@ authRoutes.post("/accept-invitation", async (c) => {
|
|
|
7676
7876
|
});
|
|
7677
7877
|
authRoutes.post(
|
|
7678
7878
|
"/request-password-reset",
|
|
7679
|
-
|
|
7879
|
+
chunk4SHNHNRP_cjs.rateLimit({ max: 3, windowMs: 15 * 60 * 1e3, keyPrefix: "password-reset" }),
|
|
7680
7880
|
async (c) => {
|
|
7681
7881
|
try {
|
|
7682
7882
|
const formData = await c.req.formData();
|
|
@@ -7913,7 +8113,7 @@ authRoutes.post("/reset-password", async (c) => {
|
|
|
7913
8113
|
if (Date.now() > user.password_reset_expires) {
|
|
7914
8114
|
return c.json({ error: "Reset token has expired" }, 400);
|
|
7915
8115
|
}
|
|
7916
|
-
const newPasswordHash = await
|
|
8116
|
+
const newPasswordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
|
|
7917
8117
|
try {
|
|
7918
8118
|
const historyStmt = db.prepare(`
|
|
7919
8119
|
INSERT INTO auth_password_history (id, user_id, password_hash, created_at)
|
|
@@ -8127,7 +8327,7 @@ app.post("/test-seed-defaults", async (c) => {
|
|
|
8127
8327
|
var test_cleanup_default = app;
|
|
8128
8328
|
|
|
8129
8329
|
// src/plugins/available/easy-mdx/index.ts
|
|
8130
|
-
|
|
8330
|
+
chunk5RSB5SEK_cjs.definePlugin({
|
|
8131
8331
|
id: "easy-mdx",
|
|
8132
8332
|
version: "1.0.0",
|
|
8133
8333
|
name: "EasyMDE Markdown Editor",
|
|
@@ -8327,7 +8527,7 @@ function getMDXEditorInitScript(config) {
|
|
|
8327
8527
|
}
|
|
8328
8528
|
|
|
8329
8529
|
// src/plugins/available/tinymce-plugin/index.ts
|
|
8330
|
-
|
|
8530
|
+
chunk5RSB5SEK_cjs.definePlugin({
|
|
8331
8531
|
id: "tinymce-plugin",
|
|
8332
8532
|
version: "1.0.0",
|
|
8333
8533
|
name: "TinyMCE",
|
|
@@ -8597,7 +8797,7 @@ function getQuillCDN(version = "2.0.2") {
|
|
|
8597
8797
|
</style>
|
|
8598
8798
|
`;
|
|
8599
8799
|
}
|
|
8600
|
-
|
|
8800
|
+
chunk5RSB5SEK_cjs.definePlugin({
|
|
8601
8801
|
id: "quill-editor",
|
|
8602
8802
|
version: "1.0.0",
|
|
8603
8803
|
name: "Quill Editor",
|
|
@@ -8609,7 +8809,7 @@ chunkXW56B23A_cjs.definePlugin({
|
|
|
8609
8809
|
});
|
|
8610
8810
|
|
|
8611
8811
|
// src/templates/pages/admin-content-form.template.ts
|
|
8612
|
-
|
|
8812
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
8613
8813
|
function renderContentFormPage(data, opts) {
|
|
8614
8814
|
const isEdit = data.isEdit || !!data.id;
|
|
8615
8815
|
const title = isEdit ? `Edit: ${data.title || "Content"}` : `New ${data.collection.display_name}`;
|
|
@@ -8691,8 +8891,8 @@ function renderContentFormPage(data, opts) {
|
|
|
8691
8891
|
<!-- Form Content -->
|
|
8692
8892
|
<div class="px-6 py-6">
|
|
8693
8893
|
<div id="form-messages">
|
|
8694
|
-
${data.error ?
|
|
8695
|
-
${data.success ?
|
|
8894
|
+
${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
8895
|
+
${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
8696
8896
|
</div>
|
|
8697
8897
|
|
|
8698
8898
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
@@ -8928,7 +9128,7 @@ function renderContentFormPage(data, opts) {
|
|
|
8928
9128
|
</div>
|
|
8929
9129
|
|
|
8930
9130
|
<!-- Confirmation Dialogs -->
|
|
8931
|
-
${
|
|
9131
|
+
${chunkPXNTCCPE_cjs.renderConfirmationDialog({
|
|
8932
9132
|
id: "duplicate-content-confirm",
|
|
8933
9133
|
title: "Duplicate Content",
|
|
8934
9134
|
message: "Create a copy of this content?",
|
|
@@ -8939,7 +9139,7 @@ function renderContentFormPage(data, opts) {
|
|
|
8939
9139
|
onConfirm: "performDuplicateContent()"
|
|
8940
9140
|
})}
|
|
8941
9141
|
|
|
8942
|
-
${
|
|
9142
|
+
${chunkPXNTCCPE_cjs.renderConfirmationDialog({
|
|
8943
9143
|
id: "delete-content-confirm",
|
|
8944
9144
|
title: "Delete Content",
|
|
8945
9145
|
message: "Are you sure you want to delete this content? This action cannot be undone.",
|
|
@@ -8950,7 +9150,7 @@ function renderContentFormPage(data, opts) {
|
|
|
8950
9150
|
onConfirm: `performDeleteContent('${data.id}')`
|
|
8951
9151
|
})}
|
|
8952
9152
|
|
|
8953
|
-
${
|
|
9153
|
+
${chunkPXNTCCPE_cjs.renderConfirmationDialog({
|
|
8954
9154
|
id: "delete-repeater-item-confirm",
|
|
8955
9155
|
title: "Delete Item",
|
|
8956
9156
|
message: "Are you sure you want to delete this item? This action cannot be undone.",
|
|
@@ -8961,7 +9161,7 @@ function renderContentFormPage(data, opts) {
|
|
|
8961
9161
|
onConfirm: "performRepeaterDelete()"
|
|
8962
9162
|
})}
|
|
8963
9163
|
|
|
8964
|
-
${
|
|
9164
|
+
${chunkPXNTCCPE_cjs.renderConfirmationDialog({
|
|
8965
9165
|
id: "delete-block-confirm",
|
|
8966
9166
|
title: "Delete Block",
|
|
8967
9167
|
message: "Are you sure you want to delete this block? This action cannot be undone.",
|
|
@@ -8972,7 +9172,7 @@ function renderContentFormPage(data, opts) {
|
|
|
8972
9172
|
onConfirm: "performRepeaterDelete()"
|
|
8973
9173
|
})}
|
|
8974
9174
|
|
|
8975
|
-
${
|
|
9175
|
+
${chunkPXNTCCPE_cjs.getConfirmationDialogScript()}
|
|
8976
9176
|
|
|
8977
9177
|
${data.lexicalEnabled ? getLexicalStyles() : "<!-- Lexical plugin not active -->"}
|
|
8978
9178
|
|
|
@@ -10058,11 +10258,11 @@ function renderContentFormPage(data, opts) {
|
|
|
10058
10258
|
content: pageContent,
|
|
10059
10259
|
version: data.version
|
|
10060
10260
|
};
|
|
10061
|
-
return
|
|
10261
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
10062
10262
|
}
|
|
10063
10263
|
|
|
10064
10264
|
// src/templates/pages/admin-content-list.template.ts
|
|
10065
|
-
|
|
10265
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
10066
10266
|
function renderContentListPage(data) {
|
|
10067
10267
|
const urlParams = new URLSearchParams();
|
|
10068
10268
|
if (data.modelName && data.modelName !== "all") urlParams.set("model", data.modelName);
|
|
@@ -10496,8 +10696,8 @@ function renderContentListPage(data) {
|
|
|
10496
10696
|
|
|
10497
10697
|
<!-- Content List -->
|
|
10498
10698
|
<div id="content-list">
|
|
10499
|
-
${
|
|
10500
|
-
${
|
|
10699
|
+
${chunkPXNTCCPE_cjs.renderTable(tableData)}
|
|
10700
|
+
${chunkPXNTCCPE_cjs.renderPagination(paginationData)}
|
|
10501
10701
|
</div>
|
|
10502
10702
|
|
|
10503
10703
|
</div>
|
|
@@ -10707,7 +10907,7 @@ function renderContentListPage(data) {
|
|
|
10707
10907
|
</script>
|
|
10708
10908
|
|
|
10709
10909
|
<!-- Confirmation Dialog for Bulk Actions -->
|
|
10710
|
-
${
|
|
10910
|
+
${chunkPXNTCCPE_cjs.renderConfirmationDialog({
|
|
10711
10911
|
id: "bulk-action-confirm",
|
|
10712
10912
|
title: "Confirm Bulk Action",
|
|
10713
10913
|
message: "Are you sure you want to perform this action? This operation will affect multiple items.",
|
|
@@ -10719,7 +10919,7 @@ function renderContentListPage(data) {
|
|
|
10719
10919
|
})}
|
|
10720
10920
|
|
|
10721
10921
|
<!-- Confirmation Dialog Script -->
|
|
10722
|
-
${
|
|
10922
|
+
${chunkPXNTCCPE_cjs.getConfirmationDialogScript()}
|
|
10723
10923
|
|
|
10724
10924
|
<!-- Advanced Search Modal -->
|
|
10725
10925
|
<div id="advancedSearchModal" class="hidden fixed inset-0 z-50 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
|
|
@@ -11016,7 +11216,7 @@ function renderContentListPage(data) {
|
|
|
11016
11216
|
version: data.version,
|
|
11017
11217
|
content: pageContent
|
|
11018
11218
|
};
|
|
11019
|
-
return
|
|
11219
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
11020
11220
|
}
|
|
11021
11221
|
|
|
11022
11222
|
// src/routes/admin-content-field-types.ts
|
|
@@ -11171,7 +11371,7 @@ function extractFieldData(fields, formData, options = {}) {
|
|
|
11171
11371
|
}
|
|
11172
11372
|
return { data, errors };
|
|
11173
11373
|
}
|
|
11174
|
-
adminContentRoutes.use("*",
|
|
11374
|
+
adminContentRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
11175
11375
|
async function getCollectionFields(db, collectionId) {
|
|
11176
11376
|
console.log(`[getCollectionFields] Loading fields for collection: ${collectionId}`);
|
|
11177
11377
|
const collectionStmt = db.prepare("SELECT schema, queryable_fields FROM document_types WHERE id = ?");
|
|
@@ -11198,7 +11398,7 @@ async function getCollectionFields(db, collectionId) {
|
|
|
11198
11398
|
};
|
|
11199
11399
|
});
|
|
11200
11400
|
}
|
|
11201
|
-
const codeCollections2 = await
|
|
11401
|
+
const codeCollections2 = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
|
|
11202
11402
|
const codeMatch = codeCollections2.find((c) => c.name === collectionId);
|
|
11203
11403
|
if (codeMatch && codeMatch.schema?.properties) {
|
|
11204
11404
|
console.log(`[getCollectionFields] DB doc type has no properties \u2014 using code collection schema`);
|
|
@@ -11230,7 +11430,7 @@ async function getCollectionFields(db, collectionId) {
|
|
|
11230
11430
|
}
|
|
11231
11431
|
}
|
|
11232
11432
|
console.log(`[getCollectionFields] Not in database, checking code collections`);
|
|
11233
|
-
const codeCollections = await
|
|
11433
|
+
const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
|
|
11234
11434
|
console.log(`[getCollectionFields] Found ${codeCollections.length} code collections`);
|
|
11235
11435
|
const codeCollection = codeCollections.find((c) => c.name === collectionId);
|
|
11236
11436
|
if (codeCollection && codeCollection.schema) {
|
|
@@ -11266,7 +11466,7 @@ async function getCollectionFields(db, collectionId) {
|
|
|
11266
11466
|
}
|
|
11267
11467
|
async function getCollection(db, collectionId) {
|
|
11268
11468
|
console.log(`[getCollection] Loading collection by ID: ${collectionId}`);
|
|
11269
|
-
const cache =
|
|
11469
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.collection);
|
|
11270
11470
|
return cache.getOrSet(
|
|
11271
11471
|
cache.generateKey("collection", collectionId),
|
|
11272
11472
|
async () => {
|
|
@@ -11284,7 +11484,7 @@ async function getCollection(db, collectionId) {
|
|
|
11284
11484
|
};
|
|
11285
11485
|
}
|
|
11286
11486
|
console.log(`[getCollection] Not in database, checking code collections`);
|
|
11287
|
-
const codeCollections = await
|
|
11487
|
+
const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
|
|
11288
11488
|
const codeCollection = codeCollections.find((c) => c.name === collectionId);
|
|
11289
11489
|
if (codeCollection) {
|
|
11290
11490
|
console.log(`[getCollection] Found code collection: ${collectionId}`);
|
|
@@ -11303,7 +11503,7 @@ async function getCollection(db, collectionId) {
|
|
|
11303
11503
|
}
|
|
11304
11504
|
async function getDocBackingType(db, collectionName) {
|
|
11305
11505
|
if (!collectionName) return null;
|
|
11306
|
-
const dt = await new
|
|
11506
|
+
const dt = await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db).findById(collectionName);
|
|
11307
11507
|
return dt && dt.isActive ? dt : null;
|
|
11308
11508
|
}
|
|
11309
11509
|
async function getCollectionByName(db, name) {
|
|
@@ -11320,7 +11520,7 @@ async function getCollectionByName(db, name) {
|
|
|
11320
11520
|
};
|
|
11321
11521
|
}
|
|
11322
11522
|
console.log(`[getCollectionByName] Not in database, checking code collections`);
|
|
11323
|
-
const codeCollections = await
|
|
11523
|
+
const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
|
|
11324
11524
|
const codeCollection = codeCollections.find((c) => c.name === name);
|
|
11325
11525
|
if (codeCollection) {
|
|
11326
11526
|
console.log(`[getCollectionByName] Found code collection: ${name}`);
|
|
@@ -11336,7 +11536,7 @@ async function getCollectionByName(db, name) {
|
|
|
11336
11536
|
return null;
|
|
11337
11537
|
}
|
|
11338
11538
|
async function loadContentEditorFlags(db) {
|
|
11339
|
-
const flags = { workflowEnabled: await
|
|
11539
|
+
const flags = { workflowEnabled: await chunk4SHNHNRP_cjs.isPluginActive(db, "workflow") };
|
|
11340
11540
|
const editors = [
|
|
11341
11541
|
["tinymce-plugin", "tinymce"],
|
|
11342
11542
|
["quill-editor", "quill"],
|
|
@@ -11344,10 +11544,10 @@ async function loadContentEditorFlags(db) {
|
|
|
11344
11544
|
["lexical-editor", "lexical"]
|
|
11345
11545
|
];
|
|
11346
11546
|
for (const [plugin, key] of editors) {
|
|
11347
|
-
const enabled = await
|
|
11547
|
+
const enabled = await chunk4SHNHNRP_cjs.isPluginActive(db, plugin);
|
|
11348
11548
|
flags[`${key}Enabled`] = enabled;
|
|
11349
11549
|
if (enabled) {
|
|
11350
|
-
const ps = new
|
|
11550
|
+
const ps = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11351
11551
|
const p = await ps.getPlugin(plugin);
|
|
11352
11552
|
flags[`${key}Settings`] = p?.settings;
|
|
11353
11553
|
}
|
|
@@ -11355,7 +11555,7 @@ async function loadContentEditorFlags(db) {
|
|
|
11355
11555
|
return flags;
|
|
11356
11556
|
}
|
|
11357
11557
|
function makeDocService(db, docType, tenantId) {
|
|
11358
|
-
return new
|
|
11558
|
+
return new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
11359
11559
|
queryableFields: docType.queryableFields ?? [],
|
|
11360
11560
|
typeSchemaVersion: docType.schemaVersion ?? 1,
|
|
11361
11561
|
maxVersionsPerRoot: docType.settings?.maxVersionsPerRoot ?? 50,
|
|
@@ -11383,9 +11583,9 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11383
11583
|
const offset = (page - 1) * limit;
|
|
11384
11584
|
const collectionsStmt = db.prepare("SELECT id, name, display_name FROM document_types WHERE is_active = 1 ORDER BY display_name");
|
|
11385
11585
|
const { results: collectionsResults } = await collectionsStmt.all();
|
|
11386
|
-
const codeCollections = await
|
|
11586
|
+
const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
|
|
11387
11587
|
const codeCollectionMap = new Map(codeCollections.map((c2) => [c2.name, c2]));
|
|
11388
|
-
const docTypeRegistry = new
|
|
11588
|
+
const docTypeRegistry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
11389
11589
|
const docTypes = (await docTypeRegistry.findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth);
|
|
11390
11590
|
const visibleTypeIds = new Set(docTypes.map((dt) => dt.id));
|
|
11391
11591
|
const allCollections = [
|
|
@@ -11397,7 +11597,7 @@ adminContentRoutes.get("/", async (c) => {
|
|
|
11397
11597
|
...allCollections.map((c2) => ({ name: c2.name, displayName: c2.displayName })),
|
|
11398
11598
|
...docTypes.filter((dt) => !collectionNames.has(dt.id)).map((dt) => ({ name: `doc:${dt.id}`, displayName: dt.displayName }))
|
|
11399
11599
|
];
|
|
11400
|
-
const newContentCollections = await
|
|
11600
|
+
const newContentCollections = await chunk5ARIHAGN_cjs.getVisibleCollections(db);
|
|
11401
11601
|
const docBackedCollection = !modelName.startsWith("doc:") && modelName !== "all" ? docTypes.find((dt) => dt.id === modelName) : void 0;
|
|
11402
11602
|
const isDocModel = modelName.startsWith("doc:") || !!docBackedCollection;
|
|
11403
11603
|
if (isDocModel) {
|
|
@@ -11674,9 +11874,9 @@ adminContentRoutes.get("/new", async (c) => {
|
|
|
11674
11874
|
const collectionsStmt = db2.prepare("SELECT id, name, display_name, description FROM document_types WHERE is_active = 1 ORDER BY display_name");
|
|
11675
11875
|
const { results } = await collectionsStmt.all();
|
|
11676
11876
|
const visibleTypeIds = new Set(
|
|
11677
|
-
(await new
|
|
11877
|
+
(await new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db2).findAll()).filter((dt) => !dt.settings?.internal && !dt.isAuth).map((dt) => dt.id)
|
|
11678
11878
|
);
|
|
11679
|
-
const codeCollections = await
|
|
11879
|
+
const codeCollections = await chunk5ARIHAGN_cjs.loadCollectionConfigs();
|
|
11680
11880
|
const dbCollectionNames = new Set((results || []).map((r) => r.name));
|
|
11681
11881
|
const allCollections = [
|
|
11682
11882
|
...codeCollections.filter((c2) => !dbCollectionNames.has(c2.name)).map((c2) => ({
|
|
@@ -11742,32 +11942,32 @@ adminContentRoutes.get("/new", async (c) => {
|
|
|
11742
11942
|
return c.html(renderContentFormPage(formData2));
|
|
11743
11943
|
}
|
|
11744
11944
|
const fields = await getCollectionFields(db, collection.id);
|
|
11745
|
-
const workflowEnabled = await
|
|
11746
|
-
const tinymceEnabled = await
|
|
11945
|
+
const workflowEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "workflow");
|
|
11946
|
+
const tinymceEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin");
|
|
11747
11947
|
let tinymceSettings;
|
|
11748
11948
|
if (tinymceEnabled) {
|
|
11749
|
-
const pluginService = new
|
|
11949
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11750
11950
|
const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
|
|
11751
11951
|
tinymceSettings = tinymcePlugin2?.settings;
|
|
11752
11952
|
}
|
|
11753
|
-
const quillEnabled = await
|
|
11953
|
+
const quillEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor");
|
|
11754
11954
|
let quillSettings;
|
|
11755
11955
|
if (quillEnabled) {
|
|
11756
|
-
const pluginService = new
|
|
11956
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11757
11957
|
const quillPlugin = await pluginService.getPlugin("quill-editor");
|
|
11758
11958
|
quillSettings = quillPlugin?.settings;
|
|
11759
11959
|
}
|
|
11760
|
-
const mdxeditorEnabled = await
|
|
11960
|
+
const mdxeditorEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx");
|
|
11761
11961
|
let mdxeditorSettings;
|
|
11762
11962
|
if (mdxeditorEnabled) {
|
|
11763
|
-
const pluginService = new
|
|
11963
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11764
11964
|
const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
|
|
11765
11965
|
mdxeditorSettings = mdxeditorPlugin?.settings;
|
|
11766
11966
|
}
|
|
11767
|
-
const lexicalEnabled = await
|
|
11967
|
+
const lexicalEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "lexical-editor");
|
|
11768
11968
|
let lexicalSettings;
|
|
11769
11969
|
if (lexicalEnabled) {
|
|
11770
|
-
const pluginService = new
|
|
11970
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11771
11971
|
const lexicalPlugin = await pluginService.getPlugin("lexical-editor");
|
|
11772
11972
|
lexicalSettings = lexicalPlugin?.settings;
|
|
11773
11973
|
}
|
|
@@ -11858,7 +12058,7 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
11858
12058
|
} : void 0
|
|
11859
12059
|
};
|
|
11860
12060
|
return c.html(renderContentFormPage(notFoundData));
|
|
11861
|
-
const cache =
|
|
12061
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
|
|
11862
12062
|
const content = await cache.getOrSet(
|
|
11863
12063
|
cache.generateKey("content", id),
|
|
11864
12064
|
async () => {
|
|
@@ -11895,32 +12095,32 @@ adminContentRoutes.get("/:id/edit", async (c) => {
|
|
|
11895
12095
|
};
|
|
11896
12096
|
const fields = await getCollectionFields(db, content.collection_id);
|
|
11897
12097
|
const contentData = content.data ? JSON.parse(content.data) : {};
|
|
11898
|
-
const workflowEnabled = await
|
|
11899
|
-
const tinymceEnabled = await
|
|
12098
|
+
const workflowEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "workflow");
|
|
12099
|
+
const tinymceEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin");
|
|
11900
12100
|
let tinymceSettings;
|
|
11901
12101
|
if (tinymceEnabled) {
|
|
11902
|
-
const pluginService = new
|
|
12102
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11903
12103
|
const tinymcePlugin2 = await pluginService.getPlugin("tinymce-plugin");
|
|
11904
12104
|
tinymceSettings = tinymcePlugin2?.settings;
|
|
11905
12105
|
}
|
|
11906
|
-
const quillEnabled = await
|
|
12106
|
+
const quillEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor");
|
|
11907
12107
|
let quillSettings;
|
|
11908
12108
|
if (quillEnabled) {
|
|
11909
|
-
const pluginService = new
|
|
12109
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11910
12110
|
const quillPlugin = await pluginService.getPlugin("quill-editor");
|
|
11911
12111
|
quillSettings = quillPlugin?.settings;
|
|
11912
12112
|
}
|
|
11913
|
-
const mdxeditorEnabled = await
|
|
12113
|
+
const mdxeditorEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx");
|
|
11914
12114
|
let mdxeditorSettings;
|
|
11915
12115
|
if (mdxeditorEnabled) {
|
|
11916
|
-
const pluginService = new
|
|
12116
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11917
12117
|
const mdxeditorPlugin = await pluginService.getPlugin("easy-mdx");
|
|
11918
12118
|
mdxeditorSettings = mdxeditorPlugin?.settings;
|
|
11919
12119
|
}
|
|
11920
|
-
const lexicalEnabled = await
|
|
12120
|
+
const lexicalEnabled = await chunk4SHNHNRP_cjs.isPluginActive(db, "lexical-editor");
|
|
11921
12121
|
let lexicalSettings;
|
|
11922
12122
|
if (lexicalEnabled) {
|
|
11923
|
-
const pluginService = new
|
|
12123
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
11924
12124
|
const lexicalPlugin = await pluginService.getPlugin("lexical-editor");
|
|
11925
12125
|
lexicalSettings = lexicalPlugin?.settings;
|
|
11926
12126
|
}
|
|
@@ -12041,7 +12241,7 @@ adminContentRoutes.post("/", async (c) => {
|
|
|
12041
12241
|
data,
|
|
12042
12242
|
publishOnCreate: status === "published"
|
|
12043
12243
|
}), user?.userId);
|
|
12044
|
-
const cache2 =
|
|
12244
|
+
const cache2 = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
|
|
12045
12245
|
await cache2.invalidate(`content:list:${collectionId}:*`);
|
|
12046
12246
|
const redirectUrl2 = `/admin/content/${doc.rootId}/edit?success=Content created successfully!`;
|
|
12047
12247
|
return c.req.header("HX-Request") === "true" ? c.text("", 200, { "HX-Redirect": redirectUrl2 }) : c.redirect(redirectUrl2);
|
|
@@ -12071,7 +12271,7 @@ adminContentRoutes.post("/", async (c) => {
|
|
|
12071
12271
|
now,
|
|
12072
12272
|
now
|
|
12073
12273
|
).run();
|
|
12074
|
-
const cache =
|
|
12274
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
|
|
12075
12275
|
await cache.invalidate(`content:list:${collectionId}:*`);
|
|
12076
12276
|
const versionStmt = db.prepare(`
|
|
12077
12277
|
INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)
|
|
@@ -12160,7 +12360,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
12160
12360
|
const pub = await db.prepare("SELECT id FROM documents WHERE root_id = ? AND is_published = 1 AND tenant_id = ?").bind(id, tenantId).first();
|
|
12161
12361
|
if (status2 === "published") await svc.publish(newDraft.id, user?.userId);
|
|
12162
12362
|
else if (pub) await svc.unpublish(pub.id);
|
|
12163
|
-
await
|
|
12363
|
+
await chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content).invalidate(`content:list:*`);
|
|
12164
12364
|
const redirectUrl2 = `/admin/content/${id}/edit?success=Content updated successfully!`;
|
|
12165
12365
|
return c.req.header("HX-Request") === "true" ? c.text("", 200, { "HX-Redirect": redirectUrl2 }) : c.redirect(redirectUrl2);
|
|
12166
12366
|
}
|
|
@@ -12241,7 +12441,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
12241
12441
|
now,
|
|
12242
12442
|
id
|
|
12243
12443
|
).run();
|
|
12244
|
-
const cache =
|
|
12444
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
|
|
12245
12445
|
await cache.delete(cache.generateKey("content", id));
|
|
12246
12446
|
await cache.invalidate(`content:list:${existingContent.collection_id}:*`);
|
|
12247
12447
|
const existingData = JSON.parse(existingContent.data || "{}");
|
|
@@ -12293,7 +12493,7 @@ adminContentRoutes.put("/:id", async (c) => {
|
|
|
12293
12493
|
`);
|
|
12294
12494
|
}
|
|
12295
12495
|
});
|
|
12296
|
-
adminContentRoutes.post("/preview",
|
|
12496
|
+
adminContentRoutes.post("/preview", chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
12297
12497
|
try {
|
|
12298
12498
|
const formData = await c.req.formData();
|
|
12299
12499
|
const collectionId = formData.get("collection_id");
|
|
@@ -12548,12 +12748,12 @@ adminContentRoutes.post("/bulk-action", async (c) => {
|
|
|
12548
12748
|
}
|
|
12549
12749
|
}
|
|
12550
12750
|
}
|
|
12551
|
-
const cache =
|
|
12751
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
|
|
12552
12752
|
for (const contentId of ids) {
|
|
12553
12753
|
await cache.delete(cache.generateKey("content", contentId));
|
|
12554
12754
|
}
|
|
12555
12755
|
await cache.invalidate("content:list:*");
|
|
12556
|
-
const apiCache =
|
|
12756
|
+
const apiCache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.api);
|
|
12557
12757
|
await apiCache.invalidate("content-filtered:*");
|
|
12558
12758
|
await apiCache.invalidate("collection-content-filtered:*");
|
|
12559
12759
|
return c.json({ success: true, count: ids.length });
|
|
@@ -12572,7 +12772,7 @@ adminContentRoutes.delete("/:id", async (c) => {
|
|
|
12572
12772
|
if (docDel && await getDocBackingType(db, docDel.type_id)) {
|
|
12573
12773
|
const now2 = Math.floor(Date.now() / 1e3);
|
|
12574
12774
|
await db.prepare("UPDATE documents SET deleted_at = ?, updated_at = ? WHERE root_id = ? AND tenant_id = ?").bind(now2, now2, id, tenantId).run();
|
|
12575
|
-
await
|
|
12775
|
+
await chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content).invalidate("content:list:*");
|
|
12576
12776
|
return c.html(`
|
|
12577
12777
|
<div id="content-list" hx-get="/admin/content?model=${docDel.type_id}" hx-trigger="load" hx-swap="outerHTML">
|
|
12578
12778
|
<div class="flex items-center justify-center p-8"><span class="text-zinc-500">Deleting\u2026</span></div>
|
|
@@ -12592,7 +12792,7 @@ adminContentRoutes.delete("/:id", async (c) => {
|
|
|
12592
12792
|
WHERE id = ?
|
|
12593
12793
|
`);
|
|
12594
12794
|
await deleteStmt.bind(now, id).run();
|
|
12595
|
-
const cache =
|
|
12795
|
+
const cache = chunk36Z3AKX3_cjs.getCacheService(chunk36Z3AKX3_cjs.CACHE_CONFIGS.content);
|
|
12596
12796
|
await cache.delete(cache.generateKey("content", id));
|
|
12597
12797
|
await cache.invalidate("content:list:*");
|
|
12598
12798
|
return c.html(`
|
|
@@ -12612,7 +12812,7 @@ adminContentRoutes.delete("/:id", async (c) => {
|
|
|
12612
12812
|
return c.json({ success: false, error: "Failed to delete content" }, 500);
|
|
12613
12813
|
}
|
|
12614
12814
|
});
|
|
12615
|
-
adminContentRoutes.get("/:id/version/:version/preview",
|
|
12815
|
+
adminContentRoutes.get("/:id/version/:version/preview", chunk4SHNHNRP_cjs.requireRole(["admin", "editor", "author"]), async (c) => {
|
|
12616
12816
|
try {
|
|
12617
12817
|
const id = c.req.param("id");
|
|
12618
12818
|
const version = parseInt(c.req.param("version") || "0");
|
|
@@ -12708,9 +12908,9 @@ function parseDocFormData(formData, queryableFields = []) {
|
|
|
12708
12908
|
return { title, slug, data };
|
|
12709
12909
|
}
|
|
12710
12910
|
async function getDocService(db, typeId, tenantId) {
|
|
12711
|
-
const registry = new
|
|
12911
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
12712
12912
|
const docType = await registry.findById(typeId);
|
|
12713
|
-
const svc = new
|
|
12913
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
12714
12914
|
queryableFields: docType?.queryableFields ?? [],
|
|
12715
12915
|
typeSchemaVersion: docType?.schemaVersion ?? 1,
|
|
12716
12916
|
maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50,
|
|
@@ -12721,10 +12921,10 @@ async function getDocService(db, typeId, tenantId) {
|
|
|
12721
12921
|
}
|
|
12722
12922
|
adminContentRoutes.get("/documents/:typeId/new", async (c) => {
|
|
12723
12923
|
const { typeId } = c.req.param();
|
|
12724
|
-
const registry = new
|
|
12924
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(c.env.DB);
|
|
12725
12925
|
const docType = await registry.findById(typeId);
|
|
12726
12926
|
if (!docType) return c.html("<p>Unknown document type.</p>", 404);
|
|
12727
|
-
return c.html(
|
|
12927
|
+
return c.html(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c) }));
|
|
12728
12928
|
});
|
|
12729
12929
|
adminContentRoutes.post("/documents/:typeId/new", async (c) => {
|
|
12730
12930
|
const { typeId } = c.req.param();
|
|
@@ -12746,17 +12946,17 @@ adminContentRoutes.post("/documents/:typeId/new", async (c) => {
|
|
|
12746
12946
|
}), user?.userId);
|
|
12747
12947
|
return c.redirect(`/admin/content/documents/${typeId}/${doc.rootId}/edit?message=Created+successfully`);
|
|
12748
12948
|
} catch (err) {
|
|
12749
|
-
const registry = new
|
|
12949
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(c.env.DB);
|
|
12750
12950
|
const docType = await registry.findById(typeId);
|
|
12751
12951
|
if (!docType) return c.html("<p>Unknown document type.</p>", 404);
|
|
12752
|
-
return c.html(
|
|
12952
|
+
return c.html(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, isEdit: false, user: userCtx(c), message: err?.message ?? "Failed to create", messageType: "error" }));
|
|
12753
12953
|
}
|
|
12754
12954
|
});
|
|
12755
12955
|
adminContentRoutes.get("/documents/:typeId/:rootId/edit", async (c) => {
|
|
12756
12956
|
const { typeId, rootId } = c.req.param();
|
|
12757
12957
|
const db = c.env.DB;
|
|
12758
12958
|
const message = c.req.query("message");
|
|
12759
|
-
const registry = new
|
|
12959
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
12760
12960
|
const docType = await registry.findById(typeId);
|
|
12761
12961
|
if (!docType) return c.html("<p>Unknown document type.</p>", 404);
|
|
12762
12962
|
const tenantId = reqTenant(c);
|
|
@@ -12803,7 +13003,7 @@ adminContentRoutes.get("/documents/:typeId/:rootId/edit", async (c) => {
|
|
|
12803
13003
|
createdAt: draftRow.created_at,
|
|
12804
13004
|
updatedAt: draftRow.updated_at
|
|
12805
13005
|
};
|
|
12806
|
-
return c.html(
|
|
13006
|
+
return c.html(chunkN32OWET6_cjs.renderDocumentFormPage({ docType, doc, publishedDoc, isEdit: true, message, user: userCtx(c), versioningEnabled: docType?.settings?.versioning === true }));
|
|
12807
13007
|
});
|
|
12808
13008
|
adminContentRoutes.post("/documents/:typeId/:rootId", async (c) => {
|
|
12809
13009
|
const { typeId, rootId } = c.req.param();
|
|
@@ -12868,8 +13068,8 @@ adminContentRoutes.post("/documents/:typeId/:documentId/delete", async (c) => {
|
|
|
12868
13068
|
adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
|
|
12869
13069
|
const { typeId, rootId } = c.req.param();
|
|
12870
13070
|
const db = c.env.DB;
|
|
12871
|
-
const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-
|
|
12872
|
-
const registry = new
|
|
13071
|
+
const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-LSZKGA5J.cjs');
|
|
13072
|
+
const registry = new chunk4SHNHNRP_cjs.DocumentTypeRegistry(db);
|
|
12873
13073
|
const docType = await registry.findById(typeId);
|
|
12874
13074
|
if (!docType) return c.html("<div>Unknown type.</div>", 404);
|
|
12875
13075
|
const result = await db.prepare(
|
|
@@ -12889,7 +13089,7 @@ adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
|
|
|
12889
13089
|
var admin_content_default = adminContentRoutes;
|
|
12890
13090
|
|
|
12891
13091
|
// src/templates/pages/admin-profile.template.ts
|
|
12892
|
-
|
|
13092
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
12893
13093
|
function renderAvatarImage(avatarUrl, firstName, lastName) {
|
|
12894
13094
|
return `<div id="avatar-image-container" class="w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden bg-gradient-to-br from-cyan-400 to-purple-400 flex items-center justify-center ring-4 ring-zinc-950/5 dark:ring-white/10">
|
|
12895
13095
|
${avatarUrl ? `<img src="${avatarUrl}" alt="Profile picture" class="w-full h-full object-cover">` : `<span class="text-2xl font-bold text-white">${firstName.charAt(0)}${lastName.charAt(0)}</span>`}
|
|
@@ -12909,8 +13109,8 @@ function renderProfilePage(data) {
|
|
|
12909
13109
|
</div>
|
|
12910
13110
|
|
|
12911
13111
|
<!-- Alert Messages -->
|
|
12912
|
-
${data.error ?
|
|
12913
|
-
${data.success ?
|
|
13112
|
+
${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
13113
|
+
${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
12914
13114
|
|
|
12915
13115
|
<!-- Profile Form -->
|
|
12916
13116
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
@@ -13287,7 +13487,7 @@ function renderProfilePage(data) {
|
|
|
13287
13487
|
version: data.version,
|
|
13288
13488
|
content: pageContent
|
|
13289
13489
|
};
|
|
13290
|
-
return
|
|
13490
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
13291
13491
|
}
|
|
13292
13492
|
|
|
13293
13493
|
// src/templates/pages/admin-activity-logs.template.ts
|
|
@@ -13497,7 +13697,7 @@ function renderActivityLogsPage(data) {
|
|
|
13497
13697
|
user: data.user,
|
|
13498
13698
|
content: pageContent
|
|
13499
13699
|
};
|
|
13500
|
-
return
|
|
13700
|
+
return chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
|
|
13501
13701
|
}
|
|
13502
13702
|
function getActionBadgeClass(action) {
|
|
13503
13703
|
if (action.includes("login") || action.includes("logout")) {
|
|
@@ -13517,7 +13717,7 @@ function formatAction(action) {
|
|
|
13517
13717
|
}
|
|
13518
13718
|
|
|
13519
13719
|
// src/templates/pages/admin-user-edit.template.ts
|
|
13520
|
-
|
|
13720
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
13521
13721
|
|
|
13522
13722
|
// src/templates/components/confirmation-dialog.template.ts
|
|
13523
13723
|
function renderConfirmationDialog2(options) {
|
|
@@ -13713,8 +13913,8 @@ function renderUserEditPage(data) {
|
|
|
13713
13913
|
|
|
13714
13914
|
<!-- Alert Messages -->
|
|
13715
13915
|
<div id="form-messages" class="mb-6 empty:mb-0">
|
|
13716
|
-
${data.error ?
|
|
13717
|
-
${data.success ?
|
|
13916
|
+
${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
13917
|
+
${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
13718
13918
|
</div>
|
|
13719
13919
|
|
|
13720
13920
|
<!-- User Edit Form -->
|
|
@@ -14036,11 +14236,11 @@ function renderUserEditPage(data) {
|
|
|
14036
14236
|
user: data.user,
|
|
14037
14237
|
content: pageContent
|
|
14038
14238
|
};
|
|
14039
|
-
return
|
|
14239
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
14040
14240
|
}
|
|
14041
14241
|
|
|
14042
14242
|
// src/templates/pages/admin-user-new.template.ts
|
|
14043
|
-
|
|
14243
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
14044
14244
|
function renderUserNewPage(data) {
|
|
14045
14245
|
const pageContent = `
|
|
14046
14246
|
<div>
|
|
@@ -14079,8 +14279,8 @@ function renderUserNewPage(data) {
|
|
|
14079
14279
|
|
|
14080
14280
|
<!-- Alert Messages -->
|
|
14081
14281
|
<div id="form-messages">
|
|
14082
|
-
${data.error ?
|
|
14083
|
-
${data.success ?
|
|
14282
|
+
${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
14283
|
+
${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
14084
14284
|
</div>
|
|
14085
14285
|
|
|
14086
14286
|
<!-- User New Form -->
|
|
@@ -14310,11 +14510,11 @@ function renderUserNewPage(data) {
|
|
|
14310
14510
|
user: data.user,
|
|
14311
14511
|
content: pageContent
|
|
14312
14512
|
};
|
|
14313
|
-
return
|
|
14513
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
14314
14514
|
}
|
|
14315
14515
|
|
|
14316
14516
|
// src/templates/pages/admin-users-list.template.ts
|
|
14317
|
-
|
|
14517
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
14318
14518
|
function renderUsersListPage(data) {
|
|
14319
14519
|
const columns = [
|
|
14320
14520
|
{
|
|
@@ -14470,8 +14670,8 @@ function renderUsersListPage(data) {
|
|
|
14470
14670
|
</div>
|
|
14471
14671
|
|
|
14472
14672
|
<!-- Alert Messages -->
|
|
14473
|
-
${data.error ?
|
|
14474
|
-
${data.success ?
|
|
14673
|
+
${data.error ? chunkPXNTCCPE_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
14674
|
+
${data.success ? chunkPXNTCCPE_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
14475
14675
|
|
|
14476
14676
|
<!-- Stats -->
|
|
14477
14677
|
<div class="mb-6">
|
|
@@ -14648,10 +14848,10 @@ function renderUsersListPage(data) {
|
|
|
14648
14848
|
</div>
|
|
14649
14849
|
|
|
14650
14850
|
<!-- Users Table -->
|
|
14651
|
-
${
|
|
14851
|
+
${chunkPXNTCCPE_cjs.renderTable(tableData)}
|
|
14652
14852
|
|
|
14653
14853
|
<!-- Pagination -->
|
|
14654
|
-
${data.pagination ?
|
|
14854
|
+
${data.pagination ? chunkPXNTCCPE_cjs.renderPagination(data.pagination) : ""}
|
|
14655
14855
|
</div>
|
|
14656
14856
|
|
|
14657
14857
|
<script>
|
|
@@ -14722,7 +14922,7 @@ function renderUsersListPage(data) {
|
|
|
14722
14922
|
version: data.version,
|
|
14723
14923
|
content: pageContent
|
|
14724
14924
|
};
|
|
14725
|
-
return
|
|
14925
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
14726
14926
|
}
|
|
14727
14927
|
|
|
14728
14928
|
// src/plugins/core-plugins/multi-tenant-plugin/services/tenant-service.ts
|
|
@@ -14741,6 +14941,7 @@ var TenantService = class {
|
|
|
14741
14941
|
constructor(db) {
|
|
14742
14942
|
this.db = db;
|
|
14743
14943
|
}
|
|
14944
|
+
db;
|
|
14744
14945
|
async listTenants() {
|
|
14745
14946
|
const { results } = await this.db.prepare(`
|
|
14746
14947
|
SELECT * FROM auth_tenant
|
|
@@ -14801,7 +15002,7 @@ var TenantService = class {
|
|
|
14801
15002
|
SET name = ?, domain = ?, status = ?, notes = ?, updated_at = ?
|
|
14802
15003
|
WHERE slug = ?
|
|
14803
15004
|
`).bind(name, domain, status, notes, now, slug).run();
|
|
14804
|
-
|
|
15005
|
+
chunk5ARIHAGN_cjs.invalidateTenantCache();
|
|
14805
15006
|
const updated = await this.getTenantBySlug(slug);
|
|
14806
15007
|
if (!updated) throw new Error("Tenant not found");
|
|
14807
15008
|
return updated;
|
|
@@ -14819,7 +15020,7 @@ var TenantService = class {
|
|
|
14819
15020
|
throw new Error(`Tenant '${slug}' still owns ${docCount} document(s). Delete or migrate its content first.`);
|
|
14820
15021
|
}
|
|
14821
15022
|
await this.db.prepare(`DELETE FROM auth_tenant WHERE slug = ?`).bind(slug).run();
|
|
14822
|
-
|
|
15023
|
+
chunk5ARIHAGN_cjs.invalidateTenantCache();
|
|
14823
15024
|
}
|
|
14824
15025
|
// ─── Membership (auth_tenant_member) ───────────────────────────────────────
|
|
14825
15026
|
// Tenant resolution and the admin switcher are gated on membership: an authed user may only
|
|
@@ -15063,7 +15264,7 @@ var TenantService = class {
|
|
|
15063
15264
|
INSERT INTO auth_tenant (id, name, slug, status, domain, notes, metadata, created_at, updated_at)
|
|
15064
15265
|
VALUES (?, ?, ?, 'active', ?, ?, '{}', ?, ?)
|
|
15065
15266
|
`).bind(id, input.name, input.slug, input.domain, input.notes, now, now).run();
|
|
15066
|
-
|
|
15267
|
+
chunk5ARIHAGN_cjs.invalidateTenantCache();
|
|
15067
15268
|
const created = await this.getTenantBySlug(input.slug);
|
|
15068
15269
|
if (!created) throw new Error("Failed to create tenant");
|
|
15069
15270
|
return created;
|
|
@@ -15087,14 +15288,14 @@ function mapRowToTenant(row) {
|
|
|
15087
15288
|
|
|
15088
15289
|
// src/routes/admin-users.ts
|
|
15089
15290
|
var userRoutes = new hono.Hono();
|
|
15090
|
-
userRoutes.use("*",
|
|
15091
|
-
userRoutes.use("/users/*",
|
|
15092
|
-
userRoutes.use("/users",
|
|
15093
|
-
userRoutes.use("/invite-user",
|
|
15094
|
-
userRoutes.use("/resend-invitation/*",
|
|
15095
|
-
userRoutes.use("/cancel-invitation/*",
|
|
15096
|
-
userRoutes.use("/activity-logs",
|
|
15097
|
-
userRoutes.use("/activity-logs/*",
|
|
15291
|
+
userRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
15292
|
+
userRoutes.use("/users/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15293
|
+
userRoutes.use("/users", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15294
|
+
userRoutes.use("/invite-user", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15295
|
+
userRoutes.use("/resend-invitation/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15296
|
+
userRoutes.use("/cancel-invitation/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15297
|
+
userRoutes.use("/activity-logs", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15298
|
+
userRoutes.use("/activity-logs/*", chunk4SHNHNRP_cjs.requireRole(["admin"]));
|
|
15098
15299
|
userRoutes.get("/", (c) => {
|
|
15099
15300
|
return c.redirect("/admin/dashboard");
|
|
15100
15301
|
});
|
|
@@ -15205,7 +15406,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15205
15406
|
const language = formData.get("language")?.toString() || "en";
|
|
15206
15407
|
const emailNotifications = formData.get("email_notifications") === "1";
|
|
15207
15408
|
if (!firstName || !lastName || !email) {
|
|
15208
|
-
return c.html(
|
|
15409
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15209
15410
|
type: "error",
|
|
15210
15411
|
message: "First name, last name, and email are required.",
|
|
15211
15412
|
dismissible: true
|
|
@@ -15213,7 +15414,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15213
15414
|
}
|
|
15214
15415
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
15215
15416
|
if (!emailRegex.test(email)) {
|
|
15216
|
-
return c.html(
|
|
15417
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15217
15418
|
type: "error",
|
|
15218
15419
|
message: "Please enter a valid email address.",
|
|
15219
15420
|
dismissible: true
|
|
@@ -15225,7 +15426,7 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15225
15426
|
`);
|
|
15226
15427
|
const existingUser = await checkStmt.bind(email, user.userId).first();
|
|
15227
15428
|
if (existingUser) {
|
|
15228
|
-
return c.html(
|
|
15429
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15229
15430
|
type: "error",
|
|
15230
15431
|
message: "Email is already taken by another user.",
|
|
15231
15432
|
dismissible: true
|
|
@@ -15257,11 +15458,11 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15257
15458
|
const validation = validateCustomData(sanitized, profileConfig);
|
|
15258
15459
|
if (!validation.valid) {
|
|
15259
15460
|
const errorMessages = Object.values(validation.errors).join(", ");
|
|
15260
|
-
return c.html(
|
|
15461
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
|
|
15261
15462
|
}
|
|
15262
15463
|
await saveCustomData(db, user.userId, sanitized);
|
|
15263
15464
|
}
|
|
15264
|
-
await
|
|
15465
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15265
15466
|
db,
|
|
15266
15467
|
user.userId,
|
|
15267
15468
|
"profile.update",
|
|
@@ -15271,14 +15472,14 @@ userRoutes.put("/profile", async (c) => {
|
|
|
15271
15472
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15272
15473
|
c.req.header("user-agent")
|
|
15273
15474
|
);
|
|
15274
|
-
return c.html(
|
|
15475
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15275
15476
|
type: "success",
|
|
15276
15477
|
message: "Profile updated successfully!",
|
|
15277
15478
|
dismissible: true
|
|
15278
15479
|
}));
|
|
15279
15480
|
} catch (error) {
|
|
15280
15481
|
console.error("Profile update error:", error);
|
|
15281
|
-
return c.html(
|
|
15482
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15282
15483
|
type: "error",
|
|
15283
15484
|
message: "Failed to update profile. Please try again.",
|
|
15284
15485
|
dismissible: true
|
|
@@ -15292,7 +15493,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15292
15493
|
const formData = await c.req.formData();
|
|
15293
15494
|
const avatarFile = formData.get("avatar");
|
|
15294
15495
|
if (!avatarFile || typeof avatarFile === "string" || !avatarFile.name) {
|
|
15295
|
-
return c.html(
|
|
15496
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15296
15497
|
type: "error",
|
|
15297
15498
|
message: "Please select an image file.",
|
|
15298
15499
|
dismissible: true
|
|
@@ -15300,7 +15501,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15300
15501
|
}
|
|
15301
15502
|
const allowedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
15302
15503
|
if (!allowedTypes.includes(avatarFile.type)) {
|
|
15303
|
-
return c.html(
|
|
15504
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15304
15505
|
type: "error",
|
|
15305
15506
|
message: "Please upload a valid image file (JPEG, PNG, GIF, or WebP).",
|
|
15306
15507
|
dismissible: true
|
|
@@ -15308,7 +15509,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15308
15509
|
}
|
|
15309
15510
|
const maxSize = 5 * 1024 * 1024;
|
|
15310
15511
|
if (avatarFile.size > maxSize) {
|
|
15311
|
-
return c.html(
|
|
15512
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15312
15513
|
type: "error",
|
|
15313
15514
|
message: "Image file must be smaller than 5MB.",
|
|
15314
15515
|
dismissible: true
|
|
@@ -15324,7 +15525,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15324
15525
|
SELECT first_name, last_name FROM auth_user WHERE id = ?
|
|
15325
15526
|
`);
|
|
15326
15527
|
const userData = await userStmt.bind(user.userId).first();
|
|
15327
|
-
await
|
|
15528
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15328
15529
|
db,
|
|
15329
15530
|
user.userId,
|
|
15330
15531
|
"profile.avatar_update",
|
|
@@ -15334,7 +15535,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15334
15535
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15335
15536
|
c.req.header("user-agent")
|
|
15336
15537
|
);
|
|
15337
|
-
const alertHtml =
|
|
15538
|
+
const alertHtml = chunkN32OWET6_cjs.renderAlert({
|
|
15338
15539
|
type: "success",
|
|
15339
15540
|
message: "Profile picture updated successfully!",
|
|
15340
15541
|
dismissible: true
|
|
@@ -15348,7 +15549,7 @@ userRoutes.post("/profile/avatar", async (c) => {
|
|
|
15348
15549
|
return c.html(alertHtml + avatarImageWithOob);
|
|
15349
15550
|
} catch (error) {
|
|
15350
15551
|
console.error("Avatar upload error:", error);
|
|
15351
|
-
return c.html(
|
|
15552
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15352
15553
|
type: "error",
|
|
15353
15554
|
message: "Failed to upload profile picture. Please try again.",
|
|
15354
15555
|
dismissible: true
|
|
@@ -15364,21 +15565,21 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15364
15565
|
const newPassword = formData.get("new_password")?.toString() || "";
|
|
15365
15566
|
const confirmPassword = formData.get("confirm_password")?.toString() || "";
|
|
15366
15567
|
if (!currentPassword || !newPassword || !confirmPassword) {
|
|
15367
|
-
return c.html(
|
|
15568
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15368
15569
|
type: "error",
|
|
15369
15570
|
message: "All password fields are required.",
|
|
15370
15571
|
dismissible: true
|
|
15371
15572
|
}));
|
|
15372
15573
|
}
|
|
15373
15574
|
if (newPassword !== confirmPassword) {
|
|
15374
|
-
return c.html(
|
|
15575
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15375
15576
|
type: "error",
|
|
15376
15577
|
message: "New passwords do not match.",
|
|
15377
15578
|
dismissible: true
|
|
15378
15579
|
}));
|
|
15379
15580
|
}
|
|
15380
15581
|
if (newPassword.length < 8) {
|
|
15381
|
-
return c.html(
|
|
15582
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15382
15583
|
type: "error",
|
|
15383
15584
|
message: "New password must be at least 8 characters long.",
|
|
15384
15585
|
dismissible: true
|
|
@@ -15389,21 +15590,21 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15389
15590
|
`);
|
|
15390
15591
|
const userData = await userStmt.bind(user.userId).first();
|
|
15391
15592
|
if (!userData) {
|
|
15392
|
-
return c.html(
|
|
15593
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15393
15594
|
type: "error",
|
|
15394
15595
|
message: "User not found.",
|
|
15395
15596
|
dismissible: true
|
|
15396
15597
|
}));
|
|
15397
15598
|
}
|
|
15398
|
-
const validPassword = await
|
|
15599
|
+
const validPassword = await chunk4SHNHNRP_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
|
|
15399
15600
|
if (!validPassword) {
|
|
15400
|
-
return c.html(
|
|
15601
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15401
15602
|
type: "error",
|
|
15402
15603
|
message: "Current password is incorrect.",
|
|
15403
15604
|
dismissible: true
|
|
15404
15605
|
}));
|
|
15405
15606
|
}
|
|
15406
|
-
const newPasswordHash = await
|
|
15607
|
+
const newPasswordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(newPassword);
|
|
15407
15608
|
const historyStmt = db.prepare(`
|
|
15408
15609
|
INSERT INTO auth_password_history (id, user_id, password_hash, created_at)
|
|
15409
15610
|
VALUES (?, ?, ?, ?)
|
|
@@ -15419,7 +15620,7 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15419
15620
|
WHERE id = ?
|
|
15420
15621
|
`);
|
|
15421
15622
|
await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
|
|
15422
|
-
await
|
|
15623
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15423
15624
|
db,
|
|
15424
15625
|
user.userId,
|
|
15425
15626
|
"profile.password_change",
|
|
@@ -15429,14 +15630,14 @@ userRoutes.post("/profile/password", async (c) => {
|
|
|
15429
15630
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15430
15631
|
c.req.header("user-agent")
|
|
15431
15632
|
);
|
|
15432
|
-
return c.html(
|
|
15633
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15433
15634
|
type: "success",
|
|
15434
15635
|
message: "Password updated successfully!",
|
|
15435
15636
|
dismissible: true
|
|
15436
15637
|
}));
|
|
15437
15638
|
} catch (error) {
|
|
15438
15639
|
console.error("Password change error:", error);
|
|
15439
|
-
return c.html(
|
|
15640
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15440
15641
|
type: "error",
|
|
15441
15642
|
message: "Failed to update password. Please try again.",
|
|
15442
15643
|
dismissible: true
|
|
@@ -15486,7 +15687,7 @@ userRoutes.get("/users", async (c) => {
|
|
|
15486
15687
|
`);
|
|
15487
15688
|
const countResult = await countStmt.bind(...params).first();
|
|
15488
15689
|
const totalUsers = countResult?.total || 0;
|
|
15489
|
-
await
|
|
15690
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15490
15691
|
db,
|
|
15491
15692
|
user.userId,
|
|
15492
15693
|
"users.list_view",
|
|
@@ -15557,7 +15758,7 @@ userRoutes.get("/users", async (c) => {
|
|
|
15557
15758
|
if (isApiRequest) {
|
|
15558
15759
|
return c.json({ error: "Failed to load users" }, 500);
|
|
15559
15760
|
}
|
|
15560
|
-
return c.html(
|
|
15761
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15561
15762
|
type: "error",
|
|
15562
15763
|
message: "Failed to load users. Please try again.",
|
|
15563
15764
|
dismissible: true
|
|
@@ -15588,7 +15789,7 @@ userRoutes.get("/users/new", async (c) => {
|
|
|
15588
15789
|
return c.html(renderUserNewPage(pageData));
|
|
15589
15790
|
} catch (error) {
|
|
15590
15791
|
console.error("User new page error:", error);
|
|
15591
|
-
return c.html(
|
|
15792
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15592
15793
|
type: "error",
|
|
15593
15794
|
message: "Failed to load user creation page. Please try again.",
|
|
15594
15795
|
dismissible: true
|
|
@@ -15622,12 +15823,12 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15622
15823
|
const validation = validateCustomData(sanitized, profileConfig);
|
|
15623
15824
|
if (!validation.valid) {
|
|
15624
15825
|
const errorMessages = Object.values(validation.errors).join(", ");
|
|
15625
|
-
return c.html(
|
|
15826
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
|
|
15626
15827
|
}
|
|
15627
15828
|
sanitizedRegistrationCustom = sanitized;
|
|
15628
15829
|
}
|
|
15629
15830
|
if (!firstName || !lastName || !email || !password) {
|
|
15630
|
-
return c.html(
|
|
15831
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15631
15832
|
type: "error",
|
|
15632
15833
|
message: "First name, last name, email, and password are required.",
|
|
15633
15834
|
dismissible: true
|
|
@@ -15635,21 +15836,21 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15635
15836
|
}
|
|
15636
15837
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
15637
15838
|
if (!emailRegex.test(email)) {
|
|
15638
|
-
return c.html(
|
|
15839
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15639
15840
|
type: "error",
|
|
15640
15841
|
message: "Please enter a valid email address.",
|
|
15641
15842
|
dismissible: true
|
|
15642
15843
|
}));
|
|
15643
15844
|
}
|
|
15644
15845
|
if (password.length < 8) {
|
|
15645
|
-
return c.html(
|
|
15846
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15646
15847
|
type: "error",
|
|
15647
15848
|
message: "Password must be at least 8 characters long.",
|
|
15648
15849
|
dismissible: true
|
|
15649
15850
|
}));
|
|
15650
15851
|
}
|
|
15651
15852
|
if (password !== confirmPassword) {
|
|
15652
|
-
return c.html(
|
|
15853
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15653
15854
|
type: "error",
|
|
15654
15855
|
message: "Passwords do not match.",
|
|
15655
15856
|
dismissible: true
|
|
@@ -15661,13 +15862,13 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15661
15862
|
`);
|
|
15662
15863
|
const existingUser = await checkStmt.bind(email).first();
|
|
15663
15864
|
if (existingUser) {
|
|
15664
|
-
return c.html(
|
|
15865
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15665
15866
|
type: "error",
|
|
15666
15867
|
message: "Email is already taken.",
|
|
15667
15868
|
dismissible: true
|
|
15668
15869
|
}));
|
|
15669
15870
|
}
|
|
15670
|
-
const passwordHash = await
|
|
15871
|
+
const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(password);
|
|
15671
15872
|
const userId = crypto.randomUUID();
|
|
15672
15873
|
const createStmt = db.prepare(`
|
|
15673
15874
|
INSERT INTO auth_user (
|
|
@@ -15692,7 +15893,7 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15692
15893
|
if (sanitizedRegistrationCustom !== null && Object.keys(sanitizedRegistrationCustom).length > 0) {
|
|
15693
15894
|
await writeProfileData(db, userId, { custom: sanitizedRegistrationCustom }, user.userId);
|
|
15694
15895
|
}
|
|
15695
|
-
await
|
|
15896
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15696
15897
|
db,
|
|
15697
15898
|
user.userId,
|
|
15698
15899
|
"user!.create",
|
|
@@ -15706,7 +15907,7 @@ userRoutes.post("/users/new", async (c) => {
|
|
|
15706
15907
|
return c.body(null, 200);
|
|
15707
15908
|
} catch (error) {
|
|
15708
15909
|
console.error("User creation error:", error);
|
|
15709
|
-
return c.html(
|
|
15910
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15710
15911
|
type: "error",
|
|
15711
15912
|
message: "Failed to create user!. Please try again.",
|
|
15712
15913
|
dismissible: true
|
|
@@ -15731,7 +15932,7 @@ userRoutes.get("/users/:id", async (c) => {
|
|
|
15731
15932
|
if (!userRecord) {
|
|
15732
15933
|
return c.json({ error: "User not found" }, 404);
|
|
15733
15934
|
}
|
|
15734
|
-
await
|
|
15935
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15735
15936
|
db,
|
|
15736
15937
|
user.userId,
|
|
15737
15938
|
"user!.view",
|
|
@@ -15776,7 +15977,7 @@ userRoutes.get("/users/:id/edit", async (c) => {
|
|
|
15776
15977
|
`);
|
|
15777
15978
|
const userToEdit = await userStmt.bind(userId).first();
|
|
15778
15979
|
if (!userToEdit) {
|
|
15779
|
-
return c.html(
|
|
15980
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15780
15981
|
type: "error",
|
|
15781
15982
|
message: "User not found",
|
|
15782
15983
|
dismissible: true
|
|
@@ -15846,7 +16047,7 @@ userRoutes.get("/users/:id/edit", async (c) => {
|
|
|
15846
16047
|
return c.html(renderUserEditPage(pageData));
|
|
15847
16048
|
} catch (error) {
|
|
15848
16049
|
console.error("User edit page error:", error);
|
|
15849
|
-
return c.html(
|
|
16050
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15850
16051
|
type: "error",
|
|
15851
16052
|
message: "Failed to load user. Please try again.",
|
|
15852
16053
|
dismissible: true
|
|
@@ -15879,12 +16080,12 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15879
16080
|
const validation = validateCustomData(sanitized, profileConfig);
|
|
15880
16081
|
if (!validation.valid) {
|
|
15881
16082
|
const errorMessages = Object.values(validation.errors).join(", ");
|
|
15882
|
-
return c.html(
|
|
16083
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({ type: "error", message: errorMessages, dismissible: true }), 400);
|
|
15883
16084
|
}
|
|
15884
16085
|
sanitizedCustom = sanitized;
|
|
15885
16086
|
}
|
|
15886
16087
|
if (!email) {
|
|
15887
|
-
return c.html(
|
|
16088
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15888
16089
|
type: "error",
|
|
15889
16090
|
message: "Email is required.",
|
|
15890
16091
|
dismissible: true
|
|
@@ -15892,7 +16093,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15892
16093
|
}
|
|
15893
16094
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
15894
16095
|
if (!emailRegex.test(email)) {
|
|
15895
|
-
return c.html(
|
|
16096
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15896
16097
|
type: "error",
|
|
15897
16098
|
message: "Please enter a valid email address.",
|
|
15898
16099
|
dismissible: true
|
|
@@ -15900,14 +16101,14 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15900
16101
|
}
|
|
15901
16102
|
if (newPassword) {
|
|
15902
16103
|
if (newPassword.length < 8) {
|
|
15903
|
-
return c.html(
|
|
16104
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15904
16105
|
type: "error",
|
|
15905
16106
|
message: "Password must be at least 8 characters long.",
|
|
15906
16107
|
dismissible: true
|
|
15907
16108
|
}));
|
|
15908
16109
|
}
|
|
15909
16110
|
if (newPassword !== confirmPassword) {
|
|
15910
|
-
return c.html(
|
|
16111
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15911
16112
|
type: "error",
|
|
15912
16113
|
message: "Passwords do not match.",
|
|
15913
16114
|
dismissible: true
|
|
@@ -15920,7 +16121,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15920
16121
|
`);
|
|
15921
16122
|
const existingUser = await checkStmt.bind(email, userId).first();
|
|
15922
16123
|
if (existingUser) {
|
|
15923
|
-
return c.html(
|
|
16124
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15924
16125
|
type: "error",
|
|
15925
16126
|
message: "Email is already taken by another user.",
|
|
15926
16127
|
dismissible: true
|
|
@@ -15945,7 +16146,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15945
16146
|
userId
|
|
15946
16147
|
).run();
|
|
15947
16148
|
if (newPassword) {
|
|
15948
|
-
const passwordHash = await
|
|
16149
|
+
const passwordHash = await chunk4SHNHNRP_cjs.AuthManager.hashPassword(newPassword);
|
|
15949
16150
|
const updatePasswordStmt = db.prepare(`
|
|
15950
16151
|
UPDATE auth_user SET password_hash = ?, updated_at = ? WHERE id = ?
|
|
15951
16152
|
`);
|
|
@@ -15958,7 +16159,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15958
16159
|
...sanitizedCustom !== null ? { custom: sanitizedCustom } : {}
|
|
15959
16160
|
}, user.userId);
|
|
15960
16161
|
}
|
|
15961
|
-
await
|
|
16162
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
15962
16163
|
db,
|
|
15963
16164
|
user.userId,
|
|
15964
16165
|
"user.update",
|
|
@@ -15968,7 +16169,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15968
16169
|
c.req.header("x-forwarded-for") || c.req.header("cf-connecting-ip"),
|
|
15969
16170
|
c.req.header("user-agent")
|
|
15970
16171
|
);
|
|
15971
|
-
return c.html(
|
|
16172
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15972
16173
|
type: "success",
|
|
15973
16174
|
message: "User updated successfully!",
|
|
15974
16175
|
dismissible: true,
|
|
@@ -15976,7 +16177,7 @@ userRoutes.put("/users/:id", async (c) => {
|
|
|
15976
16177
|
}));
|
|
15977
16178
|
} catch (error) {
|
|
15978
16179
|
console.error("User update error:", error);
|
|
15979
|
-
return c.html(
|
|
16180
|
+
return c.html(chunkN32OWET6_cjs.renderAlert({
|
|
15980
16181
|
type: "error",
|
|
15981
16182
|
message: "Failed to update user. Please try again.",
|
|
15982
16183
|
dismissible: true
|
|
@@ -16004,7 +16205,7 @@ userRoutes.post("/users/:id/toggle", async (c) => {
|
|
|
16004
16205
|
UPDATE auth_user SET is_active = ?, updated_at = ? WHERE id = ?
|
|
16005
16206
|
`);
|
|
16006
16207
|
await toggleStmt.bind(active ? 1 : 0, Date.now(), userId).run();
|
|
16007
|
-
await
|
|
16208
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
16008
16209
|
db,
|
|
16009
16210
|
user.userId,
|
|
16010
16211
|
active ? "user.activate" : "user.deactivate",
|
|
@@ -16045,7 +16246,7 @@ userRoutes.delete("/users/:id", async (c) => {
|
|
|
16045
16246
|
DELETE FROM auth_user WHERE id = ?
|
|
16046
16247
|
`);
|
|
16047
16248
|
await deleteStmt.bind(userId).run();
|
|
16048
|
-
await
|
|
16249
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
16049
16250
|
db,
|
|
16050
16251
|
user.userId,
|
|
16051
16252
|
"user!.hard_delete",
|
|
@@ -16064,7 +16265,7 @@ userRoutes.delete("/users/:id", async (c) => {
|
|
|
16064
16265
|
UPDATE auth_user SET is_active = 0, updated_at = ? WHERE id = ?
|
|
16065
16266
|
`);
|
|
16066
16267
|
await deleteStmt.bind(Date.now(), userId).run();
|
|
16067
|
-
await
|
|
16268
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
16068
16269
|
db,
|
|
16069
16270
|
user.userId,
|
|
16070
16271
|
"user!.soft_delete",
|
|
@@ -16130,7 +16331,7 @@ userRoutes.post("/invite-user", async (c) => {
|
|
|
16130
16331
|
Date.now(),
|
|
16131
16332
|
Date.now()
|
|
16132
16333
|
).run();
|
|
16133
|
-
await
|
|
16334
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
16134
16335
|
db,
|
|
16135
16336
|
user.userId,
|
|
16136
16337
|
"user!.invite_sent",
|
|
@@ -16187,7 +16388,7 @@ userRoutes.post("/resend-invitation/:id", async (c) => {
|
|
|
16187
16388
|
Date.now(),
|
|
16188
16389
|
userId
|
|
16189
16390
|
).run();
|
|
16190
|
-
await
|
|
16391
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
16191
16392
|
db,
|
|
16192
16393
|
user.userId,
|
|
16193
16394
|
"user!.invitation_resent",
|
|
@@ -16223,7 +16424,7 @@ userRoutes.delete("/cancel-invitation/:id", async (c) => {
|
|
|
16223
16424
|
}
|
|
16224
16425
|
const deleteStmt = db.prepare(`DELETE FROM auth_user WHERE id = ?`);
|
|
16225
16426
|
await deleteStmt.bind(userId).run();
|
|
16226
|
-
await
|
|
16427
|
+
await chunk4SHNHNRP_cjs.logActivity(
|
|
16227
16428
|
db,
|
|
16228
16429
|
user.userId,
|
|
16229
16430
|
"user!.invitation_cancelled",
|
|
@@ -16472,7 +16673,7 @@ function getFileIcon(mimeType) {
|
|
|
16472
16673
|
}
|
|
16473
16674
|
|
|
16474
16675
|
// src/templates/pages/admin-media-library.template.ts
|
|
16475
|
-
|
|
16676
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
16476
16677
|
function renderMediaLibraryPage(data) {
|
|
16477
16678
|
const pageContent = `
|
|
16478
16679
|
<div>
|
|
@@ -17407,7 +17608,7 @@ function renderMediaLibraryPage(data) {
|
|
|
17407
17608
|
version: data.version,
|
|
17408
17609
|
content: pageContent
|
|
17409
17610
|
};
|
|
17410
|
-
return
|
|
17611
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
17411
17612
|
}
|
|
17412
17613
|
|
|
17413
17614
|
// src/templates/components/media-file-details.template.ts
|
|
@@ -17604,7 +17805,7 @@ var fileValidationSchema2 = zod.z.object({
|
|
|
17604
17805
|
// 50MB max
|
|
17605
17806
|
});
|
|
17606
17807
|
var adminMediaRoutes = new hono.Hono();
|
|
17607
|
-
adminMediaRoutes.use("*",
|
|
17808
|
+
adminMediaRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
17608
17809
|
adminMediaRoutes.get("/", async (c) => {
|
|
17609
17810
|
try {
|
|
17610
17811
|
const user = c.get("user");
|
|
@@ -17646,7 +17847,7 @@ adminMediaRoutes.get("/selector", async (c) => {
|
|
|
17646
17847
|
const { searchParams } = new URL(c.req.url);
|
|
17647
17848
|
const search = searchParams.get("search") || "";
|
|
17648
17849
|
const db = c.env.DB;
|
|
17649
|
-
const pluginService = new
|
|
17850
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
17650
17851
|
const mediaPlugin = await pluginService.getPlugin("core-media");
|
|
17651
17852
|
if (!mediaPlugin || mediaPlugin.status !== "active") {
|
|
17652
17853
|
return c.html(html.html`
|
|
@@ -18020,7 +18221,7 @@ adminMediaRoutes.put("/:id", async (c) => {
|
|
|
18020
18221
|
`);
|
|
18021
18222
|
}
|
|
18022
18223
|
});
|
|
18023
|
-
adminMediaRoutes.delete("/cleanup",
|
|
18224
|
+
adminMediaRoutes.delete("/cleanup", chunk4SHNHNRP_cjs.requireRole("admin"), async (c) => {
|
|
18024
18225
|
try {
|
|
18025
18226
|
const db = c.env.DB;
|
|
18026
18227
|
const allMediaStmt = db.prepare("SELECT id, r2_key, filename FROM media WHERE deleted_at IS NULL");
|
|
@@ -18278,7 +18479,7 @@ function generateMediaItemHTML(file) {
|
|
|
18278
18479
|
}
|
|
18279
18480
|
|
|
18280
18481
|
// src/templates/pages/admin-plugins-list.template.ts
|
|
18281
|
-
|
|
18482
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
18282
18483
|
function renderPluginsListPage(data) {
|
|
18283
18484
|
const categories = [
|
|
18284
18485
|
{ value: "content", label: "Content Management" },
|
|
@@ -18761,7 +18962,7 @@ function renderPluginsListPage(data) {
|
|
|
18761
18962
|
version: data.version,
|
|
18762
18963
|
content: pageContent
|
|
18763
18964
|
};
|
|
18764
|
-
return
|
|
18965
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
18765
18966
|
}
|
|
18766
18967
|
function renderPluginCard(plugin) {
|
|
18767
18968
|
const statusColors = {
|
|
@@ -19139,6 +19340,8 @@ function escapeHtmlAttr(value) {
|
|
|
19139
19340
|
}
|
|
19140
19341
|
function renderPluginSettingsPage(data) {
|
|
19141
19342
|
const { plugin, activity = [], user } = data;
|
|
19343
|
+
const hasUserSettings = Object.keys(plugin.settings || {}).some((k) => !k.startsWith("_"));
|
|
19344
|
+
const defaultTab = hasUserSettings ? "settings" : "info";
|
|
19142
19345
|
const pageContent = `
|
|
19143
19346
|
<div class="w-full px-4 sm:px-6 lg:px-8 py-6">
|
|
19144
19347
|
<!-- Header with Back Button -->
|
|
@@ -19149,13 +19352,24 @@ function renderPluginSettingsPage(data) {
|
|
|
19149
19352
|
${plugin.description}
|
|
19150
19353
|
</p>
|
|
19151
19354
|
</div>
|
|
19152
|
-
<div class="mt-4 sm:mt-0 sm:ml-16
|
|
19355
|
+
<div class="mt-4 sm:mt-0 sm:ml-16 flex items-center gap-3">
|
|
19153
19356
|
<a href="/admin/plugins" class="inline-flex items-center justify-center rounded-lg bg-white dark:bg-zinc-800 px-3.5 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors shadow-sm">
|
|
19154
19357
|
<svg class="-ml-0.5 mr-1.5 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
19155
19358
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
|
19156
19359
|
</svg>
|
|
19157
19360
|
Back to Plugins
|
|
19158
19361
|
</a>
|
|
19362
|
+
${plugin.settings?._adminPath ? `
|
|
19363
|
+
<a
|
|
19364
|
+
href="${plugin.settings._adminPath}"
|
|
19365
|
+
class="inline-flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-cyan-500 to-purple-600 hover:from-cyan-400 hover:to-purple-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm transition-all duration-200"
|
|
19366
|
+
>
|
|
19367
|
+
<svg class="-ml-0.5 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
19368
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
|
|
19369
|
+
</svg>
|
|
19370
|
+
View Page
|
|
19371
|
+
</a>
|
|
19372
|
+
` : ""}
|
|
19159
19373
|
</div>
|
|
19160
19374
|
</div>
|
|
19161
19375
|
|
|
@@ -19188,23 +19402,25 @@ function renderPluginSettingsPage(data) {
|
|
|
19188
19402
|
<!-- Tabs -->
|
|
19189
19403
|
<div class="mb-6">
|
|
19190
19404
|
<nav class="flex space-x-8" aria-label="Tabs">
|
|
19191
|
-
|
|
19405
|
+
${hasUserSettings ? `
|
|
19406
|
+
<a href="#settings" onclick="showTab('settings')" id="settings-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
|
|
19192
19407
|
Settings
|
|
19193
|
-
</
|
|
19194
|
-
|
|
19195
|
-
|
|
19196
|
-
</button>
|
|
19197
|
-
<button onclick="showTab('info')" id="info-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
|
|
19408
|
+
</a>
|
|
19409
|
+
` : ""}
|
|
19410
|
+
<a href="#info" onclick="showTab('info')" id="info-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
|
|
19198
19411
|
Information
|
|
19199
|
-
</
|
|
19412
|
+
</a>
|
|
19413
|
+
<a href="#activity" onclick="showTab('activity')" id="activity-tab" class="tab-button border-b-2 border-transparent py-2 px-1 text-sm font-medium text-gray-400 hover:text-gray-300">
|
|
19414
|
+
Activity Log
|
|
19415
|
+
</a>
|
|
19200
19416
|
</nav>
|
|
19201
19417
|
</div>
|
|
19202
19418
|
|
|
19203
19419
|
<!-- Tab Content -->
|
|
19204
19420
|
<div id="tab-content">
|
|
19205
19421
|
<!-- Settings Tab -->
|
|
19206
|
-
<div id="settings-content" class="tab-content">
|
|
19207
|
-
${renderSettingsTab(plugin)}
|
|
19422
|
+
<div id="settings-content" class="tab-content hidden">
|
|
19423
|
+
${hasUserSettings ? renderSettingsTab(plugin) : ""}
|
|
19208
19424
|
</div>
|
|
19209
19425
|
|
|
19210
19426
|
<!-- Activity Tab -->
|
|
@@ -19220,27 +19436,42 @@ function renderPluginSettingsPage(data) {
|
|
|
19220
19436
|
</div>
|
|
19221
19437
|
|
|
19222
19438
|
<script>
|
|
19439
|
+
const VALID_TABS = [${hasUserSettings ? "'settings', " : ""}'activity', 'info'];
|
|
19440
|
+
|
|
19223
19441
|
function showTab(tabName) {
|
|
19224
|
-
|
|
19442
|
+
if (!VALID_TABS.includes(tabName)) tabName = '${defaultTab}';
|
|
19443
|
+
|
|
19225
19444
|
document.querySelectorAll('.tab-content').forEach(content => {
|
|
19226
19445
|
content.classList.add('hidden');
|
|
19227
19446
|
});
|
|
19228
|
-
|
|
19229
|
-
// Remove active class from all tabs
|
|
19447
|
+
|
|
19230
19448
|
document.querySelectorAll('.tab-button').forEach(tab => {
|
|
19231
19449
|
tab.classList.remove('active', 'border-blue-400', 'text-blue-400');
|
|
19232
19450
|
tab.classList.add('border-transparent', 'text-gray-400');
|
|
19233
19451
|
});
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
// Add active class to selected tab
|
|
19452
|
+
|
|
19453
|
+
const contentEl = document.getElementById(tabName + '-content');
|
|
19454
|
+
if (contentEl) contentEl.classList.remove('hidden');
|
|
19455
|
+
|
|
19239
19456
|
const activeTab = document.getElementById(tabName + '-tab');
|
|
19240
|
-
activeTab
|
|
19241
|
-
|
|
19457
|
+
if (activeTab) {
|
|
19458
|
+
activeTab.classList.add('active', 'border-blue-400', 'text-blue-400');
|
|
19459
|
+
activeTab.classList.remove('border-transparent', 'text-gray-400');
|
|
19460
|
+
}
|
|
19461
|
+
|
|
19462
|
+
if (window.location.hash !== '#' + tabName) {
|
|
19463
|
+
history.replaceState(null, '', '#' + tabName);
|
|
19464
|
+
}
|
|
19242
19465
|
}
|
|
19243
19466
|
|
|
19467
|
+
function initTabFromHash() {
|
|
19468
|
+
const hash = window.location.hash.replace('#', '');
|
|
19469
|
+
showTab(VALID_TABS.includes(hash) ? hash : '${defaultTab}');
|
|
19470
|
+
}
|
|
19471
|
+
|
|
19472
|
+
window.addEventListener('hashchange', initTabFromHash);
|
|
19473
|
+
initTabFromHash();
|
|
19474
|
+
|
|
19244
19475
|
async function togglePlugin(pluginId, action) {
|
|
19245
19476
|
const button = event.target;
|
|
19246
19477
|
const originalText = button.textContent;
|
|
@@ -19385,7 +19616,7 @@ function renderPluginSettingsPage(data) {
|
|
|
19385
19616
|
user,
|
|
19386
19617
|
content: pageContent
|
|
19387
19618
|
};
|
|
19388
|
-
return
|
|
19619
|
+
return chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
|
|
19389
19620
|
}
|
|
19390
19621
|
function renderStatusBadge(status) {
|
|
19391
19622
|
const statusColors = {
|
|
@@ -19413,6 +19644,7 @@ function renderToggleButton(plugin) {
|
|
|
19413
19644
|
function renderSettingsTab(plugin) {
|
|
19414
19645
|
const settings = plugin.settings || {};
|
|
19415
19646
|
const pluginId = plugin.id || plugin.name;
|
|
19647
|
+
const hasUserKeys = Object.keys(settings).some((k) => !k.startsWith("_"));
|
|
19416
19648
|
const customRenderer = pluginSettingsComponents[pluginId];
|
|
19417
19649
|
if (customRenderer) {
|
|
19418
19650
|
return `
|
|
@@ -19448,9 +19680,9 @@ function renderSettingsTab(plugin) {
|
|
|
19448
19680
|
`}
|
|
19449
19681
|
|
|
19450
19682
|
<form id="settings-form" class="space-y-6">
|
|
19451
|
-
${isAuthPlugin &&
|
|
19683
|
+
${isAuthPlugin && hasUserKeys ? renderAuthSettingsForm(settings) : isTurnstilePlugin && hasUserKeys ? renderTurnstileSettingsForm(settings) : hasUserKeys ? renderSettingsFields(settings) : renderNoSettings(plugin)}
|
|
19452
19684
|
|
|
19453
|
-
${
|
|
19685
|
+
${hasUserKeys ? `
|
|
19454
19686
|
<div class="flex items-center justify-end pt-6 border-t border-white/10">
|
|
19455
19687
|
<button
|
|
19456
19688
|
type="button"
|
|
@@ -19467,7 +19699,7 @@ function renderSettingsTab(plugin) {
|
|
|
19467
19699
|
`;
|
|
19468
19700
|
}
|
|
19469
19701
|
function renderSettingsFields(settings) {
|
|
19470
|
-
return Object.entries(settings).map(([key, value]) => {
|
|
19702
|
+
return Object.entries(settings).filter(([key]) => !key.startsWith("_")).map(([key, value]) => {
|
|
19471
19703
|
const fieldId = `setting_${key}`;
|
|
19472
19704
|
const displayName = key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
|
|
19473
19705
|
if (typeof value === "boolean") {
|
|
@@ -19656,6 +19888,38 @@ function renderActivityTab(activity) {
|
|
|
19656
19888
|
}
|
|
19657
19889
|
function renderInformationTab(plugin) {
|
|
19658
19890
|
return `
|
|
19891
|
+
${plugin.description ? `
|
|
19892
|
+
<!-- About -->
|
|
19893
|
+
<div class="backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6 mb-6">
|
|
19894
|
+
<h2 class="text-xl font-semibold text-white mb-3">About</h2>
|
|
19895
|
+
<p class="text-gray-300 leading-relaxed">${plugin.description}</p>
|
|
19896
|
+
</div>
|
|
19897
|
+
` : ""}
|
|
19898
|
+
|
|
19899
|
+
${(plugin.settings?._routes?.length ?? 0) > 0 ? `
|
|
19900
|
+
<!-- Routes -->
|
|
19901
|
+
<div class="backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6 mb-6">
|
|
19902
|
+
<h2 class="text-xl font-semibold text-white mb-4">Routes</h2>
|
|
19903
|
+
<div class="space-y-2">
|
|
19904
|
+
${plugin.settings._routes.map((r) => {
|
|
19905
|
+
const badge = r.method === "GET" ? "bg-emerald-500/20 text-emerald-300 border border-emerald-500/30" : r.method === "POST" ? "bg-blue-500/20 text-blue-300 border border-blue-500/30" : r.method === "DELETE" ? "bg-red-500/20 text-red-300 border border-red-500/30" : "bg-white/10 text-gray-300 border border-white/20";
|
|
19906
|
+
const pathHtml = r.method === "GET" ? `<a href="${r.path}" class="font-mono text-sm text-blue-400 hover:text-blue-300 hover:underline">${r.path}</a>` : `<span class="font-mono text-sm text-gray-200">${r.path}</span>`;
|
|
19907
|
+
const authBadge = r.requiresAuth ? `<span class="ml-2 text-xs text-amber-400/80">\u{1F512} auth</span>` : "";
|
|
19908
|
+
return `
|
|
19909
|
+
<div class="flex items-start gap-3 py-2 border-b border-white/5 last:border-0">
|
|
19910
|
+
<span class="shrink-0 inline-block px-2 py-0.5 rounded text-xs font-bold ${badge}">${r.method}</span>
|
|
19911
|
+
<div class="min-w-0">
|
|
19912
|
+
<div class="flex items-center gap-1 flex-wrap">
|
|
19913
|
+
${pathHtml}${authBadge}
|
|
19914
|
+
</div>
|
|
19915
|
+
${r.description ? `<p class="text-xs text-gray-400 mt-0.5">${r.description}</p>` : ""}
|
|
19916
|
+
</div>
|
|
19917
|
+
</div>`;
|
|
19918
|
+
}).join("")}
|
|
19919
|
+
</div>
|
|
19920
|
+
</div>
|
|
19921
|
+
` : ""}
|
|
19922
|
+
|
|
19659
19923
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
19660
19924
|
<!-- Plugin Details -->
|
|
19661
19925
|
<div class="backdrop-blur-md bg-black/20 rounded-xl border border-white/10 shadow-xl p-6">
|
|
@@ -20453,8 +20717,8 @@ defineUserProfile({
|
|
|
20453
20717
|
|
|
20454
20718
|
// src/routes/admin-plugins.ts
|
|
20455
20719
|
var adminPluginRoutes = new hono.Hono();
|
|
20456
|
-
adminPluginRoutes.use("*",
|
|
20457
|
-
var AVAILABLE_PLUGINS = Object.values(
|
|
20720
|
+
adminPluginRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
20721
|
+
var AVAILABLE_PLUGINS = Object.values(chunk5ARIHAGN_cjs.PLUGIN_REGISTRY).map((p) => ({
|
|
20458
20722
|
id: p.id,
|
|
20459
20723
|
name: p.codeName,
|
|
20460
20724
|
display_name: p.displayName,
|
|
@@ -20474,7 +20738,7 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
20474
20738
|
if (user?.role !== "admin") {
|
|
20475
20739
|
return c.text("Access denied", 403);
|
|
20476
20740
|
}
|
|
20477
|
-
const pluginService = new
|
|
20741
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20478
20742
|
let installedPlugins = [];
|
|
20479
20743
|
let stats = { total: 0, active: 0, inactive: 0, errors: 0, uninstalled: 0 };
|
|
20480
20744
|
try {
|
|
@@ -20546,10 +20810,10 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20546
20810
|
if (user?.role !== "admin") {
|
|
20547
20811
|
return c.redirect("/admin/plugins");
|
|
20548
20812
|
}
|
|
20549
|
-
const pluginService = new
|
|
20813
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20550
20814
|
let plugin = await pluginService.getPlugin(pluginId);
|
|
20551
20815
|
if (!plugin) {
|
|
20552
|
-
const def =
|
|
20816
|
+
const def = chunk5RSB5SEK_cjs.getPluginDefinition(pluginId);
|
|
20553
20817
|
if (!def) return c.text("Plugin not found", 404);
|
|
20554
20818
|
plugin = await pluginService.ensurePlugin(pluginId, {
|
|
20555
20819
|
displayName: def.displayName ?? pluginId,
|
|
@@ -20561,7 +20825,7 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20561
20825
|
const activity = await pluginService.getPluginActivity(pluginId, 20);
|
|
20562
20826
|
let enrichedSettings = plugin.settings || {};
|
|
20563
20827
|
if (pluginId === "otp-login") {
|
|
20564
|
-
const settingsService = new
|
|
20828
|
+
const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
|
|
20565
20829
|
const generalSettings = await settingsService.getGeneralSettings();
|
|
20566
20830
|
const siteName = generalSettings.siteName || "SonicJS";
|
|
20567
20831
|
const emailPlugin = await db.prepare(`
|
|
@@ -20640,14 +20904,14 @@ adminPluginRoutes.get("/:id/configure", async (c) => {
|
|
|
20640
20904
|
const user = c.get("user");
|
|
20641
20905
|
const pluginId = c.req.param("id");
|
|
20642
20906
|
if (user?.role !== "admin") return c.redirect("/admin/plugins");
|
|
20643
|
-
const def =
|
|
20907
|
+
const def = chunk5RSB5SEK_cjs.getPluginDefinition(pluginId);
|
|
20644
20908
|
if (!def?.configSchema) return c.text("No schema-driven settings for this plugin", 404);
|
|
20645
20909
|
const db = c.env.DB;
|
|
20646
|
-
const pluginService = new
|
|
20910
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20647
20911
|
const plugin = await pluginService.getPlugin(pluginId);
|
|
20648
20912
|
const stored = plugin?.settings ?? {};
|
|
20649
|
-
const values =
|
|
20650
|
-
const fieldsHtml =
|
|
20913
|
+
const values = chunk5RSB5SEK_cjs.applySchemaDefaults(def.configSchema, stored);
|
|
20914
|
+
const fieldsHtml = chunk5RSB5SEK_cjs.renderSchemaFields(def.configSchema, values);
|
|
20651
20915
|
const displayName = plugin?.display_name ?? def.displayName ?? def.id;
|
|
20652
20916
|
return c.html(`<!DOCTYPE html>
|
|
20653
20917
|
<html lang="en"><head>
|
|
@@ -20674,19 +20938,21 @@ adminPluginRoutes.post("/:id/configure", async (c) => {
|
|
|
20674
20938
|
const user = c.get("user");
|
|
20675
20939
|
const pluginId = c.req.param("id");
|
|
20676
20940
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
20677
|
-
const def =
|
|
20941
|
+
const def = chunk5RSB5SEK_cjs.getPluginDefinition(pluginId);
|
|
20678
20942
|
if (!def?.configSchema) return c.text("No schema-driven settings for this plugin", 404);
|
|
20679
20943
|
const form = await c.req.formData();
|
|
20680
|
-
const parsed =
|
|
20944
|
+
const parsed = chunk5RSB5SEK_cjs.parseFormDataToSettings(def.configSchema, form);
|
|
20681
20945
|
const db = c.env.DB;
|
|
20682
|
-
const pluginService = new
|
|
20946
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20683
20947
|
await pluginService.ensurePlugin(pluginId, {
|
|
20684
20948
|
displayName: def.displayName ?? pluginId,
|
|
20685
20949
|
version: def.version,
|
|
20686
20950
|
description: def.description,
|
|
20687
20951
|
author: typeof def.author === "object" ? def.author?.name : def.author
|
|
20688
20952
|
});
|
|
20689
|
-
await pluginService.
|
|
20953
|
+
const existingPlugin = await pluginService.getPlugin(pluginId);
|
|
20954
|
+
const existingSettings = existingPlugin?.settings ?? {};
|
|
20955
|
+
await pluginService.updatePluginSettings(pluginId, { ...existingSettings, ...parsed });
|
|
20690
20956
|
return c.redirect(`/admin/plugins/${encodeURIComponent(pluginId)}/configure`);
|
|
20691
20957
|
} catch (error) {
|
|
20692
20958
|
console.error("Error saving schema settings:", error);
|
|
@@ -20701,7 +20967,7 @@ adminPluginRoutes.post("/:id/activate", async (c) => {
|
|
|
20701
20967
|
if (user?.role !== "admin") {
|
|
20702
20968
|
return c.json({ error: "Access denied" }, 403);
|
|
20703
20969
|
}
|
|
20704
|
-
const pluginService = new
|
|
20970
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20705
20971
|
await pluginService.activatePlugin(pluginId);
|
|
20706
20972
|
return c.json({ success: true });
|
|
20707
20973
|
} catch (error) {
|
|
@@ -20718,7 +20984,7 @@ adminPluginRoutes.post("/:id/deactivate", async (c) => {
|
|
|
20718
20984
|
if (user?.role !== "admin") {
|
|
20719
20985
|
return c.json({ error: "Access denied" }, 403);
|
|
20720
20986
|
}
|
|
20721
|
-
const pluginService = new
|
|
20987
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20722
20988
|
await pluginService.deactivatePlugin(pluginId);
|
|
20723
20989
|
return c.json({ success: true });
|
|
20724
20990
|
} catch (error) {
|
|
@@ -20735,8 +21001,8 @@ adminPluginRoutes.post("/install", async (c) => {
|
|
|
20735
21001
|
return c.json({ error: "Access denied" }, 403);
|
|
20736
21002
|
}
|
|
20737
21003
|
const body = await c.req.json();
|
|
20738
|
-
const pluginService = new
|
|
20739
|
-
const registryEntry =
|
|
21004
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
21005
|
+
const registryEntry = chunk5ARIHAGN_cjs.findPluginByCodeName(body.name) || chunk5ARIHAGN_cjs.PLUGIN_REGISTRY[body.name] || chunk5ARIHAGN_cjs.PLUGIN_REGISTRY[body.id];
|
|
20740
21006
|
if (!registryEntry) {
|
|
20741
21007
|
return c.json({ error: "Plugin not found in registry" }, 404);
|
|
20742
21008
|
}
|
|
@@ -20769,7 +21035,7 @@ adminPluginRoutes.post("/:id/uninstall", async (c) => {
|
|
|
20769
21035
|
if (user?.role !== "admin") {
|
|
20770
21036
|
return c.json({ error: "Access denied" }, 403);
|
|
20771
21037
|
}
|
|
20772
|
-
const pluginService = new
|
|
21038
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20773
21039
|
await pluginService.uninstallPlugin(pluginId);
|
|
20774
21040
|
return c.json({ success: true });
|
|
20775
21041
|
} catch (error) {
|
|
@@ -20787,7 +21053,7 @@ adminPluginRoutes.post("/:id/settings", async (c) => {
|
|
|
20787
21053
|
return c.json({ error: "Access denied" }, 403);
|
|
20788
21054
|
}
|
|
20789
21055
|
const settings = await c.req.json();
|
|
20790
|
-
const pluginService = new
|
|
21056
|
+
const pluginService = new chunk5ARIHAGN_cjs.PluginService(db);
|
|
20791
21057
|
await pluginService.updatePluginSettings(pluginId, settings);
|
|
20792
21058
|
if (pluginId === "core-auth") {
|
|
20793
21059
|
try {
|
|
@@ -20820,7 +21086,7 @@ function formatLastUpdated(timestamp) {
|
|
|
20820
21086
|
}
|
|
20821
21087
|
|
|
20822
21088
|
// src/templates/pages/admin-logs-list.template.ts
|
|
20823
|
-
|
|
21089
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
20824
21090
|
function renderLogsListPage(data) {
|
|
20825
21091
|
const { logs, pagination, filters, user } = data;
|
|
20826
21092
|
const content = `
|
|
@@ -21131,7 +21397,7 @@ function renderLogsListPage(data) {
|
|
|
21131
21397
|
user,
|
|
21132
21398
|
content
|
|
21133
21399
|
};
|
|
21134
|
-
return
|
|
21400
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
21135
21401
|
}
|
|
21136
21402
|
function renderLogDetailsPage(data) {
|
|
21137
21403
|
const { log, user } = data;
|
|
@@ -21343,7 +21609,7 @@ function renderLogDetailsPage(data) {
|
|
|
21343
21609
|
</div>
|
|
21344
21610
|
</div>
|
|
21345
21611
|
`;
|
|
21346
|
-
return
|
|
21612
|
+
return chunkPXNTCCPE_cjs.adminLayoutV2({
|
|
21347
21613
|
title: `Log Details - ${log.id}`,
|
|
21348
21614
|
user,
|
|
21349
21615
|
content
|
|
@@ -21586,7 +21852,7 @@ function renderLogConfigPage(data) {
|
|
|
21586
21852
|
|
|
21587
21853
|
<script src="https://unpkg.com/htmx.org@1.9.6"></script>
|
|
21588
21854
|
`;
|
|
21589
|
-
return
|
|
21855
|
+
return chunkPXNTCCPE_cjs.adminLayoutV2({
|
|
21590
21856
|
title: "Log Configuration",
|
|
21591
21857
|
user,
|
|
21592
21858
|
content
|
|
@@ -21595,11 +21861,11 @@ function renderLogConfigPage(data) {
|
|
|
21595
21861
|
|
|
21596
21862
|
// src/routes/admin-logs.ts
|
|
21597
21863
|
var adminLogsRoutes = new hono.Hono();
|
|
21598
|
-
adminLogsRoutes.use("*",
|
|
21864
|
+
adminLogsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
21599
21865
|
adminLogsRoutes.get("/", async (c) => {
|
|
21600
21866
|
try {
|
|
21601
21867
|
const user = c.get("user");
|
|
21602
|
-
const logger =
|
|
21868
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21603
21869
|
const query = c.req.query();
|
|
21604
21870
|
const page = parseInt(query.page || "1");
|
|
21605
21871
|
const limit = parseInt(query.limit || "50");
|
|
@@ -21679,7 +21945,7 @@ adminLogsRoutes.get("/:id", async (c) => {
|
|
|
21679
21945
|
try {
|
|
21680
21946
|
const id = c.req.param("id");
|
|
21681
21947
|
const user = c.get("user");
|
|
21682
|
-
const logger =
|
|
21948
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21683
21949
|
const { logs } = await logger.getLogs({
|
|
21684
21950
|
limit: 1,
|
|
21685
21951
|
offset: 0,
|
|
@@ -21716,7 +21982,7 @@ adminLogsRoutes.get("/:id", async (c) => {
|
|
|
21716
21982
|
adminLogsRoutes.get("/config", async (c) => {
|
|
21717
21983
|
try {
|
|
21718
21984
|
const user = c.get("user");
|
|
21719
|
-
const logger =
|
|
21985
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21720
21986
|
const configs = await logger.getAllConfigs();
|
|
21721
21987
|
const pageData = {
|
|
21722
21988
|
configs,
|
|
@@ -21740,7 +22006,7 @@ adminLogsRoutes.post("/config/:category", async (c) => {
|
|
|
21740
22006
|
const level = formData.get("level");
|
|
21741
22007
|
const retention = parseInt(formData.get("retention"));
|
|
21742
22008
|
const maxSize = parseInt(formData.get("max_size"));
|
|
21743
|
-
const logger =
|
|
22009
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21744
22010
|
await logger.updateConfig(category, {
|
|
21745
22011
|
enabled,
|
|
21746
22012
|
level,
|
|
@@ -21769,7 +22035,7 @@ adminLogsRoutes.get("/export", async (c) => {
|
|
|
21769
22035
|
const category = query.category;
|
|
21770
22036
|
const startDate = query.start_date;
|
|
21771
22037
|
const endDate = query.end_date;
|
|
21772
|
-
const logger =
|
|
22038
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21773
22039
|
const filter = {
|
|
21774
22040
|
limit: 1e4,
|
|
21775
22041
|
// Export up to 10k logs
|
|
@@ -21850,7 +22116,7 @@ adminLogsRoutes.post("/cleanup", async (c) => {
|
|
|
21850
22116
|
error: "Unauthorized. Admin access required."
|
|
21851
22117
|
}, 403);
|
|
21852
22118
|
}
|
|
21853
|
-
const logger =
|
|
22119
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21854
22120
|
await logger.cleanupByRetention();
|
|
21855
22121
|
return c.html(html.html`
|
|
21856
22122
|
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
|
|
@@ -21872,7 +22138,7 @@ adminLogsRoutes.post("/search", async (c) => {
|
|
|
21872
22138
|
const search = formData.get("search");
|
|
21873
22139
|
const level = formData.get("level");
|
|
21874
22140
|
const category = formData.get("category");
|
|
21875
|
-
const logger =
|
|
22141
|
+
const logger = chunk36Z3AKX3_cjs.getLogger(c.env.DB);
|
|
21876
22142
|
const filter = {
|
|
21877
22143
|
limit: 20,
|
|
21878
22144
|
offset: 0,
|
|
@@ -21967,7 +22233,7 @@ adminCheckboxRoutes.get("/", (c) => {
|
|
|
21967
22233
|
role: user.role
|
|
21968
22234
|
} : void 0
|
|
21969
22235
|
};
|
|
21970
|
-
return c.html(
|
|
22236
|
+
return c.html(chunkPXNTCCPE_cjs.renderCheckboxPage(pageData));
|
|
21971
22237
|
});
|
|
21972
22238
|
|
|
21973
22239
|
// src/templates/pages/admin-dashboard.template.ts
|
|
@@ -22039,7 +22305,7 @@ function renderDashboardPage(data) {
|
|
|
22039
22305
|
version: data.version,
|
|
22040
22306
|
content: pageContent
|
|
22041
22307
|
};
|
|
22042
|
-
return
|
|
22308
|
+
return chunkPXNTCCPE_cjs.renderAdminLayout(layoutData);
|
|
22043
22309
|
}
|
|
22044
22310
|
function renderStatsCards(stats) {
|
|
22045
22311
|
const cards = [
|
|
@@ -22587,9 +22853,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
|
|
|
22587
22853
|
}
|
|
22588
22854
|
|
|
22589
22855
|
// src/routes/admin-dashboard.ts
|
|
22590
|
-
var VERSION =
|
|
22856
|
+
var VERSION = chunkAQJEMVAY_cjs.getCoreVersion();
|
|
22591
22857
|
var router = new hono.Hono();
|
|
22592
|
-
router.use("*",
|
|
22858
|
+
router.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
22593
22859
|
router.get("/", async (c) => {
|
|
22594
22860
|
const user = c.get("user");
|
|
22595
22861
|
try {
|
|
@@ -22779,7 +23045,7 @@ router.get("/system-status", async (c) => {
|
|
|
22779
23045
|
});
|
|
22780
23046
|
|
|
22781
23047
|
// src/templates/pages/admin-collections-list.template.ts
|
|
22782
|
-
|
|
23048
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
22783
23049
|
|
|
22784
23050
|
// src/templates/components/table.template.ts
|
|
22785
23051
|
function renderTable2(data) {
|
|
@@ -23261,11 +23527,11 @@ function renderCollectionsListPage(data) {
|
|
|
23261
23527
|
version: data.version,
|
|
23262
23528
|
content: pageContent
|
|
23263
23529
|
};
|
|
23264
|
-
return
|
|
23530
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
23265
23531
|
}
|
|
23266
23532
|
|
|
23267
23533
|
// src/templates/pages/admin-collections-form.template.ts
|
|
23268
|
-
|
|
23534
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
23269
23535
|
function getFieldTypeBadge(fieldType) {
|
|
23270
23536
|
const typeLabels = {
|
|
23271
23537
|
"text": "Text",
|
|
@@ -23438,8 +23704,8 @@ function renderCollectionFormPage(data) {
|
|
|
23438
23704
|
<!-- Form Content -->
|
|
23439
23705
|
<div class="px-6 py-6">
|
|
23440
23706
|
<div id="form-messages"></div>
|
|
23441
|
-
${data.error ?
|
|
23442
|
-
${data.success ?
|
|
23707
|
+
${data.error ? chunkN32OWET6_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
23708
|
+
${data.success ? chunkN32OWET6_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
23443
23709
|
|
|
23444
23710
|
<!-- Form Styling -->
|
|
23445
23711
|
<style>
|
|
@@ -23550,7 +23816,7 @@ function renderCollectionFormPage(data) {
|
|
|
23550
23816
|
}
|
|
23551
23817
|
</style>
|
|
23552
23818
|
|
|
23553
|
-
${
|
|
23819
|
+
${chunkPXNTCCPE_cjs.renderForm(formData)}
|
|
23554
23820
|
|
|
23555
23821
|
${isEdit && data.managed ? `
|
|
23556
23822
|
<!-- Read-Only Fields Display for Managed Collections -->
|
|
@@ -24548,13 +24814,13 @@ function renderCollectionFormPage(data) {
|
|
|
24548
24814
|
version: data.version,
|
|
24549
24815
|
content: pageContent
|
|
24550
24816
|
};
|
|
24551
|
-
return
|
|
24817
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
24552
24818
|
}
|
|
24553
24819
|
|
|
24554
24820
|
// src/routes/admin-collections.ts
|
|
24555
|
-
|
|
24821
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
24556
24822
|
var adminCollectionsRoutes = new hono.Hono();
|
|
24557
|
-
adminCollectionsRoutes.use("*",
|
|
24823
|
+
adminCollectionsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
24558
24824
|
adminCollectionsRoutes.get("/", async (c) => {
|
|
24559
24825
|
try {
|
|
24560
24826
|
const user = c.get("user");
|
|
@@ -24571,7 +24837,7 @@ adminCollectionsRoutes.get("/", async (c) => {
|
|
|
24571
24837
|
results = queryResults.results ?? [];
|
|
24572
24838
|
} catch (e) {
|
|
24573
24839
|
}
|
|
24574
|
-
const codeCollections =
|
|
24840
|
+
const codeCollections = chunk5ARIHAGN_cjs.getCollectionRegistry().list();
|
|
24575
24841
|
const codeCollectionsMap = new Map(
|
|
24576
24842
|
codeCollections.map((cfg) => {
|
|
24577
24843
|
const fieldCount = cfg.schema?.properties ? Object.keys(cfg.schema.properties).length : 0;
|
|
@@ -24585,7 +24851,7 @@ adminCollectionsRoutes.get("/", async (c) => {
|
|
|
24585
24851
|
field_count: fieldCount,
|
|
24586
24852
|
managed: cfg.managed !== false,
|
|
24587
24853
|
source_type: "code",
|
|
24588
|
-
internal:
|
|
24854
|
+
internal: chunk5ARIHAGN_cjs.isCodeCollectionInternal(cfg),
|
|
24589
24855
|
versioning: cfg.versioning === true
|
|
24590
24856
|
}];
|
|
24591
24857
|
})
|
|
@@ -24624,7 +24890,7 @@ adminCollectionsRoutes.get("/", async (c) => {
|
|
|
24624
24890
|
field_count: fieldCount,
|
|
24625
24891
|
managed: false,
|
|
24626
24892
|
source_type: row.source === "code" || row.source === "system" || row.source === "plugin" ? "code" : "user",
|
|
24627
|
-
internal:
|
|
24893
|
+
internal: chunk5ARIHAGN_cjs.isDbDocTypeInternal(row.source),
|
|
24628
24894
|
versioning: dbVersioning
|
|
24629
24895
|
};
|
|
24630
24896
|
});
|
|
@@ -24781,11 +25047,11 @@ export const myPlugin = definePlugin({
|
|
|
24781
25047
|
`;
|
|
24782
25048
|
const u = user;
|
|
24783
25049
|
return c.html(
|
|
24784
|
-
|
|
25050
|
+
chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
24785
25051
|
title: "Add a Collection",
|
|
24786
25052
|
pageTitle: "Add a Collection",
|
|
24787
25053
|
currentPath: "/admin/collections",
|
|
24788
|
-
version:
|
|
25054
|
+
version: chunkAQJEMVAY_cjs.getCoreVersion(),
|
|
24789
25055
|
user: u ? { name: u.email ?? "Admin", email: u.email ?? "", role: u.role ?? "admin" } : void 0,
|
|
24790
25056
|
content
|
|
24791
25057
|
})
|
|
@@ -24802,7 +25068,7 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
24802
25068
|
collection = await stmt.bind(id).first();
|
|
24803
25069
|
} catch {
|
|
24804
25070
|
}
|
|
24805
|
-
const registryRecord =
|
|
25071
|
+
const registryRecord = chunk5ARIHAGN_cjs.getCollectionRegistry().getById(id) ?? chunk5ARIHAGN_cjs.getCollectionRegistry().getByName(id);
|
|
24806
25072
|
if (!collection && !registryRecord) {
|
|
24807
25073
|
const formData2 = {
|
|
24808
25074
|
isEdit: true,
|
|
@@ -24849,9 +25115,9 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
24849
25115
|
isCodeDriven = true;
|
|
24850
25116
|
}
|
|
24851
25117
|
const [tinymceActive, quillActive, mdxeditorActive] = await Promise.all([
|
|
24852
|
-
|
|
24853
|
-
|
|
24854
|
-
|
|
25118
|
+
chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin"),
|
|
25119
|
+
chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor"),
|
|
25120
|
+
chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx")
|
|
24855
25121
|
]);
|
|
24856
25122
|
const displayName = collection?.display_name ?? registryRecord?.displayName ?? id;
|
|
24857
25123
|
const formData = {
|
|
@@ -24871,9 +25137,9 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
24871
25137
|
console.error("Error fetching collection:", error);
|
|
24872
25138
|
const user = c.get("user");
|
|
24873
25139
|
const [tinymceActive, quillActive, mdxeditorActive] = await Promise.all([
|
|
24874
|
-
|
|
24875
|
-
|
|
24876
|
-
|
|
25140
|
+
chunk4SHNHNRP_cjs.isPluginActive(db, "tinymce-plugin"),
|
|
25141
|
+
chunk4SHNHNRP_cjs.isPluginActive(db, "quill-editor"),
|
|
25142
|
+
chunk4SHNHNRP_cjs.isPluginActive(db, "easy-mdx")
|
|
24877
25143
|
]);
|
|
24878
25144
|
const formData = {
|
|
24879
25145
|
isEdit: true,
|
|
@@ -24887,7 +25153,7 @@ adminCollectionsRoutes.get("/:id", async (c) => {
|
|
|
24887
25153
|
});
|
|
24888
25154
|
|
|
24889
25155
|
// src/templates/pages/admin-settings.template.ts
|
|
24890
|
-
|
|
25156
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
24891
25157
|
function renderSettingsPage(data) {
|
|
24892
25158
|
const activeTab = data.activeTab || "general";
|
|
24893
25159
|
const pageContent = `
|
|
@@ -25277,7 +25543,7 @@ function renderSettingsPage(data) {
|
|
|
25277
25543
|
version: data.version,
|
|
25278
25544
|
content: pageContent
|
|
25279
25545
|
};
|
|
25280
|
-
return
|
|
25546
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
25281
25547
|
}
|
|
25282
25548
|
function renderTabButton(tabId, label, iconPath, activeTab) {
|
|
25283
25549
|
const isActive = activeTab === tabId;
|
|
@@ -25822,7 +26088,7 @@ function renderDatabaseToolsSettings(settings) {
|
|
|
25822
26088
|
|
|
25823
26089
|
// src/routes/admin-settings.ts
|
|
25824
26090
|
var adminSettingsRoutes = new hono.Hono();
|
|
25825
|
-
adminSettingsRoutes.use("*",
|
|
26091
|
+
adminSettingsRoutes.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
25826
26092
|
function getMockSettings(user) {
|
|
25827
26093
|
return {
|
|
25828
26094
|
general: {
|
|
@@ -25856,7 +26122,7 @@ adminSettingsRoutes.get("/", (c) => {
|
|
|
25856
26122
|
adminSettingsRoutes.get("/general", async (c) => {
|
|
25857
26123
|
const user = c.get("user");
|
|
25858
26124
|
const db = c.env.DB;
|
|
25859
|
-
const settingsService = new
|
|
26125
|
+
const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
|
|
25860
26126
|
const generalSettings = await settingsService.getGeneralSettings(user?.email);
|
|
25861
26127
|
const mockSettings = getMockSettings(user);
|
|
25862
26128
|
mockSettings.general = generalSettings;
|
|
@@ -25875,7 +26141,7 @@ adminSettingsRoutes.get("/general", async (c) => {
|
|
|
25875
26141
|
adminSettingsRoutes.get("/security", async (c) => {
|
|
25876
26142
|
const user = c.get("user");
|
|
25877
26143
|
const db = c.env.DB;
|
|
25878
|
-
const settingsService = new
|
|
26144
|
+
const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
|
|
25879
26145
|
const persisted = await settingsService.getSecuritySettings();
|
|
25880
26146
|
const mockSettings = getMockSettings(user);
|
|
25881
26147
|
mockSettings.security = {
|
|
@@ -25925,7 +26191,7 @@ adminSettingsRoutes.get("/database-tools", (c) => {
|
|
|
25925
26191
|
adminSettingsRoutes.get("/api/migrations/status", async (c) => {
|
|
25926
26192
|
try {
|
|
25927
26193
|
const db = c.env.DB;
|
|
25928
|
-
const migrationService = new
|
|
26194
|
+
const migrationService = new chunkTQG5FNNR_cjs.MigrationService(db);
|
|
25929
26195
|
const status = await migrationService.getMigrationStatus();
|
|
25930
26196
|
return c.json({
|
|
25931
26197
|
success: true,
|
|
@@ -25965,7 +26231,7 @@ adminSettingsRoutes.post("/api/migrations/run", async (c) => {
|
|
|
25965
26231
|
adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
|
|
25966
26232
|
try {
|
|
25967
26233
|
const db = c.env.DB;
|
|
25968
|
-
const migrationService = new
|
|
26234
|
+
const migrationService = new chunkTQG5FNNR_cjs.MigrationService(db);
|
|
25969
26235
|
const validation = await migrationService.validateSchema();
|
|
25970
26236
|
return c.json({
|
|
25971
26237
|
success: true,
|
|
@@ -26134,7 +26400,7 @@ adminSettingsRoutes.post("/general", async (c) => {
|
|
|
26134
26400
|
}
|
|
26135
26401
|
const formData = await c.req.formData();
|
|
26136
26402
|
const db = c.env.DB;
|
|
26137
|
-
const settingsService = new
|
|
26403
|
+
const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
|
|
26138
26404
|
const settings = {
|
|
26139
26405
|
siteName: formData.get("siteName"),
|
|
26140
26406
|
siteDescription: formData.get("siteDescription"),
|
|
@@ -26180,7 +26446,7 @@ adminSettingsRoutes.post("/security", async (c) => {
|
|
|
26180
26446
|
}
|
|
26181
26447
|
const formData = await c.req.formData();
|
|
26182
26448
|
const db = c.env.DB;
|
|
26183
|
-
const settingsService = new
|
|
26449
|
+
const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
|
|
26184
26450
|
const jwtExpiresInRaw = formData.get("jwtExpiresIn")?.trim() || "";
|
|
26185
26451
|
const graceRaw = formData.get("jwtRefreshGraceSeconds")?.trim() || "";
|
|
26186
26452
|
if (!/^\d+(?:s|m|h|d)?$/i.test(jwtExpiresInRaw)) {
|
|
@@ -26223,7 +26489,7 @@ adminSettingsRoutes.post("/", async (c) => {
|
|
|
26223
26489
|
});
|
|
26224
26490
|
|
|
26225
26491
|
// src/templates/pages/admin-api-reference.template.ts
|
|
26226
|
-
|
|
26492
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
26227
26493
|
function renderAuthBadge(auth) {
|
|
26228
26494
|
if (auth === true) {
|
|
26229
26495
|
return `
|
|
@@ -26364,7 +26630,7 @@ function renderAPIReferencePage(data) {
|
|
|
26364
26630
|
>
|
|
26365
26631
|
<option value="">All Categories</option>
|
|
26366
26632
|
${categories.map((category) => {
|
|
26367
|
-
const info =
|
|
26633
|
+
const info = chunk36Z3AKX3_cjs.CATEGORY_INFO[category];
|
|
26368
26634
|
const title = info ? info.title : category;
|
|
26369
26635
|
return `<option value="${category}">${title}</option>`;
|
|
26370
26636
|
}).join("\n ")}
|
|
@@ -26381,7 +26647,7 @@ function renderAPIReferencePage(data) {
|
|
|
26381
26647
|
<!-- API Categories -->
|
|
26382
26648
|
<div class="space-y-6">
|
|
26383
26649
|
${Object.entries(endpointsByCategory).map(([category, endpoints]) => {
|
|
26384
|
-
const info =
|
|
26650
|
+
const info = chunk36Z3AKX3_cjs.CATEGORY_INFO[category] || { title: category, description: "", icon: "📋" };
|
|
26385
26651
|
return `
|
|
26386
26652
|
<div class="api-category" data-category="${category}">
|
|
26387
26653
|
<div class="rounded-lg bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden">
|
|
@@ -26554,20 +26820,20 @@ function renderAPIReferencePage(data) {
|
|
|
26554
26820
|
version: data.version,
|
|
26555
26821
|
content: pageContent
|
|
26556
26822
|
};
|
|
26557
|
-
return
|
|
26823
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
26558
26824
|
}
|
|
26559
26825
|
|
|
26560
26826
|
// src/routes/admin-api-reference.ts
|
|
26561
|
-
var VERSION2 =
|
|
26827
|
+
var VERSION2 = chunkAQJEMVAY_cjs.getCoreVersion();
|
|
26562
26828
|
var router2 = new hono.Hono();
|
|
26563
|
-
router2.use("*",
|
|
26829
|
+
router2.use("*", chunk4SHNHNRP_cjs.requireAuth());
|
|
26564
26830
|
router2.get("/", async (c) => {
|
|
26565
26831
|
const user = c.get("user");
|
|
26566
26832
|
try {
|
|
26567
|
-
const app2 =
|
|
26568
|
-
const baseEndpoints =
|
|
26833
|
+
const app2 = chunk36Z3AKX3_cjs.getAppInstance();
|
|
26834
|
+
const baseEndpoints = chunk36Z3AKX3_cjs.buildRouteList(app2);
|
|
26569
26835
|
const collectionRoutes = [];
|
|
26570
|
-
const collections =
|
|
26836
|
+
const collections = chunk5ARIHAGN_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal);
|
|
26571
26837
|
const methodOrder = { GET: 0, POST: 1, PUT: 2, PATCH: 3, DELETE: 4 };
|
|
26572
26838
|
for (const col of collections) {
|
|
26573
26839
|
const displayName = col.displayName || col.name;
|
|
@@ -26659,6 +26925,7 @@ exports.api_default = api_default;
|
|
|
26659
26925
|
exports.api_media_default = api_media_default;
|
|
26660
26926
|
exports.api_system_default = api_system_default;
|
|
26661
26927
|
exports.auth_default = auth_default;
|
|
26928
|
+
exports.createDocumentSchema = createDocumentSchema;
|
|
26662
26929
|
exports.createUserProfilesPlugin = createUserProfilesPlugin;
|
|
26663
26930
|
exports.defineUserProfile = defineUserProfile;
|
|
26664
26931
|
exports.denyIfNotAllowed = denyIfNotAllowed;
|
|
@@ -26683,5 +26950,5 @@ exports.setVariablesCache = setVariablesCache;
|
|
|
26683
26950
|
exports.test_cleanup_default = test_cleanup_default;
|
|
26684
26951
|
exports.userProfilesPlugin = userProfilesPlugin;
|
|
26685
26952
|
exports.userRoutes = userRoutes;
|
|
26686
|
-
//# sourceMappingURL=chunk-
|
|
26687
|
-
//# sourceMappingURL=chunk-
|
|
26953
|
+
//# sourceMappingURL=chunk-3E7IROND.cjs.map
|
|
26954
|
+
//# sourceMappingURL=chunk-3E7IROND.cjs.map
|