@sonicjs-cms/core 3.0.0-beta.2 → 3.0.0-beta.21
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-BLMTL57B.js → chunk-3TMTYJAJ.js} +26 -4
- package/dist/chunk-3TMTYJAJ.js.map +1 -0
- package/dist/{chunk-ZGGXCFR6.js → chunk-4LVVMVQI.js} +282 -4
- package/dist/chunk-4LVVMVQI.js.map +1 -0
- package/dist/{chunk-RZ6H7OZK.js → chunk-4UYJPHSV.js} +87 -12
- package/dist/chunk-4UYJPHSV.js.map +1 -0
- package/dist/{chunk-NLJVSER2.js → chunk-5U75XP74.js} +3 -2
- package/dist/chunk-5U75XP74.js.map +1 -0
- package/dist/{chunk-H2AXVCLS.cjs → chunk-5UXU3LP4.cjs} +141 -74
- package/dist/chunk-5UXU3LP4.cjs.map +1 -0
- package/dist/{chunk-3TB6AT6X.js → chunk-5V62WT6M.js} +35 -4
- package/dist/chunk-5V62WT6M.js.map +1 -0
- package/dist/{chunk-6OUHGKFD.js → chunk-7OTOXWEB.js} +3 -3
- package/dist/{chunk-6OUHGKFD.js.map → chunk-7OTOXWEB.js.map} +1 -1
- package/dist/{chunk-VXE42MYF.cjs → chunk-7RUW244J.cjs} +710 -434
- package/dist/chunk-7RUW244J.cjs.map +1 -0
- package/dist/{chunk-XW56B23A.cjs → chunk-A4KUJ3LD.cjs} +4 -4
- package/dist/{chunk-XW56B23A.cjs.map → chunk-A4KUJ3LD.cjs.map} +1 -1
- package/dist/{chunk-LRZIAW7U.cjs → chunk-AOUVUF32.cjs} +3 -3
- package/dist/chunk-AOUVUF32.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-AAWNRBRB.cjs → chunk-FCLKX2OS.cjs} +95 -20
- package/dist/chunk-FCLKX2OS.cjs.map +1 -0
- package/dist/{chunk-YHSQVQXX.js → chunk-GICS5AIO.js} +135 -68
- package/dist/chunk-GICS5AIO.js.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-NMPEMSU4.js → chunk-JEX3UPZL.js} +3 -3
- package/dist/chunk-JEX3UPZL.js.map +1 -0
- 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-QAYFOER6.cjs → chunk-KVBHB7QP.cjs} +285 -3
- package/dist/chunk-KVBHB7QP.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-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-DSA4UX5B.cjs → chunk-OJC4G5JE.cjs} +3 -2
- package/dist/chunk-OJC4G5JE.cjs.map +1 -0
- 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-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-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-HIKBY7MS.cjs → chunk-XWVDSM2L.cjs} +12 -3
- package/dist/chunk-XWVDSM2L.cjs.map +1 -0
- package/dist/{chunk-VD2EA3WT.js → chunk-ZP77LTN4.js} +343 -68
- package/dist/chunk-ZP77LTN4.js.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 +1119 -440
- 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 +803 -137
- 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-HMX5SPN2.js +4 -0
- package/dist/{migrations-WCAVBD7C.js.map → migrations-HMX5SPN2.js.map} +1 -1
- package/dist/migrations-V73ARYV5.cjs +13 -0
- package/dist/{migrations-NJJWQUKK.cjs.map → migrations-V73ARYV5.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
package/dist/index.cjs
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
require('./chunk-
|
|
6
|
-
require('./chunk-
|
|
7
|
-
var
|
|
3
|
+
var chunkGMMCCIQO_cjs = require('./chunk-GMMCCIQO.cjs');
|
|
4
|
+
var chunk7RUW244J_cjs = require('./chunk-7RUW244J.cjs');
|
|
5
|
+
require('./chunk-XWVDSM2L.cjs');
|
|
6
|
+
require('./chunk-N32OWET6.cjs');
|
|
7
|
+
var chunk36Z3AKX3_cjs = require('./chunk-36Z3AKX3.cjs');
|
|
8
8
|
var chunkYA3TJ65D_cjs = require('./chunk-YA3TJ65D.cjs');
|
|
9
9
|
var chunkYP7GW2G5_cjs = require('./chunk-YP7GW2G5.cjs');
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
var
|
|
19
|
-
var
|
|
10
|
+
var chunkFCLKX2OS_cjs = require('./chunk-FCLKX2OS.cjs');
|
|
11
|
+
var chunkLTZ5WYOK_cjs = require('./chunk-LTZ5WYOK.cjs');
|
|
12
|
+
var chunkKIGVVO6N_cjs = require('./chunk-KIGVVO6N.cjs');
|
|
13
|
+
var chunkKVBHB7QP_cjs = require('./chunk-KVBHB7QP.cjs');
|
|
14
|
+
var chunkOJC4G5JE_cjs = require('./chunk-OJC4G5JE.cjs');
|
|
15
|
+
var chunkCRGUD4KC_cjs = require('./chunk-CRGUD4KC.cjs');
|
|
16
|
+
var chunkPXNTCCPE_cjs = require('./chunk-PXNTCCPE.cjs');
|
|
17
|
+
var chunkK623Q6WD_cjs = require('./chunk-K623Q6WD.cjs');
|
|
18
|
+
var chunk5UXU3LP4_cjs = require('./chunk-5UXU3LP4.cjs');
|
|
19
|
+
var chunkA4KUJ3LD_cjs = require('./chunk-A4KUJ3LD.cjs');
|
|
20
20
|
var chunkJ6JTWD2A_cjs = require('./chunk-J6JTWD2A.cjs');
|
|
21
21
|
var chunkIXUHXTHW_cjs = require('./chunk-IXUHXTHW.cjs');
|
|
22
|
-
require('./chunk-P3XDZL6Q.cjs');
|
|
23
22
|
var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
|
|
24
|
-
|
|
23
|
+
require('./chunk-P3XDZL6Q.cjs');
|
|
24
|
+
var chunkAOUVUF32_cjs = require('./chunk-AOUVUF32.cjs');
|
|
25
25
|
var chunkMNWKYY5E_cjs = require('./chunk-MNWKYY5E.cjs');
|
|
26
26
|
var chunkQTFKZBLC_cjs = require('./chunk-QTFKZBLC.cjs');
|
|
27
27
|
require('./chunk-IGJUBJBW.cjs');
|
|
28
28
|
var hono = require('hono');
|
|
29
|
+
var cors = require('hono/cors');
|
|
29
30
|
var zod = require('zod');
|
|
30
31
|
var cookie = require('hono/cookie');
|
|
31
32
|
var html = require('hono/html');
|
|
@@ -39,6 +40,7 @@ var DatabaseToolsService = class {
|
|
|
39
40
|
constructor(db) {
|
|
40
41
|
this.db = db;
|
|
41
42
|
}
|
|
43
|
+
db;
|
|
42
44
|
/**
|
|
43
45
|
* Get database statistics
|
|
44
46
|
*/
|
|
@@ -180,9 +182,9 @@ var DatabaseToolsService = class {
|
|
|
180
182
|
}
|
|
181
183
|
}
|
|
182
184
|
/**
|
|
183
|
-
* Get table data with optional pagination and
|
|
185
|
+
* Get table data with optional pagination, sorting, and search
|
|
184
186
|
*/
|
|
185
|
-
async getTableData(tableName, limit = 100, offset = 0, sortColumn, sortDirection = "asc") {
|
|
187
|
+
async getTableData(tableName, limit = 100, offset = 0, sortColumn, sortDirection = "asc", search) {
|
|
186
188
|
try {
|
|
187
189
|
const tables = await this.getTables();
|
|
188
190
|
if (!tables.includes(tableName)) {
|
|
@@ -193,14 +195,26 @@ var DatabaseToolsService = class {
|
|
|
193
195
|
if (sortColumn && !columns.includes(sortColumn)) {
|
|
194
196
|
sortColumn = void 0;
|
|
195
197
|
}
|
|
196
|
-
const
|
|
198
|
+
const searchTerm = search?.trim();
|
|
199
|
+
let whereClause = "";
|
|
200
|
+
let bindings = [];
|
|
201
|
+
if (searchTerm) {
|
|
202
|
+
const conditions = columns.map(() => `CAST(? AS TEXT) IS NOT NULL AND CAST(? AS TEXT) LIKE ?`).join(" OR ");
|
|
203
|
+
const colConditions = columns.map((col) => `CAST("${col}" AS TEXT) LIKE ?`).join(" OR ");
|
|
204
|
+
whereClause = ` WHERE (${colConditions})`;
|
|
205
|
+
bindings = columns.map(() => `%${searchTerm}%`);
|
|
206
|
+
}
|
|
207
|
+
const countQuery = `SELECT COUNT(*) as count FROM "${tableName}"${whereClause}`;
|
|
208
|
+
const countStmt = this.db.prepare(countQuery);
|
|
209
|
+
const countResult = bindings.length > 0 ? await countStmt.bind(...bindings).first() : await countStmt.first();
|
|
197
210
|
const totalRows = countResult?.count || 0;
|
|
198
|
-
let query = `SELECT * FROM ${tableName}`;
|
|
211
|
+
let query = `SELECT * FROM "${tableName}"${whereClause}`;
|
|
199
212
|
if (sortColumn) {
|
|
200
|
-
query += ` ORDER BY ${sortColumn} ${sortDirection.toUpperCase()}`;
|
|
213
|
+
query += ` ORDER BY "${sortColumn}" ${sortDirection.toUpperCase()}`;
|
|
201
214
|
}
|
|
202
215
|
query += ` LIMIT ${limit} OFFSET ${offset}`;
|
|
203
|
-
const
|
|
216
|
+
const dataStmt = this.db.prepare(query);
|
|
217
|
+
const dataResult = bindings.length > 0 ? await dataStmt.bind(...bindings).all() : await dataStmt.all();
|
|
204
218
|
return {
|
|
205
219
|
tableName,
|
|
206
220
|
columns,
|
|
@@ -249,7 +263,7 @@ var DatabaseToolsService = class {
|
|
|
249
263
|
};
|
|
250
264
|
|
|
251
265
|
// src/templates/pages/admin-database-table.template.ts
|
|
252
|
-
|
|
266
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
253
267
|
function renderDatabaseTablePage(data) {
|
|
254
268
|
const totalPages = Math.ceil(data.totalRows / data.pageSize);
|
|
255
269
|
const startRow = (data.currentPage - 1) * data.pageSize + 1;
|
|
@@ -304,6 +318,43 @@ function renderDatabaseTablePage(data) {
|
|
|
304
318
|
</div>
|
|
305
319
|
</div>
|
|
306
320
|
|
|
321
|
+
<!-- Search bar -->
|
|
322
|
+
<div class="flex items-center gap-3">
|
|
323
|
+
<div class="relative flex-1 max-w-xl">
|
|
324
|
+
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
325
|
+
<svg class="h-4 w-4 text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
326
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0"/>
|
|
327
|
+
</svg>
|
|
328
|
+
</div>
|
|
329
|
+
<input
|
|
330
|
+
id="searchInput"
|
|
331
|
+
type="text"
|
|
332
|
+
placeholder="Search all columns including JSON data..."
|
|
333
|
+
value="${escapeHtml2(data.search || "")}"
|
|
334
|
+
class="block w-full rounded-lg border-0 py-2.5 pl-10 pr-10 text-sm text-zinc-900 dark:text-white bg-white dark:bg-zinc-800 ring-1 ring-inset ring-zinc-300 dark:ring-zinc-700 placeholder:text-zinc-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600"
|
|
335
|
+
onkeydown="if(event.key==='Enter') doSearch()"
|
|
336
|
+
/>
|
|
337
|
+
${data.search ? `
|
|
338
|
+
<button
|
|
339
|
+
onclick="clearSearch()"
|
|
340
|
+
class="absolute inset-y-0 right-0 flex items-center pr-3 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200"
|
|
341
|
+
title="Clear search"
|
|
342
|
+
>
|
|
343
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
344
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
345
|
+
</svg>
|
|
346
|
+
</button>
|
|
347
|
+
` : ""}
|
|
348
|
+
</div>
|
|
349
|
+
<button
|
|
350
|
+
onclick="doSearch()"
|
|
351
|
+
class="inline-flex items-center justify-center rounded-lg bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-indigo-500 transition-colors shadow-sm"
|
|
352
|
+
>
|
|
353
|
+
Search
|
|
354
|
+
</button>
|
|
355
|
+
${data.search ? `<span class="text-sm text-zinc-500 dark:text-zinc-400">Filtered: <strong class="text-zinc-900 dark:text-white">${escapeHtml2(data.search)}</strong></span>` : ""}
|
|
356
|
+
</div>
|
|
357
|
+
|
|
307
358
|
<!-- Table Card -->
|
|
308
359
|
<div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 overflow-hidden">
|
|
309
360
|
<!-- Table -->
|
|
@@ -338,7 +389,7 @@ function renderDatabaseTablePage(data) {
|
|
|
338
389
|
<tr class="${idx % 2 === 0 ? "bg-white dark:bg-zinc-900" : "bg-zinc-50 dark:bg-zinc-900/50"}">
|
|
339
390
|
${data.columns.map((col) => `
|
|
340
391
|
<td class="px-4 py-3 text-sm text-zinc-700 dark:text-zinc-300 whitespace-nowrap max-w-xs overflow-hidden text-ellipsis" title="${escapeHtml2(String(row[col] ?? ""))}">
|
|
341
|
-
${formatCellValue(row[col])}
|
|
392
|
+
${formatCellValue(row[col], col)}
|
|
342
393
|
</td>
|
|
343
394
|
`).join("")}
|
|
344
395
|
</tr>
|
|
@@ -414,79 +465,143 @@ function renderDatabaseTablePage(data) {
|
|
|
414
465
|
</div>
|
|
415
466
|
</div>
|
|
416
467
|
|
|
468
|
+
<!-- JSON Viewer Modal -->
|
|
469
|
+
<div id="jsonModal" class="fixed inset-0 z-50 hidden" role="dialog" aria-modal="true">
|
|
470
|
+
<div class="fixed inset-0 bg-black/60 backdrop-blur-sm" onclick="closeJsonModal()"></div>
|
|
471
|
+
<div class="fixed inset-0 flex items-center justify-center p-4 pointer-events-none">
|
|
472
|
+
<div class="pointer-events-auto relative w-full max-w-4xl max-h-[85vh] flex flex-col rounded-xl bg-white dark:bg-zinc-900 shadow-2xl ring-1 ring-zinc-950/10 dark:ring-white/10">
|
|
473
|
+
<div class="flex items-center justify-between px-6 py-4 border-b border-zinc-200 dark:border-zinc-700">
|
|
474
|
+
<div>
|
|
475
|
+
<h3 id="jsonModalTitle" class="text-base font-semibold text-zinc-900 dark:text-white">Field Value</h3>
|
|
476
|
+
<p id="jsonModalSubtitle" class="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5"></p>
|
|
477
|
+
</div>
|
|
478
|
+
<div class="flex items-center gap-2">
|
|
479
|
+
<button onclick="copyJsonValue()" class="inline-flex items-center gap-1.5 rounded-lg bg-zinc-100 dark:bg-zinc-800 px-3 py-1.5 text-xs font-medium text-zinc-700 dark:text-zinc-300 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors">
|
|
480
|
+
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
481
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
|
482
|
+
</svg>
|
|
483
|
+
Copy
|
|
484
|
+
</button>
|
|
485
|
+
<button onclick="closeJsonModal()" class="rounded-lg p-1.5 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors">
|
|
486
|
+
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
487
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
488
|
+
</svg>
|
|
489
|
+
</button>
|
|
490
|
+
</div>
|
|
491
|
+
</div>
|
|
492
|
+
<div class="flex-1 overflow-auto p-6">
|
|
493
|
+
<pre id="jsonModalContent" class="text-sm font-mono text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words leading-relaxed"></pre>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
|
|
417
499
|
<script>
|
|
418
500
|
const currentTableName = '${data.tableName}';
|
|
419
501
|
let currentPage = ${data.currentPage};
|
|
420
502
|
let currentPageSize = ${data.pageSize};
|
|
421
503
|
let currentSort = '${data.sortColumn || ""}';
|
|
422
504
|
let currentSortDir = '${data.sortDirection || "asc"}';
|
|
505
|
+
let currentSearch = ${JSON.stringify(data.search || "")};
|
|
506
|
+
|
|
507
|
+
function buildParams(overrides = {}) {
|
|
508
|
+
const params = new URLSearchParams();
|
|
509
|
+
const p = { page: currentPage, pageSize: currentPageSize, sort: currentSort, dir: currentSortDir, search: currentSearch, ...overrides };
|
|
510
|
+
if (p.page) params.set('page', p.page);
|
|
511
|
+
if (p.pageSize) params.set('pageSize', p.pageSize);
|
|
512
|
+
if (p.sort) { params.set('sort', p.sort); params.set('dir', p.dir || 'asc'); }
|
|
513
|
+
if (p.search) params.set('search', p.search);
|
|
514
|
+
return params;
|
|
515
|
+
}
|
|
423
516
|
|
|
424
517
|
function goToPage(page) {
|
|
425
518
|
if (page < 1 || page > ${totalPages}) return;
|
|
426
|
-
|
|
427
|
-
params.set('page', page);
|
|
428
|
-
params.set('pageSize', currentPageSize);
|
|
429
|
-
if (currentSort) {
|
|
430
|
-
params.set('sort', currentSort);
|
|
431
|
-
params.set('dir', currentSortDir);
|
|
432
|
-
}
|
|
433
|
-
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${params}\`;
|
|
519
|
+
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${buildParams({ page })}\`;
|
|
434
520
|
}
|
|
435
521
|
|
|
436
522
|
function sortTable(column) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
newDir = 'desc';
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
const params = new URLSearchParams();
|
|
443
|
-
params.set('page', '1');
|
|
444
|
-
params.set('pageSize', currentPageSize);
|
|
445
|
-
params.set('sort', column);
|
|
446
|
-
params.set('dir', newDir);
|
|
447
|
-
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${params}\`;
|
|
523
|
+
const newDir = (currentSort === column && currentSortDir === 'asc') ? 'desc' : 'asc';
|
|
524
|
+
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${buildParams({ page: 1, sort: column, dir: newDir })}\`;
|
|
448
525
|
}
|
|
449
526
|
|
|
450
527
|
function changePageSize(newSize) {
|
|
451
|
-
|
|
452
|
-
params.set('page', '1');
|
|
453
|
-
params.set('pageSize', newSize);
|
|
454
|
-
if (currentSort) {
|
|
455
|
-
params.set('sort', currentSort);
|
|
456
|
-
params.set('dir', currentSortDir);
|
|
457
|
-
}
|
|
458
|
-
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${params}\`;
|
|
528
|
+
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${buildParams({ page: 1, pageSize: newSize })}\`;
|
|
459
529
|
}
|
|
460
530
|
|
|
461
531
|
function refreshTableData() {
|
|
462
532
|
window.location.reload();
|
|
463
533
|
}
|
|
464
534
|
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
535
|
+
function doSearch() {
|
|
536
|
+
const val = document.getElementById('searchInput').value.trim();
|
|
537
|
+
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${buildParams({ page: 1, search: val })}\`;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function clearSearch() {
|
|
541
|
+
window.location.href = \`/admin/database-tools/tables/\${currentTableName}?\${buildParams({ page: 1, search: '' })}\`;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// JSON viewer modal
|
|
545
|
+
let _jsonModalValue = '';
|
|
546
|
+
|
|
547
|
+
function openJsonModal(rawValue, colName) {
|
|
548
|
+
// rawValue comes from dataset \u2014 browser already decoded HTML entities, so it's the original string
|
|
549
|
+
_jsonModalValue = rawValue;
|
|
550
|
+
document.getElementById('jsonModalTitle').textContent = colName;
|
|
551
|
+
const el = document.getElementById('jsonModalContent');
|
|
552
|
+
const subtitle = document.getElementById('jsonModalSubtitle');
|
|
553
|
+
try {
|
|
554
|
+
const parsed = JSON.parse(rawValue);
|
|
555
|
+
const pretty = JSON.stringify(parsed, null, 2);
|
|
556
|
+
subtitle.textContent = 'JSON \u2022 ' + rawValue.length + ' chars';
|
|
557
|
+
el.innerHTML = syntaxHighlight(pretty);
|
|
558
|
+
} catch {
|
|
559
|
+
el.textContent = rawValue;
|
|
560
|
+
subtitle.textContent = rawValue.length + ' chars';
|
|
478
561
|
}
|
|
479
|
-
|
|
562
|
+
document.getElementById('jsonModal').classList.remove('hidden');
|
|
563
|
+
document.body.style.overflow = 'hidden';
|
|
480
564
|
}
|
|
481
565
|
|
|
566
|
+
function closeJsonModal() {
|
|
567
|
+
document.getElementById('jsonModal').classList.add('hidden');
|
|
568
|
+
document.body.style.overflow = '';
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function copyJsonValue() {
|
|
572
|
+
navigator.clipboard.writeText(_jsonModalValue).then(() => {
|
|
573
|
+
const btn = event.currentTarget;
|
|
574
|
+
const orig = btn.innerHTML;
|
|
575
|
+
btn.textContent = 'Copied!';
|
|
576
|
+
setTimeout(() => { btn.innerHTML = orig; }, 1500);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function syntaxHighlight(json) {
|
|
581
|
+
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
582
|
+
return json.replace(/("(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\"])*"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g, function(match) {
|
|
583
|
+
let cls = 'text-purple-600 dark:text-purple-400'; // number
|
|
584
|
+
if (/^"/.test(match)) {
|
|
585
|
+
if (/:$/.test(match)) {
|
|
586
|
+
cls = 'text-blue-600 dark:text-blue-400 font-medium'; // key
|
|
587
|
+
} else {
|
|
588
|
+
cls = 'text-green-700 dark:text-green-400'; // string value
|
|
589
|
+
}
|
|
590
|
+
} else if (/true|false/.test(match)) {
|
|
591
|
+
cls = 'text-orange-600 dark:text-orange-400';
|
|
592
|
+
} else if (/null/.test(match)) {
|
|
593
|
+
cls = 'text-zinc-400 italic';
|
|
594
|
+
}
|
|
595
|
+
return \`<span class="\${cls}">\${match}</span>\`;
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
document.addEventListener('keydown', (e) => {
|
|
600
|
+
if (e.key === 'Escape') closeJsonModal();
|
|
601
|
+
});
|
|
602
|
+
|
|
482
603
|
function escapeHtml(text) {
|
|
483
|
-
const map = {
|
|
484
|
-
'&': '&',
|
|
485
|
-
'<': '<',
|
|
486
|
-
'>': '>',
|
|
487
|
-
'"': '"',
|
|
488
|
-
"'": '''
|
|
489
|
-
};
|
|
604
|
+
const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
|
|
490
605
|
return String(text).replace(/[&<>"']/g, m => map[m]);
|
|
491
606
|
}
|
|
492
607
|
</script>
|
|
@@ -498,7 +613,7 @@ function renderDatabaseTablePage(data) {
|
|
|
498
613
|
user: data.user,
|
|
499
614
|
content: pageContent
|
|
500
615
|
};
|
|
501
|
-
return
|
|
616
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
502
617
|
}
|
|
503
618
|
function generatePageNumbers(currentPage, totalPages) {
|
|
504
619
|
const pages = [];
|
|
@@ -553,7 +668,16 @@ function escapeHtml2(text) {
|
|
|
553
668
|
};
|
|
554
669
|
return String(text).replace(/[&<>"']/g, (m) => map[m] || m);
|
|
555
670
|
}
|
|
556
|
-
function
|
|
671
|
+
function isJsonString(str2) {
|
|
672
|
+
const s = str2.trim();
|
|
673
|
+
return (s.startsWith("{") || s.startsWith("[")) && (s.endsWith("}") || s.endsWith("]"));
|
|
674
|
+
}
|
|
675
|
+
function jsonButton(raw, colName) {
|
|
676
|
+
const preview = raw.length > 60 ? escapeHtml2(raw.substring(0, 60)) + "\u2026" : escapeHtml2(raw);
|
|
677
|
+
return `<button data-json-val="${escapeHtml2(raw)}" data-col-name="${escapeHtml2(colName)}" onclick="openJsonModal(this.dataset.jsonVal, this.dataset.colName)" class="text-left text-xs font-mono text-indigo-600 dark:text-indigo-400 hover:underline">${preview}</button>`;
|
|
678
|
+
}
|
|
679
|
+
function formatCellValue(value, colName) {
|
|
680
|
+
const col = colName || "value";
|
|
557
681
|
if (value === null || value === void 0) {
|
|
558
682
|
return '<span class="text-zinc-400 dark:text-zinc-500 italic">null</span>';
|
|
559
683
|
}
|
|
@@ -561,11 +685,15 @@ function formatCellValue(value) {
|
|
|
561
685
|
return `<span class="px-2 py-0.5 rounded text-xs font-medium ${value ? "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400" : "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-400"}">${value}</span>`;
|
|
562
686
|
}
|
|
563
687
|
if (typeof value === "object") {
|
|
564
|
-
return
|
|
688
|
+
return jsonButton(JSON.stringify(value), col);
|
|
565
689
|
}
|
|
566
690
|
const str2 = String(value);
|
|
567
|
-
if (str2
|
|
568
|
-
return
|
|
691
|
+
if (isJsonString(str2)) {
|
|
692
|
+
return jsonButton(str2, col);
|
|
693
|
+
}
|
|
694
|
+
if (str2.length > 120) {
|
|
695
|
+
const preview = escapeHtml2(str2.substring(0, 120)) + "\u2026";
|
|
696
|
+
return `<button data-json-val="${escapeHtml2(str2)}" data-col-name="${escapeHtml2(col)}" onclick="openJsonModal(this.dataset.jsonVal, this.dataset.colName)" class="text-left text-sm text-zinc-700 dark:text-zinc-300 hover:underline">${preview}</button>`;
|
|
569
697
|
}
|
|
570
698
|
return escapeHtml2(str2);
|
|
571
699
|
}
|
|
@@ -573,7 +701,7 @@ function formatCellValue(value) {
|
|
|
573
701
|
// src/plugins/core-plugins/database-tools-plugin/admin-routes.ts
|
|
574
702
|
function createDatabaseToolsAdminRoutes() {
|
|
575
703
|
const router3 = new hono.Hono();
|
|
576
|
-
router3.use("*",
|
|
704
|
+
router3.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
577
705
|
router3.get("/api/stats", async (c) => {
|
|
578
706
|
try {
|
|
579
707
|
const user = c.get("user");
|
|
@@ -700,9 +828,10 @@ function createDatabaseToolsAdminRoutes() {
|
|
|
700
828
|
const offset = parseInt(c.req.query("offset") || "0");
|
|
701
829
|
const sortColumn = c.req.query("sort");
|
|
702
830
|
const sortDirection = c.req.query("dir") || "asc";
|
|
831
|
+
const search = c.req.query("search");
|
|
703
832
|
const db = c.env.DB;
|
|
704
833
|
const service = new DatabaseToolsService(db);
|
|
705
|
-
const tableData = await service.getTableData(tableName, limit, offset, sortColumn, sortDirection);
|
|
834
|
+
const tableData = await service.getTableData(tableName, limit, offset, sortColumn, sortDirection, search);
|
|
706
835
|
return c.json({
|
|
707
836
|
success: true,
|
|
708
837
|
data: tableData
|
|
@@ -726,10 +855,11 @@ function createDatabaseToolsAdminRoutes() {
|
|
|
726
855
|
const pageSize = parseInt(c.req.query("pageSize") || "20");
|
|
727
856
|
const sortColumn = c.req.query("sort");
|
|
728
857
|
const sortDirection = c.req.query("dir") || "asc";
|
|
858
|
+
const search = c.req.query("search");
|
|
729
859
|
const offset = (page - 1) * pageSize;
|
|
730
860
|
const db = c.env.DB;
|
|
731
861
|
const service = new DatabaseToolsService(db);
|
|
732
|
-
const tableData = await service.getTableData(tableName, pageSize, offset, sortColumn, sortDirection);
|
|
862
|
+
const tableData = await service.getTableData(tableName, pageSize, offset, sortColumn, sortDirection, search);
|
|
733
863
|
const pageData = {
|
|
734
864
|
user: {
|
|
735
865
|
name: user.email.split("@")[0] || "Unknown",
|
|
@@ -743,7 +873,8 @@ function createDatabaseToolsAdminRoutes() {
|
|
|
743
873
|
currentPage: page,
|
|
744
874
|
pageSize,
|
|
745
875
|
sortColumn,
|
|
746
|
-
sortDirection
|
|
876
|
+
sortDirection,
|
|
877
|
+
search
|
|
747
878
|
};
|
|
748
879
|
return c.html(renderDatabaseTablePage(pageData));
|
|
749
880
|
} catch (error) {
|
|
@@ -897,6 +1028,7 @@ var EmailSettingsService = class {
|
|
|
897
1028
|
constructor(db) {
|
|
898
1029
|
this.db = db;
|
|
899
1030
|
}
|
|
1031
|
+
db;
|
|
900
1032
|
async load() {
|
|
901
1033
|
let row = null;
|
|
902
1034
|
try {
|
|
@@ -925,8 +1057,10 @@ var SiteConfigService = class {
|
|
|
925
1057
|
this.db = db;
|
|
926
1058
|
this.env = env;
|
|
927
1059
|
}
|
|
1060
|
+
db;
|
|
1061
|
+
env;
|
|
928
1062
|
async load() {
|
|
929
|
-
const settings = new
|
|
1063
|
+
const settings = new chunk36Z3AKX3_cjs.SettingsService(this.db);
|
|
930
1064
|
const general = await settings.getGeneralSettings();
|
|
931
1065
|
const siteUrl = this.env.PUBLIC_URL || "http://localhost:8787";
|
|
932
1066
|
return {
|
|
@@ -976,7 +1110,7 @@ var SiteConfigService = class {
|
|
|
976
1110
|
|
|
977
1111
|
// src/plugins/core-plugins/email-plugin/routes/admin.ts
|
|
978
1112
|
var adminRoutes = new hono.Hono();
|
|
979
|
-
adminRoutes.use("*",
|
|
1113
|
+
adminRoutes.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
980
1114
|
adminRoutes.post("/settings", async (c) => {
|
|
981
1115
|
if (c.get("user")?.role !== "admin") {
|
|
982
1116
|
return c.json({ error: "admin role required" }, 403);
|
|
@@ -1014,7 +1148,7 @@ adminRoutes.post("/test", async (c) => {
|
|
|
1014
1148
|
const { subject, html: html4, text } = renderTestEmail({ siteName });
|
|
1015
1149
|
try {
|
|
1016
1150
|
const settingsLoaded = await settings.load();
|
|
1017
|
-
const result = await
|
|
1151
|
+
const result = await chunk7RUW244J_cjs.getEmailService().send({
|
|
1018
1152
|
to,
|
|
1019
1153
|
subject,
|
|
1020
1154
|
html: html4,
|
|
@@ -1096,7 +1230,7 @@ function makeOnRegistrationCompleted(env) {
|
|
|
1096
1230
|
siteName,
|
|
1097
1231
|
loginUrl: siteConfig.buildLoginUrl(siteUrl)
|
|
1098
1232
|
});
|
|
1099
|
-
const result = await
|
|
1233
|
+
const result = await chunk7RUW244J_cjs.getEmailService().send({
|
|
1100
1234
|
to: user.email,
|
|
1101
1235
|
subject,
|
|
1102
1236
|
html: html4,
|
|
@@ -1170,7 +1304,7 @@ function makeOnPasswordResetRequested(env) {
|
|
|
1170
1304
|
expiresAt: Date.now() + DEFAULT_EXPIRY_MS,
|
|
1171
1305
|
siteName
|
|
1172
1306
|
});
|
|
1173
|
-
const result = await
|
|
1307
|
+
const result = await chunk7RUW244J_cjs.getEmailService().send({
|
|
1174
1308
|
to: user.email,
|
|
1175
1309
|
subject,
|
|
1176
1310
|
html: html4,
|
|
@@ -1238,7 +1372,7 @@ function makeOnPasswordResetCompleted(env) {
|
|
|
1238
1372
|
supportEmail,
|
|
1239
1373
|
when: Date.now()
|
|
1240
1374
|
});
|
|
1241
|
-
const result = await
|
|
1375
|
+
const result = await chunk7RUW244J_cjs.getEmailService().send({
|
|
1242
1376
|
to: user.email,
|
|
1243
1377
|
subject,
|
|
1244
1378
|
html: html4,
|
|
@@ -1262,6 +1396,8 @@ var EmailValidationError = class extends Error {
|
|
|
1262
1396
|
this.reason = reason;
|
|
1263
1397
|
this.name = "EmailValidationError";
|
|
1264
1398
|
}
|
|
1399
|
+
field;
|
|
1400
|
+
reason;
|
|
1265
1401
|
code = "EMAIL_VALIDATION_FAILED";
|
|
1266
1402
|
};
|
|
1267
1403
|
|
|
@@ -1297,6 +1433,9 @@ var CfGraphqlClient = class {
|
|
|
1297
1433
|
throw new EmailValidationError("apiToken", "EMAIL_API_TOKEN is required for GraphQL queries");
|
|
1298
1434
|
}
|
|
1299
1435
|
}
|
|
1436
|
+
zoneId;
|
|
1437
|
+
apiToken;
|
|
1438
|
+
fetchImpl;
|
|
1300
1439
|
async queryEmailSends(input) {
|
|
1301
1440
|
const startIso = new Date(input.startSeconds * 1e3).toISOString();
|
|
1302
1441
|
const endIso = new Date(input.endSeconds * 1e3).toISOString();
|
|
@@ -1359,6 +1498,7 @@ var EmailLogService = class {
|
|
|
1359
1498
|
constructor(db) {
|
|
1360
1499
|
this.db = db;
|
|
1361
1500
|
}
|
|
1501
|
+
db;
|
|
1362
1502
|
/**
|
|
1363
1503
|
* Records a successful submission to CF Email Service. `status` =
|
|
1364
1504
|
* `'submitted'`, `delivery_state` remains NULL until reconciliation runs.
|
|
@@ -1532,6 +1672,8 @@ var ReconciliationService = class {
|
|
|
1532
1672
|
this.graphql = graphql;
|
|
1533
1673
|
this.emailLog = emailLog;
|
|
1534
1674
|
}
|
|
1675
|
+
graphql;
|
|
1676
|
+
emailLog;
|
|
1535
1677
|
async run(input = {}) {
|
|
1536
1678
|
const windowHours = input.windowHours ?? 24;
|
|
1537
1679
|
const nowMs = input.now ?? Date.now();
|
|
@@ -1940,6 +2082,7 @@ var CloudflareEmailProvider = class {
|
|
|
1940
2082
|
constructor(binding) {
|
|
1941
2083
|
this.binding = binding;
|
|
1942
2084
|
}
|
|
2085
|
+
binding;
|
|
1943
2086
|
name = "cloudflare";
|
|
1944
2087
|
isConfigured() {
|
|
1945
2088
|
return !!this.binding;
|
|
@@ -1970,7 +2113,7 @@ var CloudflareEmailProvider = class {
|
|
|
1970
2113
|
}
|
|
1971
2114
|
}
|
|
1972
2115
|
};
|
|
1973
|
-
var emailPluginV3 =
|
|
2116
|
+
var emailPluginV3 = chunkA4KUJ3LD_cjs.definePlugin({
|
|
1974
2117
|
id: "email",
|
|
1975
2118
|
version: "1.0.0",
|
|
1976
2119
|
name: "Email",
|
|
@@ -1984,7 +2127,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
|
|
|
1984
2127
|
const db = env.DB;
|
|
1985
2128
|
if (db) {
|
|
1986
2129
|
try {
|
|
1987
|
-
const typeRegistry = new
|
|
2130
|
+
const typeRegistry = new chunkFCLKX2OS_cjs.DocumentTypeRegistry(db);
|
|
1988
2131
|
await typeRegistry.register({
|
|
1989
2132
|
id: "email_log",
|
|
1990
2133
|
name: "email_log",
|
|
@@ -1999,7 +2142,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
|
|
|
1999
2142
|
} catch {
|
|
2000
2143
|
}
|
|
2001
2144
|
}
|
|
2002
|
-
if (!
|
|
2145
|
+
if (!chunk7RUW244J_cjs.hasEmailService()) {
|
|
2003
2146
|
const settings = db ? await new EmailSettingsService(db).load() : {};
|
|
2004
2147
|
const envResendKey = typeof env.RESEND_API_KEY === "string" && env.RESEND_API_KEY ? env.RESEND_API_KEY : void 0;
|
|
2005
2148
|
const cfEmailBinding = env.EMAIL;
|
|
@@ -2017,7 +2160,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
|
|
|
2017
2160
|
} else {
|
|
2018
2161
|
provider = resolveEmailProvider({ env });
|
|
2019
2162
|
}
|
|
2020
|
-
|
|
2163
|
+
chunk7RUW244J_cjs.setEmailService(new EmailService({ ...serviceOpts, provider }));
|
|
2021
2164
|
}
|
|
2022
2165
|
ctx.hooks.on("auth:registration:completed", makeOnRegistrationCompleted(env));
|
|
2023
2166
|
ctx.hooks.on("auth:password-reset:requested", makeOnPasswordResetRequested(env));
|
|
@@ -2028,7 +2171,7 @@ var emailPluginV3 = chunkXW56B23A_cjs.definePlugin({
|
|
|
2028
2171
|
var BATCH_SIZE = 100;
|
|
2029
2172
|
({
|
|
2030
2173
|
schema: zod.z.record(zod.z.string(), zod.z.unknown())});
|
|
2031
|
-
var emailReconciliationPlugin =
|
|
2174
|
+
var emailReconciliationPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
2032
2175
|
id: "email-reconciliation",
|
|
2033
2176
|
version: "1.0.0",
|
|
2034
2177
|
description: "Hourly cron that backfills email delivery state from provider status APIs. Only active for providers that implement EmailProvider.reconcile().",
|
|
@@ -2049,11 +2192,11 @@ var emailReconciliationPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
2049
2192
|
console.warn("[email-reconciliation] No DB binding in cron env \u2014 skipping.");
|
|
2050
2193
|
return;
|
|
2051
2194
|
}
|
|
2052
|
-
if (!
|
|
2195
|
+
if (!chunk7RUW244J_cjs.hasEmailService()) {
|
|
2053
2196
|
console.warn("[email-reconciliation] EmailService not initialized \u2014 skipping.");
|
|
2054
2197
|
return;
|
|
2055
2198
|
}
|
|
2056
|
-
const emailService =
|
|
2199
|
+
const emailService = chunk7RUW244J_cjs.getEmailService();
|
|
2057
2200
|
let rows = [];
|
|
2058
2201
|
try {
|
|
2059
2202
|
const result = await db.prepare(
|
|
@@ -2122,6 +2265,7 @@ var OTPService = class {
|
|
|
2122
2265
|
constructor(db) {
|
|
2123
2266
|
this.db = db;
|
|
2124
2267
|
}
|
|
2268
|
+
db;
|
|
2125
2269
|
/**
|
|
2126
2270
|
* Generate a secure random OTP code
|
|
2127
2271
|
*/
|
|
@@ -2485,7 +2629,7 @@ function buildOtpApi() {
|
|
|
2485
2629
|
console.warn("Failed to parse OTP plugin settings, using defaults");
|
|
2486
2630
|
}
|
|
2487
2631
|
}
|
|
2488
|
-
const settingsService = new
|
|
2632
|
+
const settingsService = new chunk36Z3AKX3_cjs.SettingsService(db);
|
|
2489
2633
|
const generalSettings = await settingsService.getGeneralSettings();
|
|
2490
2634
|
const siteName = generalSettings.siteName;
|
|
2491
2635
|
const canRequest = await otpService.checkRateLimit(normalizedEmail, settings);
|
|
@@ -2539,8 +2683,8 @@ function buildOtpApi() {
|
|
|
2539
2683
|
loginUrl: settings.loginUrl || "",
|
|
2540
2684
|
loginButtonText: settings.loginButtonText || ""
|
|
2541
2685
|
});
|
|
2542
|
-
if (
|
|
2543
|
-
const sent = await
|
|
2686
|
+
if (chunk7RUW244J_cjs.hasEmailService()) {
|
|
2687
|
+
const sent = await chunk7RUW244J_cjs.getEmailService().send({
|
|
2544
2688
|
to: normalizedEmail,
|
|
2545
2689
|
subject: `Your login code for ${siteName}`,
|
|
2546
2690
|
flow: "otp",
|
|
@@ -2642,21 +2786,21 @@ function buildOtpApi() {
|
|
|
2642
2786
|
error: "Account is deactivated"
|
|
2643
2787
|
}, 403);
|
|
2644
2788
|
}
|
|
2645
|
-
const tokenTtl = await
|
|
2646
|
-
const token = await
|
|
2789
|
+
const tokenTtl = await chunkFCLKX2OS_cjs.getJwtExpirySecondsFromDb(db, c.env);
|
|
2790
|
+
const token = await chunkFCLKX2OS_cjs.AuthManager.generateToken(user.id, user.email, user.role, c.env.JWT_SECRET, tokenTtl);
|
|
2647
2791
|
cookie.setCookie(c, "auth_token", token, {
|
|
2648
2792
|
httpOnly: true,
|
|
2649
2793
|
secure: true,
|
|
2650
2794
|
sameSite: "Strict",
|
|
2651
2795
|
maxAge: tokenTtl
|
|
2652
2796
|
});
|
|
2653
|
-
|
|
2797
|
+
chunk7RUW244J_cjs.dispatchHookEvent(
|
|
2654
2798
|
c,
|
|
2655
2799
|
"auth:otp:verified",
|
|
2656
2800
|
{ user: { id: user.id, email: user.email, role: user.role } },
|
|
2657
2801
|
"fire-and-forget"
|
|
2658
2802
|
);
|
|
2659
|
-
const customData = await
|
|
2803
|
+
const customData = await chunk7RUW244J_cjs.getCustomData(db, user.id);
|
|
2660
2804
|
const { is_active: _isActive, ...publicUser } = user;
|
|
2661
2805
|
return c.json({
|
|
2662
2806
|
success: true,
|
|
@@ -2701,7 +2845,7 @@ function buildOtpApi() {
|
|
|
2701
2845
|
});
|
|
2702
2846
|
return otpAPI;
|
|
2703
2847
|
}
|
|
2704
|
-
var otpLoginPlugin =
|
|
2848
|
+
var otpLoginPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
2705
2849
|
id: "otp-login",
|
|
2706
2850
|
version: "1.0.0",
|
|
2707
2851
|
name: "OTP Login",
|
|
@@ -2756,6 +2900,7 @@ var OAuthService = class {
|
|
|
2756
2900
|
constructor(db) {
|
|
2757
2901
|
this.db = db;
|
|
2758
2902
|
}
|
|
2903
|
+
db;
|
|
2759
2904
|
/**
|
|
2760
2905
|
* Build the authorization redirect URL for a provider.
|
|
2761
2906
|
*/
|
|
@@ -3098,15 +3243,15 @@ function buildOauthApi() {
|
|
|
3098
3243
|
if (!user || !user.is_active) {
|
|
3099
3244
|
return c.redirect("/auth/login?error=Account is deactivated");
|
|
3100
3245
|
}
|
|
3101
|
-
const tokenTtl2 = await
|
|
3102
|
-
const jwt2 = await
|
|
3246
|
+
const tokenTtl2 = await chunkFCLKX2OS_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
3247
|
+
const jwt2 = await chunkFCLKX2OS_cjs.AuthManager.generateToken(
|
|
3103
3248
|
user.id,
|
|
3104
3249
|
user.email,
|
|
3105
3250
|
user.role,
|
|
3106
3251
|
c.env.JWT_SECRET,
|
|
3107
3252
|
tokenTtl2
|
|
3108
3253
|
);
|
|
3109
|
-
|
|
3254
|
+
chunkFCLKX2OS_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
|
|
3110
3255
|
return c.redirect("/admin");
|
|
3111
3256
|
}
|
|
3112
3257
|
const existingUser = await oauthService.findUserByEmail(profile.email);
|
|
@@ -3123,15 +3268,15 @@ function buildOauthApi() {
|
|
|
3123
3268
|
tokenExpiresAt: tokenExpiresAt ?? void 0,
|
|
3124
3269
|
profileData: JSON.stringify(profile)
|
|
3125
3270
|
});
|
|
3126
|
-
const tokenTtl2 = await
|
|
3127
|
-
const jwt2 = await
|
|
3271
|
+
const tokenTtl2 = await chunkFCLKX2OS_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
3272
|
+
const jwt2 = await chunkFCLKX2OS_cjs.AuthManager.generateToken(
|
|
3128
3273
|
existingUser.id,
|
|
3129
3274
|
existingUser.email,
|
|
3130
3275
|
existingUser.role,
|
|
3131
3276
|
c.env.JWT_SECRET,
|
|
3132
3277
|
tokenTtl2
|
|
3133
3278
|
);
|
|
3134
|
-
|
|
3279
|
+
chunkFCLKX2OS_cjs.AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax", maxAge: tokenTtl2 });
|
|
3135
3280
|
return c.redirect("/admin");
|
|
3136
3281
|
}
|
|
3137
3282
|
const newUserId = await oauthService.createUserFromOAuth(profile);
|
|
@@ -3144,15 +3289,15 @@ function buildOauthApi() {
|
|
|
3144
3289
|
tokenExpiresAt: tokenExpiresAt ?? void 0,
|
|
3145
3290
|
profileData: JSON.stringify(profile)
|
|
3146
3291
|
});
|
|
3147
|
-
const tokenTtl = await
|
|
3148
|
-
const jwt = await
|
|
3292
|
+
const tokenTtl = await chunkFCLKX2OS_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
3293
|
+
const jwt = await chunkFCLKX2OS_cjs.AuthManager.generateToken(
|
|
3149
3294
|
newUserId,
|
|
3150
3295
|
profile.email.toLowerCase(),
|
|
3151
3296
|
"viewer",
|
|
3152
3297
|
c.env.JWT_SECRET,
|
|
3153
3298
|
tokenTtl
|
|
3154
3299
|
);
|
|
3155
|
-
|
|
3300
|
+
chunkFCLKX2OS_cjs.AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax", maxAge: tokenTtl });
|
|
3156
3301
|
return c.redirect("/admin");
|
|
3157
3302
|
} catch (error) {
|
|
3158
3303
|
console.error("OAuth callback error:", error);
|
|
@@ -3247,7 +3392,7 @@ function buildOauthApi() {
|
|
|
3247
3392
|
});
|
|
3248
3393
|
return oauthAPI;
|
|
3249
3394
|
}
|
|
3250
|
-
var oauthProvidersPlugin =
|
|
3395
|
+
var oauthProvidersPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
3251
3396
|
id: "oauth-providers",
|
|
3252
3397
|
version: "1.0.0",
|
|
3253
3398
|
name: "OAuth Providers",
|
|
@@ -3272,6 +3417,7 @@ var EmbeddingService = class {
|
|
|
3272
3417
|
constructor(ai) {
|
|
3273
3418
|
this.ai = ai;
|
|
3274
3419
|
}
|
|
3420
|
+
ai;
|
|
3275
3421
|
/**
|
|
3276
3422
|
* Generate embedding for a single text
|
|
3277
3423
|
*/
|
|
@@ -3476,6 +3622,9 @@ var CustomRAGService = class {
|
|
|
3476
3622
|
this.embeddingService = new EmbeddingService(ai);
|
|
3477
3623
|
this.chunkingService = new ChunkingService();
|
|
3478
3624
|
}
|
|
3625
|
+
db;
|
|
3626
|
+
ai;
|
|
3627
|
+
vectorize;
|
|
3479
3628
|
embeddingService;
|
|
3480
3629
|
chunkingService;
|
|
3481
3630
|
/**
|
|
@@ -3766,6 +3915,9 @@ var AISearchService = class {
|
|
|
3766
3915
|
console.log("[AISearchService] Custom RAG not available, using keyword search only");
|
|
3767
3916
|
}
|
|
3768
3917
|
}
|
|
3918
|
+
db;
|
|
3919
|
+
ai;
|
|
3920
|
+
vectorize;
|
|
3769
3921
|
customRAG;
|
|
3770
3922
|
/**
|
|
3771
3923
|
* Get plugin settings
|
|
@@ -3824,7 +3976,7 @@ var AISearchService = class {
|
|
|
3824
3976
|
*/
|
|
3825
3977
|
async detectNewCollections() {
|
|
3826
3978
|
try {
|
|
3827
|
-
const allCollections =
|
|
3979
|
+
const allCollections = chunkKVBHB7QP_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => ({
|
|
3828
3980
|
id: r.id,
|
|
3829
3981
|
name: r.name,
|
|
3830
3982
|
display_name: r.displayName,
|
|
@@ -3876,7 +4028,7 @@ var AISearchService = class {
|
|
|
3876
4028
|
*/
|
|
3877
4029
|
async getAllCollections() {
|
|
3878
4030
|
try {
|
|
3879
|
-
const allCollections =
|
|
4031
|
+
const allCollections = chunkKVBHB7QP_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).sort((a, b) => a.displayName.localeCompare(b.displayName)).map((r) => ({
|
|
3880
4032
|
id: r.id,
|
|
3881
4033
|
name: r.name,
|
|
3882
4034
|
display_name: r.displayName,
|
|
@@ -4206,13 +4358,16 @@ var IndexManager = class {
|
|
|
4206
4358
|
console.log("[IndexManager] Custom RAG initialized");
|
|
4207
4359
|
}
|
|
4208
4360
|
}
|
|
4361
|
+
db;
|
|
4362
|
+
ai;
|
|
4363
|
+
vectorize;
|
|
4209
4364
|
customRAG;
|
|
4210
4365
|
/**
|
|
4211
4366
|
* Index all content items within a collection using Custom RAG
|
|
4212
4367
|
*/
|
|
4213
4368
|
async indexCollection(collectionId) {
|
|
4214
4369
|
try {
|
|
4215
|
-
const registry =
|
|
4370
|
+
const registry = chunkKVBHB7QP_cjs.getCollectionRegistry();
|
|
4216
4371
|
const record = registry.getById(collectionId) ?? registry.getByName(collectionId);
|
|
4217
4372
|
if (!record) {
|
|
4218
4373
|
throw new Error(`Collection ${collectionId} not found`);
|
|
@@ -4828,7 +4983,7 @@ function renderSettingsPage(data) {
|
|
|
4828
4983
|
}, 30000);
|
|
4829
4984
|
</script>
|
|
4830
4985
|
`;
|
|
4831
|
-
return
|
|
4986
|
+
return chunkPXNTCCPE_cjs.renderAdminLayout({
|
|
4832
4987
|
title: "AI Search Settings",
|
|
4833
4988
|
pageTitle: "AI Search Settings",
|
|
4834
4989
|
currentPath: "/admin/plugins/ai-search/settings",
|
|
@@ -4839,7 +4994,7 @@ function renderSettingsPage(data) {
|
|
|
4839
4994
|
|
|
4840
4995
|
// src/plugins/core-plugins/ai-search-plugin/routes/admin.ts
|
|
4841
4996
|
var adminRoutes2 = new hono.Hono();
|
|
4842
|
-
adminRoutes2.use("*",
|
|
4997
|
+
adminRoutes2.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
4843
4998
|
adminRoutes2.get("/", async (c) => {
|
|
4844
4999
|
try {
|
|
4845
5000
|
const user = c.get("user");
|
|
@@ -5080,7 +5235,7 @@ var manifest_default = {
|
|
|
5080
5235
|
author: "SonicJS"};
|
|
5081
5236
|
|
|
5082
5237
|
// src/plugins/core-plugins/ai-search-plugin/index.ts
|
|
5083
|
-
var aiSearchPlugin =
|
|
5238
|
+
var aiSearchPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
5084
5239
|
id: manifest_default.id,
|
|
5085
5240
|
version: manifest_default.version,
|
|
5086
5241
|
name: manifest_default.name,
|
|
@@ -5133,12 +5288,14 @@ var SecurityAuditService = class {
|
|
|
5133
5288
|
constructor(db, settings = DEFAULT_SETTINGS2) {
|
|
5134
5289
|
this.db = db;
|
|
5135
5290
|
this.settings = settings;
|
|
5136
|
-
this.docsService = new
|
|
5291
|
+
this.docsService = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
5137
5292
|
queryableFields: QUERYABLE_FIELDS,
|
|
5138
5293
|
maxVersionsPerRoot: 1,
|
|
5139
5294
|
tenantId: TENANT
|
|
5140
5295
|
});
|
|
5141
5296
|
}
|
|
5297
|
+
db;
|
|
5298
|
+
settings;
|
|
5142
5299
|
docsService;
|
|
5143
5300
|
async logEvent(event) {
|
|
5144
5301
|
const doc = await this.docsService.create({
|
|
@@ -5379,7 +5536,7 @@ function rowToEvent(row) {
|
|
|
5379
5536
|
}
|
|
5380
5537
|
|
|
5381
5538
|
// src/plugins/core-plugins/security-audit-plugin/components/dashboard-page.ts
|
|
5382
|
-
|
|
5539
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
5383
5540
|
function formatTimestamp(ts) {
|
|
5384
5541
|
const date = new Date(ts);
|
|
5385
5542
|
const now = Date.now();
|
|
@@ -5578,11 +5735,11 @@ function renderSecurityDashboard(data) {
|
|
|
5578
5735
|
version,
|
|
5579
5736
|
dynamicMenuItems
|
|
5580
5737
|
};
|
|
5581
|
-
return
|
|
5738
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
5582
5739
|
}
|
|
5583
5740
|
|
|
5584
5741
|
// src/plugins/core-plugins/security-audit-plugin/components/event-log-page.ts
|
|
5585
|
-
|
|
5742
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
5586
5743
|
function formatTimestamp2(ts) {
|
|
5587
5744
|
const date = new Date(ts);
|
|
5588
5745
|
return date.toLocaleDateString("en-US", {
|
|
@@ -5789,11 +5946,11 @@ function renderEventLogPage(data) {
|
|
|
5789
5946
|
version,
|
|
5790
5947
|
dynamicMenuItems
|
|
5791
5948
|
};
|
|
5792
|
-
return
|
|
5949
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
5793
5950
|
}
|
|
5794
5951
|
|
|
5795
5952
|
// src/plugins/core-plugins/security-audit-plugin/components/settings-page.ts
|
|
5796
|
-
|
|
5953
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
5797
5954
|
function renderSecuritySettingsPage(data) {
|
|
5798
5955
|
const { settings, user, version, message, dynamicMenuItems } = data;
|
|
5799
5956
|
const content2 = `
|
|
@@ -5946,12 +6103,12 @@ function renderSecuritySettingsPage(data) {
|
|
|
5946
6103
|
version,
|
|
5947
6104
|
dynamicMenuItems
|
|
5948
6105
|
};
|
|
5949
|
-
return
|
|
6106
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
5950
6107
|
}
|
|
5951
6108
|
|
|
5952
6109
|
// src/plugins/core-plugins/security-audit-plugin/routes/admin.ts
|
|
5953
6110
|
var adminRoutes3 = new hono.Hono();
|
|
5954
|
-
adminRoutes3.use("*",
|
|
6111
|
+
adminRoutes3.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
5955
6112
|
adminRoutes3.use("*", async (c, next) => {
|
|
5956
6113
|
const user = c.get("user");
|
|
5957
6114
|
if (user?.role !== "admin") {
|
|
@@ -5961,7 +6118,7 @@ adminRoutes3.use("*", async (c, next) => {
|
|
|
5961
6118
|
});
|
|
5962
6119
|
async function getSettings(db) {
|
|
5963
6120
|
try {
|
|
5964
|
-
const pluginService = new
|
|
6121
|
+
const pluginService = new chunkKVBHB7QP_cjs.PluginService(db);
|
|
5965
6122
|
const plugin2 = await pluginService.getPlugin("security-audit");
|
|
5966
6123
|
if (plugin2?.settings) {
|
|
5967
6124
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
@@ -6066,7 +6223,7 @@ adminRoutes3.post("/settings", async (c) => {
|
|
|
6066
6223
|
autoPurge: body["retention.autoPurge"] === "true"
|
|
6067
6224
|
}
|
|
6068
6225
|
};
|
|
6069
|
-
const pluginService = new
|
|
6226
|
+
const pluginService = new chunkKVBHB7QP_cjs.PluginService(db);
|
|
6070
6227
|
await pluginService.updatePluginSettings("security-audit", settings);
|
|
6071
6228
|
if (c.req.header("HX-Request")) {
|
|
6072
6229
|
return c.json({ success: true });
|
|
@@ -6082,6 +6239,7 @@ var BruteForceDetector = class {
|
|
|
6082
6239
|
this.kv = kv;
|
|
6083
6240
|
this.settings = settings || DEFAULT_SETTINGS2.bruteForce;
|
|
6084
6241
|
}
|
|
6242
|
+
kv;
|
|
6085
6243
|
settings;
|
|
6086
6244
|
async recordFailedAttempt(ip, email) {
|
|
6087
6245
|
if (!this.settings.enabled || !this.kv) {
|
|
@@ -6227,7 +6385,7 @@ var BruteForceDetector = class {
|
|
|
6227
6385
|
|
|
6228
6386
|
// src/plugins/core-plugins/security-audit-plugin/routes/api.ts
|
|
6229
6387
|
var apiRoutes2 = new hono.Hono();
|
|
6230
|
-
apiRoutes2.use("*",
|
|
6388
|
+
apiRoutes2.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
6231
6389
|
apiRoutes2.use("*", async (c, next) => {
|
|
6232
6390
|
const user = c.get("user");
|
|
6233
6391
|
if (user?.role !== "admin") {
|
|
@@ -6237,7 +6395,7 @@ apiRoutes2.use("*", async (c, next) => {
|
|
|
6237
6395
|
});
|
|
6238
6396
|
async function getSettings2(db) {
|
|
6239
6397
|
try {
|
|
6240
|
-
const pluginService = new
|
|
6398
|
+
const pluginService = new chunkKVBHB7QP_cjs.PluginService(db);
|
|
6241
6399
|
const plugin2 = await pluginService.getPlugin("security-audit");
|
|
6242
6400
|
if (plugin2?.settings) {
|
|
6243
6401
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
@@ -6385,7 +6543,7 @@ function generateFingerprint(ip, userAgent) {
|
|
|
6385
6543
|
}
|
|
6386
6544
|
async function getPluginSettings(db) {
|
|
6387
6545
|
try {
|
|
6388
|
-
const pluginService = new
|
|
6546
|
+
const pluginService = new chunkKVBHB7QP_cjs.PluginService(db);
|
|
6389
6547
|
const plugin2 = await pluginService.getPlugin("security-audit");
|
|
6390
6548
|
if (plugin2?.settings) {
|
|
6391
6549
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
@@ -6616,7 +6774,7 @@ async function logAuthEvent(c, db, settings, ip, userAgent, countryCode, fingerp
|
|
|
6616
6774
|
|
|
6617
6775
|
// src/plugins/core-plugins/security-audit-plugin/index.ts
|
|
6618
6776
|
var SECURITY_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>`;
|
|
6619
|
-
var securityAuditPlugin =
|
|
6777
|
+
var securityAuditPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
6620
6778
|
id: "security-audit",
|
|
6621
6779
|
version: "1.0.0",
|
|
6622
6780
|
name: "Security Audit",
|
|
@@ -6634,11 +6792,465 @@ var securityAuditPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
6634
6792
|
deactivate: async () => console.log("[SecurityAudit] Plugin deactivated")
|
|
6635
6793
|
});
|
|
6636
6794
|
|
|
6795
|
+
// src/plugins/core-plugins/api-keys-plugin/services/api-key-service.ts
|
|
6796
|
+
var API_KEY_QUERYABLE = [
|
|
6797
|
+
{ name: "keyHash", kind: "scalar", type: "text", column: "q_apikey_hash" },
|
|
6798
|
+
{ name: "userId", kind: "scalar", type: "text", column: "q_apikey_user_id" },
|
|
6799
|
+
{ name: "revoked", kind: "scalar", type: "integer", column: "q_apikey_revoked" }
|
|
6800
|
+
];
|
|
6801
|
+
var KEY_PREFIX = "sk_";
|
|
6802
|
+
var KEY_BYTES = 24;
|
|
6803
|
+
var DISPLAY_PREFIX_LEN = KEY_PREFIX.length + 8;
|
|
6804
|
+
function generateApiKeySecret() {
|
|
6805
|
+
const bytes = new Uint8Array(KEY_BYTES);
|
|
6806
|
+
crypto.getRandomValues(bytes);
|
|
6807
|
+
let hex = "";
|
|
6808
|
+
for (const b of bytes) hex += b.toString(16).padStart(2, "0");
|
|
6809
|
+
return KEY_PREFIX + hex;
|
|
6810
|
+
}
|
|
6811
|
+
async function hashApiKey(secret) {
|
|
6812
|
+
const data = new TextEncoder().encode(secret);
|
|
6813
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
6814
|
+
const view = new Uint8Array(digest);
|
|
6815
|
+
let hex = "";
|
|
6816
|
+
for (const b of view) hex += b.toString(16).padStart(2, "0");
|
|
6817
|
+
return hex;
|
|
6818
|
+
}
|
|
6819
|
+
var ApiKeyService = class {
|
|
6820
|
+
constructor(db, tenantId = "default") {
|
|
6821
|
+
this.db = db;
|
|
6822
|
+
this.tenantId = tenantId;
|
|
6823
|
+
}
|
|
6824
|
+
db;
|
|
6825
|
+
tenantId;
|
|
6826
|
+
docService() {
|
|
6827
|
+
return new chunkLTZ5WYOK_cjs.DocumentsService(this.db, {
|
|
6828
|
+
queryableFields: API_KEY_QUERYABLE,
|
|
6829
|
+
tenantId: this.tenantId,
|
|
6830
|
+
maxVersionsPerRoot: 1
|
|
6831
|
+
});
|
|
6832
|
+
}
|
|
6833
|
+
/** Count a user's active (non-revoked) keys — used to enforce the per-user cap. */
|
|
6834
|
+
async countForUser(userId) {
|
|
6835
|
+
const row = await this.db.prepare(
|
|
6836
|
+
`SELECT COUNT(*) AS c FROM documents
|
|
6837
|
+
WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
|
|
6838
|
+
AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0`
|
|
6839
|
+
).bind(this.tenantId, userId).first();
|
|
6840
|
+
return row?.c ?? 0;
|
|
6841
|
+
}
|
|
6842
|
+
/**
|
|
6843
|
+
* Mint a new key for a user. The returned `key` is the only time the plaintext
|
|
6844
|
+
* exists outside the caller — it is hashed before storage.
|
|
6845
|
+
*/
|
|
6846
|
+
async create(input) {
|
|
6847
|
+
const name = input.name.trim() || "API Key";
|
|
6848
|
+
const secret = generateApiKeySecret();
|
|
6849
|
+
const keyHash = await hashApiKey(secret);
|
|
6850
|
+
const prefix = secret.slice(0, DISPLAY_PREFIX_LEN);
|
|
6851
|
+
const expiresAt = input.expiresAt ?? null;
|
|
6852
|
+
const doc = await this.docService().create(
|
|
6853
|
+
chunk7RUW244J_cjs.createDocumentSchema.parse({
|
|
6854
|
+
typeId: "api_key",
|
|
6855
|
+
tenantId: this.tenantId,
|
|
6856
|
+
title: name,
|
|
6857
|
+
ownerId: input.userId,
|
|
6858
|
+
publishOnCreate: true,
|
|
6859
|
+
data: {
|
|
6860
|
+
name,
|
|
6861
|
+
userId: input.userId,
|
|
6862
|
+
keyHash,
|
|
6863
|
+
keyPrefix: prefix,
|
|
6864
|
+
revoked: 0,
|
|
6865
|
+
lastUsedAt: null,
|
|
6866
|
+
expiresAt
|
|
6867
|
+
}
|
|
6868
|
+
}),
|
|
6869
|
+
input.userId
|
|
6870
|
+
);
|
|
6871
|
+
return { id: doc.rootId, key: secret, name, prefix, expiresAt };
|
|
6872
|
+
}
|
|
6873
|
+
/** List a user's non-revoked keys (metadata only — never the secret or hash). */
|
|
6874
|
+
async list(userId) {
|
|
6875
|
+
const res = await this.db.prepare(
|
|
6876
|
+
`SELECT root_id, data, created_at FROM documents
|
|
6877
|
+
WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
|
|
6878
|
+
AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0
|
|
6879
|
+
ORDER BY created_at DESC`
|
|
6880
|
+
).bind(this.tenantId, userId).all();
|
|
6881
|
+
return (res.results ?? []).map((row) => {
|
|
6882
|
+
const d = JSON.parse(row.data);
|
|
6883
|
+
return {
|
|
6884
|
+
id: row.root_id,
|
|
6885
|
+
name: d.name ?? "API Key",
|
|
6886
|
+
prefix: d.keyPrefix ?? "",
|
|
6887
|
+
createdAt: row.created_at,
|
|
6888
|
+
lastUsedAt: d.lastUsedAt ?? null,
|
|
6889
|
+
expiresAt: d.expiresAt ?? null
|
|
6890
|
+
};
|
|
6891
|
+
});
|
|
6892
|
+
}
|
|
6893
|
+
/**
|
|
6894
|
+
* Revoke (hard-delete) a key owned by `userId`. Credentials are erased, not
|
|
6895
|
+
* soft-flagged. Returns false if the key does not exist or is not owned by
|
|
6896
|
+
* the caller (no information leak about other users' keys).
|
|
6897
|
+
*/
|
|
6898
|
+
async revoke(rootId, userId) {
|
|
6899
|
+
const row = await this.db.prepare(
|
|
6900
|
+
`SELECT q_apikey_user_id AS owner FROM documents
|
|
6901
|
+
WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1 AND deleted_at IS NULL`
|
|
6902
|
+
).bind(rootId, this.tenantId).first();
|
|
6903
|
+
if (!row || row.owner !== userId) return false;
|
|
6904
|
+
await this.docService().erase(rootId, this.tenantId);
|
|
6905
|
+
return true;
|
|
6906
|
+
}
|
|
6907
|
+
/**
|
|
6908
|
+
* Resolve a presented secret to its owning user, or null. Rejects unknown,
|
|
6909
|
+
* revoked, expired keys and inactive users. Best-effort updates lastUsedAt.
|
|
6910
|
+
*/
|
|
6911
|
+
async resolve(secret) {
|
|
6912
|
+
if (!secret || !secret.startsWith(KEY_PREFIX)) return null;
|
|
6913
|
+
const keyHash = await hashApiKey(secret);
|
|
6914
|
+
const keyRow2 = await this.db.prepare(
|
|
6915
|
+
`SELECT root_id, data FROM documents
|
|
6916
|
+
WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL
|
|
6917
|
+
AND q_apikey_hash = ? AND q_apikey_revoked = 0
|
|
6918
|
+
LIMIT 1`
|
|
6919
|
+
).bind(this.tenantId, keyHash).first();
|
|
6920
|
+
if (!keyRow2) return null;
|
|
6921
|
+
const d = JSON.parse(keyRow2.data);
|
|
6922
|
+
if (d.expiresAt != null && Date.now() > Number(d.expiresAt)) return null;
|
|
6923
|
+
const user = await this.db.prepare(`SELECT id, email, role, is_active, is_super_admin FROM auth_user WHERE id = ?`).bind(d.userId).first();
|
|
6924
|
+
if (!user || user.is_active !== 1) return null;
|
|
6925
|
+
try {
|
|
6926
|
+
await this.touchLastUsed(keyRow2.root_id, d);
|
|
6927
|
+
} catch {
|
|
6928
|
+
}
|
|
6929
|
+
return {
|
|
6930
|
+
userId: user.id,
|
|
6931
|
+
email: user.email,
|
|
6932
|
+
role: user.role ?? "viewer",
|
|
6933
|
+
isSuperAdmin: user.is_super_admin === 1
|
|
6934
|
+
};
|
|
6935
|
+
}
|
|
6936
|
+
/** Update lastUsedAt in-place (single-version type, no history churn). */
|
|
6937
|
+
async touchLastUsed(rootId, data) {
|
|
6938
|
+
const next = JSON.stringify({ ...data, lastUsedAt: Date.now() });
|
|
6939
|
+
await this.db.prepare(
|
|
6940
|
+
`UPDATE documents SET data = ? WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1`
|
|
6941
|
+
).bind(next, rootId, this.tenantId).run();
|
|
6942
|
+
}
|
|
6943
|
+
};
|
|
6944
|
+
|
|
6945
|
+
// src/plugins/core-plugins/api-keys-plugin/components/keys-page.ts
|
|
6946
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
6947
|
+
function fmtDate(ms) {
|
|
6948
|
+
if (!ms) return "\u2014";
|
|
6949
|
+
try {
|
|
6950
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
6951
|
+
} catch {
|
|
6952
|
+
return "\u2014";
|
|
6953
|
+
}
|
|
6954
|
+
}
|
|
6955
|
+
function keyRow(k) {
|
|
6956
|
+
const name = chunkMNWKYY5E_cjs.escapeHtml(k.name);
|
|
6957
|
+
const prefix = chunkMNWKYY5E_cjs.escapeHtml(k.prefix);
|
|
6958
|
+
const id = chunkMNWKYY5E_cjs.escapeHtml(k.id);
|
|
6959
|
+
return `
|
|
6960
|
+
<tr class="border-t border-zinc-950/5 dark:border-white/10" data-key-id="${id}">
|
|
6961
|
+
<td class="py-3 pr-4 text-sm font-medium text-zinc-950 dark:text-white">${name}</td>
|
|
6962
|
+
<td class="py-3 pr-4 text-sm font-mono text-zinc-500 dark:text-zinc-400">${prefix}\u2026</td>
|
|
6963
|
+
<td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${fmtDate(k.createdAt ? k.createdAt * 1e3 : null)}</td>
|
|
6964
|
+
<td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.lastUsedAt ? fmtDate(k.lastUsedAt) : "Never"}</td>
|
|
6965
|
+
<td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.expiresAt ? fmtDate(k.expiresAt) : "Never"}</td>
|
|
6966
|
+
<td class="py-3 text-right">
|
|
6967
|
+
<button type="button" onclick="revokeApiKey('${id}', '${name.replace(/'/g, "\\'")}')"
|
|
6968
|
+
class="rounded-lg bg-red-50 dark:bg-red-900/20 px-3 py-1.5 text-sm font-medium text-red-700 dark:text-red-400 hover:bg-red-100 dark:hover:bg-red-900/40 ring-1 ring-red-200 dark:ring-red-800 transition-colors">
|
|
6969
|
+
Revoke
|
|
6970
|
+
</button>
|
|
6971
|
+
</td>
|
|
6972
|
+
</tr>`;
|
|
6973
|
+
}
|
|
6974
|
+
function renderApiKeysPage(data) {
|
|
6975
|
+
const { keys, user, version, dynamicMenuItems } = data;
|
|
6976
|
+
const rows = keys.length ? keys.map(keyRow).join("") : `<tr><td colspan="6" class="py-8 text-center text-sm text-zinc-500 dark:text-zinc-400">No API keys yet. Create one to enable programmatic access.</td></tr>`;
|
|
6977
|
+
const content2 = `
|
|
6978
|
+
<div>
|
|
6979
|
+
<div class="sm:flex sm:items-center sm:justify-between mb-6">
|
|
6980
|
+
<div class="sm:flex-auto">
|
|
6981
|
+
<h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">API Keys</h1>
|
|
6982
|
+
<p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
|
|
6983
|
+
Long-lived secrets for headless / server-to-server REST access. Send a key as the
|
|
6984
|
+
<code class="font-mono">x-api-key</code> header or <code class="font-mono">Authorization: Bearer <key></code>.
|
|
6985
|
+
The secret is shown once at creation \u2014 store it now.
|
|
6986
|
+
</p>
|
|
6987
|
+
</div>
|
|
6988
|
+
<div class="mt-4 sm:mt-0 sm:ml-16">
|
|
6989
|
+
<button type="button" onclick="document.getElementById('create-key-modal').classList.remove('hidden')"
|
|
6990
|
+
class="inline-flex items-center justify-center rounded-lg bg-cyan-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors shadow-sm">
|
|
6991
|
+
Create API key
|
|
6992
|
+
</button>
|
|
6993
|
+
</div>
|
|
6994
|
+
</div>
|
|
6995
|
+
|
|
6996
|
+
<!-- Newly-created secret banner (populated by JS, shown once) -->
|
|
6997
|
+
<div id="new-key-banner" class="hidden mb-6 rounded-xl bg-emerald-50 dark:bg-emerald-900/20 p-4 ring-1 ring-emerald-200 dark:ring-emerald-800">
|
|
6998
|
+
<p class="text-sm font-medium text-emerald-800 dark:text-emerald-300 mb-2">
|
|
6999
|
+
Copy your new key now \u2014 it will not be shown again.
|
|
7000
|
+
</p>
|
|
7001
|
+
<div class="flex items-center gap-2">
|
|
7002
|
+
<code id="new-key-value" class="flex-1 rounded-lg bg-white dark:bg-zinc-900 px-3 py-2 text-sm font-mono text-zinc-950 dark:text-white ring-1 ring-zinc-950/10 dark:ring-white/10 break-all"></code>
|
|
7003
|
+
<button type="button" onclick="copyNewKey()"
|
|
7004
|
+
class="rounded-lg bg-emerald-600 px-3 py-2 text-sm font-semibold text-white hover:bg-emerald-500 transition-colors">
|
|
7005
|
+
Copy
|
|
7006
|
+
</button>
|
|
7007
|
+
</div>
|
|
7008
|
+
</div>
|
|
7009
|
+
|
|
7010
|
+
<div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-6 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm overflow-x-auto">
|
|
7011
|
+
<table class="w-full text-left">
|
|
7012
|
+
<thead>
|
|
7013
|
+
<tr class="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
|
|
7014
|
+
<th class="pb-2 pr-4">Name</th>
|
|
7015
|
+
<th class="pb-2 pr-4">Prefix</th>
|
|
7016
|
+
<th class="pb-2 pr-4">Created</th>
|
|
7017
|
+
<th class="pb-2 pr-4">Last used</th>
|
|
7018
|
+
<th class="pb-2 pr-4">Expires</th>
|
|
7019
|
+
<th class="pb-2 text-right">Actions</th>
|
|
7020
|
+
</tr>
|
|
7021
|
+
</thead>
|
|
7022
|
+
<tbody id="keys-tbody">${rows}</tbody>
|
|
7023
|
+
</table>
|
|
7024
|
+
</div>
|
|
7025
|
+
</div>
|
|
7026
|
+
|
|
7027
|
+
<!-- Create modal -->
|
|
7028
|
+
<div id="create-key-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
|
|
7029
|
+
<div class="w-full max-w-md rounded-xl bg-white dark:bg-zinc-900 p-6 ring-1 ring-zinc-950/10 dark:ring-white/10 shadow-xl">
|
|
7030
|
+
<h2 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Create API key</h2>
|
|
7031
|
+
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Name</label>
|
|
7032
|
+
<input id="new-key-name" type="text" placeholder="e.g. CI deploy token"
|
|
7033
|
+
class="w-full rounded-lg border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white mb-4 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
|
|
7034
|
+
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Expires in (days, optional)</label>
|
|
7035
|
+
<input id="new-key-expiry" type="number" min="1" max="3650" placeholder="Never"
|
|
7036
|
+
class="w-full rounded-lg border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white mb-4 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
|
|
7037
|
+
<div class="flex justify-end gap-2">
|
|
7038
|
+
<button type="button" onclick="document.getElementById('create-key-modal').classList.add('hidden')"
|
|
7039
|
+
class="rounded-lg bg-white dark:bg-zinc-800 px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
|
|
7040
|
+
Cancel
|
|
7041
|
+
</button>
|
|
7042
|
+
<button type="button" onclick="createApiKey()"
|
|
7043
|
+
class="rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors">
|
|
7044
|
+
Create
|
|
7045
|
+
</button>
|
|
7046
|
+
</div>
|
|
7047
|
+
</div>
|
|
7048
|
+
</div>
|
|
7049
|
+
|
|
7050
|
+
<script>
|
|
7051
|
+
// CSRF: the csrf_token cookie is JS-readable (httpOnly:false); echo it back
|
|
7052
|
+
// as X-CSRF-Token on state-changing requests (signed double-submit).
|
|
7053
|
+
function csrfHeader() {
|
|
7054
|
+
const m = document.cookie.match(/(?:^|; )csrf_token=([^;]+)/)
|
|
7055
|
+
return m ? { 'X-CSRF-Token': decodeURIComponent(m[1]) } : {}
|
|
7056
|
+
}
|
|
7057
|
+
async function createApiKey() {
|
|
7058
|
+
const name = document.getElementById('new-key-name').value.trim()
|
|
7059
|
+
if (!name) { window.showNotification && window.showNotification('Name is required', 'error'); return }
|
|
7060
|
+
const expiry = parseInt(document.getElementById('new-key-expiry').value, 10)
|
|
7061
|
+
const body = { name }
|
|
7062
|
+
if (Number.isFinite(expiry) && expiry > 0) body.expiresInDays = expiry
|
|
7063
|
+
const res = await fetch('/admin/plugins/api-keys/api/keys', {
|
|
7064
|
+
method: 'POST',
|
|
7065
|
+
headers: { 'Content-Type': 'application/json', ...csrfHeader() },
|
|
7066
|
+
body: JSON.stringify(body),
|
|
7067
|
+
})
|
|
7068
|
+
if (!res.ok) {
|
|
7069
|
+
const e = await res.json().catch(() => ({}))
|
|
7070
|
+
window.showNotification && window.showNotification(e.error || 'Failed to create key', 'error')
|
|
7071
|
+
return
|
|
7072
|
+
}
|
|
7073
|
+
const { apiKey } = await res.json()
|
|
7074
|
+
document.getElementById('create-key-modal').classList.add('hidden')
|
|
7075
|
+
document.getElementById('new-key-value').textContent = apiKey.key
|
|
7076
|
+
document.getElementById('new-key-banner').classList.remove('hidden')
|
|
7077
|
+
setTimeout(() => location.reload(), 1500)
|
|
7078
|
+
}
|
|
7079
|
+
function copyNewKey() {
|
|
7080
|
+
const v = document.getElementById('new-key-value').textContent
|
|
7081
|
+
navigator.clipboard.writeText(v).then(() => window.showNotification && window.showNotification('Copied', 'success'))
|
|
7082
|
+
}
|
|
7083
|
+
async function revokeApiKey(id, name) {
|
|
7084
|
+
if (!confirm('Revoke "' + name + '"? This cannot be undone and will break any client using it.')) return
|
|
7085
|
+
const res = await fetch('/admin/plugins/api-keys/api/keys/' + id, { method: 'DELETE', headers: { ...csrfHeader() } })
|
|
7086
|
+
if (res.ok) {
|
|
7087
|
+
const row = document.querySelector('[data-key-id="' + id + '"]')
|
|
7088
|
+
if (row) row.remove()
|
|
7089
|
+
window.showNotification && window.showNotification('Key revoked', 'success')
|
|
7090
|
+
} else {
|
|
7091
|
+
window.showNotification && window.showNotification('Failed to revoke', 'error')
|
|
7092
|
+
}
|
|
7093
|
+
}
|
|
7094
|
+
</script>`;
|
|
7095
|
+
const layoutData = {
|
|
7096
|
+
title: "API Keys",
|
|
7097
|
+
pageTitle: "API Keys",
|
|
7098
|
+
currentPath: "/admin/plugins/api-keys",
|
|
7099
|
+
user,
|
|
7100
|
+
content: content2,
|
|
7101
|
+
version,
|
|
7102
|
+
dynamicMenuItems
|
|
7103
|
+
};
|
|
7104
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
7105
|
+
}
|
|
7106
|
+
|
|
7107
|
+
// src/plugins/core-plugins/api-keys-plugin/types.ts
|
|
7108
|
+
var DEFAULT_SETTINGS3 = {
|
|
7109
|
+
maxKeysPerUser: 50,
|
|
7110
|
+
defaultExpiryDays: 0
|
|
7111
|
+
};
|
|
7112
|
+
|
|
7113
|
+
// src/plugins/core-plugins/api-keys-plugin/routes/admin.ts
|
|
7114
|
+
var adminRoutes4 = new hono.Hono();
|
|
7115
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
7116
|
+
var createSchema = zod.z.object({
|
|
7117
|
+
name: zod.z.string().min(1).max(100),
|
|
7118
|
+
// Optional lifetime in days; omitted/null → plugin default (which may be "never").
|
|
7119
|
+
expiresInDays: zod.z.number().int().positive().max(3650).nullish()
|
|
7120
|
+
});
|
|
7121
|
+
async function getSettings3(db) {
|
|
7122
|
+
try {
|
|
7123
|
+
const plugin2 = await new chunkKVBHB7QP_cjs.PluginService(db).getPlugin("api-keys");
|
|
7124
|
+
if (plugin2?.settings) {
|
|
7125
|
+
const s = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
7126
|
+
return { ...DEFAULT_SETTINGS3, ...s };
|
|
7127
|
+
}
|
|
7128
|
+
} catch {
|
|
7129
|
+
}
|
|
7130
|
+
return DEFAULT_SETTINGS3;
|
|
7131
|
+
}
|
|
7132
|
+
adminRoutes4.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
7133
|
+
adminRoutes4.use("*", async (c, next) => {
|
|
7134
|
+
const user = c.get("user");
|
|
7135
|
+
if (user?.role !== "admin") {
|
|
7136
|
+
return c.json({ error: "Access denied" }, 403);
|
|
7137
|
+
}
|
|
7138
|
+
return next();
|
|
7139
|
+
});
|
|
7140
|
+
adminRoutes4.get("/", async (c) => {
|
|
7141
|
+
const user = c.get("user");
|
|
7142
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7143
|
+
const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
|
|
7144
|
+
return c.html(
|
|
7145
|
+
renderApiKeysPage({
|
|
7146
|
+
keys,
|
|
7147
|
+
user: { name: user.email, email: user.email, role: user.role },
|
|
7148
|
+
version: c.get("appVersion"),
|
|
7149
|
+
dynamicMenuItems: c.get("pluginMenuItems")
|
|
7150
|
+
})
|
|
7151
|
+
);
|
|
7152
|
+
});
|
|
7153
|
+
adminRoutes4.get("/api/keys", async (c) => {
|
|
7154
|
+
const user = c.get("user");
|
|
7155
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7156
|
+
const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
|
|
7157
|
+
return c.json({ keys });
|
|
7158
|
+
});
|
|
7159
|
+
adminRoutes4.post("/api/keys", async (c) => {
|
|
7160
|
+
const user = c.get("user");
|
|
7161
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7162
|
+
const body = await c.req.json().catch(() => ({}));
|
|
7163
|
+
const parsed = createSchema.safeParse(body);
|
|
7164
|
+
if (!parsed.success) {
|
|
7165
|
+
return c.json({ error: "Invalid request", details: parsed.error.flatten() }, 400);
|
|
7166
|
+
}
|
|
7167
|
+
const settings = await getSettings3(c.env.DB);
|
|
7168
|
+
const svc = new ApiKeyService(c.env.DB, tenantId);
|
|
7169
|
+
if (await svc.countForUser(user.userId) >= settings.maxKeysPerUser) {
|
|
7170
|
+
return c.json({ error: `API key limit reached (max ${settings.maxKeysPerUser})` }, 409);
|
|
7171
|
+
}
|
|
7172
|
+
const days = parsed.data.expiresInDays ?? (settings.defaultExpiryDays > 0 ? settings.defaultExpiryDays : null);
|
|
7173
|
+
const expiresAt = days ? Date.now() + days * DAY_MS : null;
|
|
7174
|
+
const created = await svc.create({ userId: user.userId, name: parsed.data.name, expiresAt });
|
|
7175
|
+
return c.json({ apiKey: created }, 201);
|
|
7176
|
+
});
|
|
7177
|
+
adminRoutes4.delete("/api/keys/:id", async (c) => {
|
|
7178
|
+
const user = c.get("user");
|
|
7179
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7180
|
+
const ok = await new ApiKeyService(c.env.DB, tenantId).revoke(c.req.param("id") ?? "", user.userId);
|
|
7181
|
+
if (!ok) return c.json({ error: "API key not found" }, 404);
|
|
7182
|
+
return c.json({ success: true });
|
|
7183
|
+
});
|
|
7184
|
+
|
|
7185
|
+
// src/plugins/core-plugins/api-keys-plugin/middleware/api-key-auth.ts
|
|
7186
|
+
function apiKeyAuthMiddleware() {
|
|
7187
|
+
return async (c, next) => {
|
|
7188
|
+
if (!c.get("user")) {
|
|
7189
|
+
const authz = c.req.header("authorization") || "";
|
|
7190
|
+
const bearer = authz.toLowerCase().startsWith("bearer ") ? authz.slice(7).trim() : "";
|
|
7191
|
+
const presented = c.req.header("x-api-key") || (bearer.startsWith("sk_") ? bearer : "");
|
|
7192
|
+
if (presented) {
|
|
7193
|
+
try {
|
|
7194
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7195
|
+
const resolved = await new ApiKeyService(c.env.DB, tenantId).resolve(presented);
|
|
7196
|
+
if (resolved) {
|
|
7197
|
+
c.set("user", {
|
|
7198
|
+
userId: resolved.userId,
|
|
7199
|
+
email: resolved.email,
|
|
7200
|
+
role: resolved.role,
|
|
7201
|
+
isSuperAdmin: resolved.isSuperAdmin,
|
|
7202
|
+
// API keys are stateless bearer creds — no session window.
|
|
7203
|
+
exp: 0,
|
|
7204
|
+
iat: 0
|
|
7205
|
+
});
|
|
7206
|
+
}
|
|
7207
|
+
} catch {
|
|
7208
|
+
}
|
|
7209
|
+
}
|
|
7210
|
+
}
|
|
7211
|
+
await next();
|
|
7212
|
+
};
|
|
7213
|
+
}
|
|
7214
|
+
|
|
7215
|
+
// src/plugins/core-plugins/api-keys-plugin/index.ts
|
|
7216
|
+
var KEY_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/></svg>`;
|
|
7217
|
+
var apiKeysPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
7218
|
+
id: "api-keys",
|
|
7219
|
+
version: "1.0.0-beta.1",
|
|
7220
|
+
name: "API Keys",
|
|
7221
|
+
description: "Programmatic API access keys for headless / server-to-server REST access.",
|
|
7222
|
+
sonicjsVersionRange: "^3.0.0",
|
|
7223
|
+
author: { name: "SonicJS Team" },
|
|
7224
|
+
register(app2) {
|
|
7225
|
+
app2.route("/admin/plugins/api-keys", adminRoutes4);
|
|
7226
|
+
},
|
|
7227
|
+
menu: [
|
|
7228
|
+
{ label: "API Keys", path: "/admin/plugins/api-keys", icon: KEY_ICON, order: 86 }
|
|
7229
|
+
],
|
|
7230
|
+
configSchema: {
|
|
7231
|
+
maxKeysPerUser: {
|
|
7232
|
+
type: "number",
|
|
7233
|
+
label: "Max keys per user",
|
|
7234
|
+
description: "Hard cap on active keys a single user may hold.",
|
|
7235
|
+
default: 50
|
|
7236
|
+
},
|
|
7237
|
+
defaultExpiryDays: {
|
|
7238
|
+
type: "number",
|
|
7239
|
+
label: "Default expiry (days)",
|
|
7240
|
+
description: "Lifetime applied to new keys when no explicit expiry is given. 0 = never expires.",
|
|
7241
|
+
default: 0
|
|
7242
|
+
}
|
|
7243
|
+
},
|
|
7244
|
+
activate: async () => console.log("[ApiKeys] Plugin activated"),
|
|
7245
|
+
deactivate: async () => console.log("[ApiKeys] Plugin deactivated")
|
|
7246
|
+
});
|
|
7247
|
+
|
|
6637
7248
|
// src/plugins/core-plugins/stripe-plugin/services/subscription-service.ts
|
|
6638
7249
|
var SubscriptionService = class {
|
|
6639
7250
|
constructor(db) {
|
|
6640
7251
|
this.db = db;
|
|
6641
7252
|
}
|
|
7253
|
+
db;
|
|
6642
7254
|
/**
|
|
6643
7255
|
* Ensure the subscriptions table exists
|
|
6644
7256
|
*/
|
|
@@ -6877,6 +7489,7 @@ var StripeEventService = class {
|
|
|
6877
7489
|
constructor(db) {
|
|
6878
7490
|
this.db = db;
|
|
6879
7491
|
}
|
|
7492
|
+
db;
|
|
6880
7493
|
async ensureTable() {
|
|
6881
7494
|
await this.db.prepare(`
|
|
6882
7495
|
CREATE TABLE IF NOT EXISTS stripe_events (
|
|
@@ -6987,7 +7600,7 @@ var StripeEventService = class {
|
|
|
6987
7600
|
};
|
|
6988
7601
|
|
|
6989
7602
|
// src/plugins/core-plugins/stripe-plugin/components/subscriptions-page.ts
|
|
6990
|
-
|
|
7603
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
6991
7604
|
|
|
6992
7605
|
// src/plugins/core-plugins/stripe-plugin/components/tab-bar.ts
|
|
6993
7606
|
var TABS = [
|
|
@@ -7120,7 +7733,7 @@ function renderSubscriptionsPage(data) {
|
|
|
7120
7733
|
version,
|
|
7121
7734
|
dynamicMenuItems
|
|
7122
7735
|
};
|
|
7123
|
-
return
|
|
7736
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
7124
7737
|
}
|
|
7125
7738
|
function statsCard(label, value, colorClass) {
|
|
7126
7739
|
return `
|
|
@@ -7200,7 +7813,7 @@ function renderPagination2(page, totalPages, status) {
|
|
|
7200
7813
|
}
|
|
7201
7814
|
|
|
7202
7815
|
// src/plugins/core-plugins/stripe-plugin/components/events-page.ts
|
|
7203
|
-
|
|
7816
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
7204
7817
|
function renderEventsPage(data) {
|
|
7205
7818
|
const { events, stats, types, filters, user, version, dynamicMenuItems } = data;
|
|
7206
7819
|
const content2 = `
|
|
@@ -7273,7 +7886,7 @@ function renderEventsPage(data) {
|
|
|
7273
7886
|
version,
|
|
7274
7887
|
dynamicMenuItems
|
|
7275
7888
|
};
|
|
7276
|
-
return
|
|
7889
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
7277
7890
|
}
|
|
7278
7891
|
function eventStatsCard(label, value, colorClass) {
|
|
7279
7892
|
return `
|
|
@@ -7361,7 +7974,7 @@ function renderEventPagination(page, totalPages, type, status) {
|
|
|
7361
7974
|
}
|
|
7362
7975
|
|
|
7363
7976
|
// src/plugins/core-plugins/stripe-plugin/types.ts
|
|
7364
|
-
var
|
|
7977
|
+
var DEFAULT_SETTINGS4 = {
|
|
7365
7978
|
stripePublishableKey: "",
|
|
7366
7979
|
stripeSecretKey: "",
|
|
7367
7980
|
stripeWebhookSecret: "",
|
|
@@ -7371,28 +7984,28 @@ var DEFAULT_SETTINGS3 = {
|
|
|
7371
7984
|
};
|
|
7372
7985
|
|
|
7373
7986
|
// src/plugins/core-plugins/stripe-plugin/routes/admin.ts
|
|
7374
|
-
var
|
|
7375
|
-
|
|
7376
|
-
|
|
7987
|
+
var adminRoutes5 = new hono.Hono();
|
|
7988
|
+
adminRoutes5.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
7989
|
+
adminRoutes5.use("*", async (c, next) => {
|
|
7377
7990
|
const user = c.get("user");
|
|
7378
7991
|
if (user?.role !== "admin") {
|
|
7379
7992
|
return c.text("Access denied", 403);
|
|
7380
7993
|
}
|
|
7381
7994
|
return next();
|
|
7382
7995
|
});
|
|
7383
|
-
async function
|
|
7996
|
+
async function getSettings4(db) {
|
|
7384
7997
|
try {
|
|
7385
|
-
const pluginService = new
|
|
7998
|
+
const pluginService = new chunkKVBHB7QP_cjs.PluginService(db);
|
|
7386
7999
|
const plugin2 = await pluginService.getPlugin("stripe");
|
|
7387
8000
|
if (plugin2?.settings) {
|
|
7388
8001
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
7389
|
-
return { ...
|
|
8002
|
+
return { ...DEFAULT_SETTINGS4, ...settings };
|
|
7390
8003
|
}
|
|
7391
8004
|
} catch {
|
|
7392
8005
|
}
|
|
7393
|
-
return
|
|
8006
|
+
return DEFAULT_SETTINGS4;
|
|
7394
8007
|
}
|
|
7395
|
-
|
|
8008
|
+
adminRoutes5.get("/", async (c) => {
|
|
7396
8009
|
const db = c.env.DB;
|
|
7397
8010
|
const user = c.get("user");
|
|
7398
8011
|
const subscriptionService = new SubscriptionService(db);
|
|
@@ -7415,7 +8028,7 @@ adminRoutes4.get("/", async (c) => {
|
|
|
7415
8028
|
});
|
|
7416
8029
|
return c.html(html4);
|
|
7417
8030
|
});
|
|
7418
|
-
|
|
8031
|
+
adminRoutes5.get("/events", async (c) => {
|
|
7419
8032
|
const db = c.env.DB;
|
|
7420
8033
|
const user = c.get("user");
|
|
7421
8034
|
const eventService = new StripeEventService(db);
|
|
@@ -7441,11 +8054,11 @@ adminRoutes4.get("/events", async (c) => {
|
|
|
7441
8054
|
});
|
|
7442
8055
|
return c.html(html4);
|
|
7443
8056
|
});
|
|
7444
|
-
|
|
8057
|
+
adminRoutes5.get("/settings", async (c) => {
|
|
7445
8058
|
const db = c.env.DB;
|
|
7446
8059
|
const user = c.get("user");
|
|
7447
|
-
const settings = await
|
|
7448
|
-
const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-
|
|
8060
|
+
const settings = await getSettings4(db);
|
|
8061
|
+
const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-KDHKVLXR.cjs');
|
|
7449
8062
|
const content2 = `
|
|
7450
8063
|
<div>
|
|
7451
8064
|
<div class="mb-6">
|
|
@@ -7551,7 +8164,7 @@ adminRoutes4.get("/settings", async (c) => {
|
|
|
7551
8164
|
dynamicMenuItems: c.get("pluginMenuItems")
|
|
7552
8165
|
}));
|
|
7553
8166
|
});
|
|
7554
|
-
|
|
8167
|
+
adminRoutes5.post("/settings", async (c) => {
|
|
7555
8168
|
try {
|
|
7556
8169
|
const body = await c.req.json();
|
|
7557
8170
|
const db = c.env.DB;
|
|
@@ -7573,6 +8186,7 @@ var StripeAPI = class {
|
|
|
7573
8186
|
constructor(secretKey) {
|
|
7574
8187
|
this.secretKey = secretKey;
|
|
7575
8188
|
}
|
|
8189
|
+
secretKey;
|
|
7576
8190
|
baseUrl = "https://api.stripe.com/v1";
|
|
7577
8191
|
/**
|
|
7578
8192
|
* Verify a webhook signature
|
|
@@ -7702,17 +8316,17 @@ function timingSafeEqual(a, b) {
|
|
|
7702
8316
|
|
|
7703
8317
|
// src/plugins/core-plugins/stripe-plugin/routes/api.ts
|
|
7704
8318
|
var apiRoutes3 = new hono.Hono();
|
|
7705
|
-
async function
|
|
8319
|
+
async function getSettings5(db) {
|
|
7706
8320
|
try {
|
|
7707
|
-
const pluginService = new
|
|
8321
|
+
const pluginService = new chunkKVBHB7QP_cjs.PluginService(db);
|
|
7708
8322
|
const plugin2 = await pluginService.getPlugin("stripe");
|
|
7709
8323
|
if (plugin2?.settings) {
|
|
7710
8324
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
7711
|
-
return { ...
|
|
8325
|
+
return { ...DEFAULT_SETTINGS4, ...settings };
|
|
7712
8326
|
}
|
|
7713
8327
|
} catch {
|
|
7714
8328
|
}
|
|
7715
|
-
return
|
|
8329
|
+
return DEFAULT_SETTINGS4;
|
|
7716
8330
|
}
|
|
7717
8331
|
function mapStripeStatus(status) {
|
|
7718
8332
|
const map = {
|
|
@@ -7729,7 +8343,7 @@ function mapStripeStatus(status) {
|
|
|
7729
8343
|
}
|
|
7730
8344
|
apiRoutes3.post("/webhook", async (c) => {
|
|
7731
8345
|
const db = c.env.DB;
|
|
7732
|
-
const settings = await
|
|
8346
|
+
const settings = await getSettings5(db);
|
|
7733
8347
|
if (!settings.stripeWebhookSecret) {
|
|
7734
8348
|
return c.json({ error: "Webhook secret not configured" }, 500);
|
|
7735
8349
|
}
|
|
@@ -7855,11 +8469,11 @@ apiRoutes3.post("/webhook", async (c) => {
|
|
|
7855
8469
|
}
|
|
7856
8470
|
return c.json({ received: true });
|
|
7857
8471
|
});
|
|
7858
|
-
apiRoutes3.post("/create-checkout-session",
|
|
8472
|
+
apiRoutes3.post("/create-checkout-session", chunkFCLKX2OS_cjs.requireAuth(), async (c) => {
|
|
7859
8473
|
const db = c.env.DB;
|
|
7860
8474
|
const user = c.get("user");
|
|
7861
8475
|
if (!user) return c.json({ error: "Unauthorized" }, 401);
|
|
7862
|
-
const settings = await
|
|
8476
|
+
const settings = await getSettings5(db);
|
|
7863
8477
|
if (!settings.stripeSecretKey) {
|
|
7864
8478
|
return c.json({ error: "Stripe not configured" }, 500);
|
|
7865
8479
|
}
|
|
@@ -7895,7 +8509,7 @@ apiRoutes3.post("/create-checkout-session", chunkAAWNRBRB_cjs.requireAuth(), asy
|
|
|
7895
8509
|
});
|
|
7896
8510
|
return c.json({ sessionId: session.id, url: session.url });
|
|
7897
8511
|
});
|
|
7898
|
-
apiRoutes3.get("/subscription",
|
|
8512
|
+
apiRoutes3.get("/subscription", chunkFCLKX2OS_cjs.requireAuth(), async (c) => {
|
|
7899
8513
|
const user = c.get("user");
|
|
7900
8514
|
if (!user) return c.json({ error: "Unauthorized" }, 401);
|
|
7901
8515
|
const db = c.env.DB;
|
|
@@ -7907,7 +8521,7 @@ apiRoutes3.get("/subscription", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
|
|
|
7907
8521
|
}
|
|
7908
8522
|
return c.json({ subscription });
|
|
7909
8523
|
});
|
|
7910
|
-
apiRoutes3.get("/subscriptions",
|
|
8524
|
+
apiRoutes3.get("/subscriptions", chunkFCLKX2OS_cjs.requireAuth(), async (c) => {
|
|
7911
8525
|
const user = c.get("user");
|
|
7912
8526
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
7913
8527
|
const db = c.env.DB;
|
|
@@ -7923,7 +8537,7 @@ apiRoutes3.get("/subscriptions", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
|
|
|
7923
8537
|
const result = await subscriptionService.list(filters);
|
|
7924
8538
|
return c.json(result);
|
|
7925
8539
|
});
|
|
7926
|
-
apiRoutes3.get("/stats",
|
|
8540
|
+
apiRoutes3.get("/stats", chunkFCLKX2OS_cjs.requireAuth(), async (c) => {
|
|
7927
8541
|
const user = c.get("user");
|
|
7928
8542
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
7929
8543
|
const db = c.env.DB;
|
|
@@ -7932,11 +8546,11 @@ apiRoutes3.get("/stats", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
|
|
|
7932
8546
|
const stats = await subscriptionService.getStats();
|
|
7933
8547
|
return c.json(stats);
|
|
7934
8548
|
});
|
|
7935
|
-
apiRoutes3.post("/sync-subscriptions",
|
|
8549
|
+
apiRoutes3.post("/sync-subscriptions", chunkFCLKX2OS_cjs.requireAuth(), async (c) => {
|
|
7936
8550
|
const user = c.get("user");
|
|
7937
8551
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
7938
8552
|
const db = c.env.DB;
|
|
7939
|
-
const settings = await
|
|
8553
|
+
const settings = await getSettings5(db);
|
|
7940
8554
|
if (!settings.stripeSecretKey) {
|
|
7941
8555
|
return c.json({ error: "Stripe secret key not configured" }, 400);
|
|
7942
8556
|
}
|
|
@@ -7980,7 +8594,7 @@ apiRoutes3.post("/sync-subscriptions", chunkAAWNRBRB_cjs.requireAuth(), async (c
|
|
|
7980
8594
|
}, 500);
|
|
7981
8595
|
}
|
|
7982
8596
|
});
|
|
7983
|
-
apiRoutes3.get("/events",
|
|
8597
|
+
apiRoutes3.get("/events", chunkFCLKX2OS_cjs.requireAuth(), async (c) => {
|
|
7984
8598
|
const user = c.get("user");
|
|
7985
8599
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
7986
8600
|
const db = c.env.DB;
|
|
@@ -8003,7 +8617,7 @@ apiRoutes3.get("/events", chunkAAWNRBRB_cjs.requireAuth(), async (c) => {
|
|
|
8003
8617
|
|
|
8004
8618
|
// src/plugins/core-plugins/stripe-plugin/index.ts
|
|
8005
8619
|
var STRIPE_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"/></svg>`;
|
|
8006
|
-
var stripePlugin =
|
|
8620
|
+
var stripePlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
8007
8621
|
id: "stripe",
|
|
8008
8622
|
version: "1.0.0",
|
|
8009
8623
|
name: "Stripe",
|
|
@@ -8011,7 +8625,7 @@ var stripePlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
8011
8625
|
sonicjsVersionRange: "^3.0.0",
|
|
8012
8626
|
author: { name: "SonicJS Team" },
|
|
8013
8627
|
register(app2) {
|
|
8014
|
-
app2.route("/admin/plugins/stripe",
|
|
8628
|
+
app2.route("/admin/plugins/stripe", adminRoutes5);
|
|
8015
8629
|
app2.route("/api/stripe", apiRoutes3);
|
|
8016
8630
|
},
|
|
8017
8631
|
menu: [
|
|
@@ -8024,7 +8638,7 @@ var stripePlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
8024
8638
|
});
|
|
8025
8639
|
|
|
8026
8640
|
// src/templates/pages/admin-forms-list.template.ts
|
|
8027
|
-
|
|
8641
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
8028
8642
|
function renderFormsListPage(data) {
|
|
8029
8643
|
const tableData = {
|
|
8030
8644
|
tableId: "forms-table",
|
|
@@ -8276,7 +8890,7 @@ function renderFormsListPage(data) {
|
|
|
8276
8890
|
|
|
8277
8891
|
<!-- Forms Table -->
|
|
8278
8892
|
<div class="bg-white dark:bg-zinc-900 rounded-lg border border-zinc-950/5 dark:border-white/10 overflow-hidden">
|
|
8279
|
-
${
|
|
8893
|
+
${chunk7RUW244J_cjs.renderTable(tableData)}
|
|
8280
8894
|
</div>
|
|
8281
8895
|
</div>
|
|
8282
8896
|
`;
|
|
@@ -8286,11 +8900,11 @@ function renderFormsListPage(data) {
|
|
|
8286
8900
|
user: data.user,
|
|
8287
8901
|
version: data.version
|
|
8288
8902
|
};
|
|
8289
|
-
return
|
|
8903
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
8290
8904
|
}
|
|
8291
8905
|
|
|
8292
8906
|
// src/templates/pages/admin-forms-builder.template.ts
|
|
8293
|
-
|
|
8907
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
8294
8908
|
function getTurnstileComponentScript() {
|
|
8295
8909
|
return `
|
|
8296
8910
|
(function() {
|
|
@@ -9503,11 +10117,11 @@ ${getTurnstileComponentScript()}
|
|
|
9503
10117
|
user: data.user,
|
|
9504
10118
|
version: data.version
|
|
9505
10119
|
};
|
|
9506
|
-
return
|
|
10120
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
9507
10121
|
}
|
|
9508
10122
|
|
|
9509
10123
|
// src/templates/pages/admin-forms-create.template.ts
|
|
9510
|
-
|
|
10124
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
9511
10125
|
function renderFormCreatePage(data) {
|
|
9512
10126
|
const pageContent = `
|
|
9513
10127
|
<div class="max-w-3xl mx-auto">
|
|
@@ -9700,12 +10314,13 @@ function renderFormCreatePage(data) {
|
|
|
9700
10314
|
user: data.user,
|
|
9701
10315
|
version: data.version
|
|
9702
10316
|
};
|
|
9703
|
-
return
|
|
10317
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
9704
10318
|
}
|
|
9705
10319
|
|
|
9706
10320
|
// src/routes/admin-forms.ts
|
|
10321
|
+
var isTableMissing = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: forms");
|
|
9707
10322
|
var adminFormsRoutes = new hono.Hono();
|
|
9708
|
-
adminFormsRoutes.use("*",
|
|
10323
|
+
adminFormsRoutes.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
9709
10324
|
adminFormsRoutes.get("/", async (c) => {
|
|
9710
10325
|
try {
|
|
9711
10326
|
const user = c.get("user");
|
|
@@ -9745,6 +10360,14 @@ adminFormsRoutes.get("/", async (c) => {
|
|
|
9745
10360
|
};
|
|
9746
10361
|
return c.html(renderFormsListPage(pageData));
|
|
9747
10362
|
} catch (error) {
|
|
10363
|
+
if (isTableMissing(error)) {
|
|
10364
|
+
const user = c.get("user");
|
|
10365
|
+
return c.html(renderFormsListPage({
|
|
10366
|
+
forms: [],
|
|
10367
|
+
user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
|
|
10368
|
+
version: c.get("appVersion")
|
|
10369
|
+
}));
|
|
10370
|
+
}
|
|
9748
10371
|
console.error("Error listing forms:", error);
|
|
9749
10372
|
return c.html("<p>Error loading forms</p>", 500);
|
|
9750
10373
|
}
|
|
@@ -9855,6 +10478,7 @@ adminFormsRoutes.post("/", async (c) => {
|
|
|
9855
10478
|
).run();
|
|
9856
10479
|
return c.redirect(`/admin/forms/${formId}/builder`);
|
|
9857
10480
|
} catch (error) {
|
|
10481
|
+
if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
|
|
9858
10482
|
console.error("Error creating form:", error);
|
|
9859
10483
|
return c.json({ error: "Failed to create form" }, 500);
|
|
9860
10484
|
}
|
|
@@ -9869,7 +10493,7 @@ adminFormsRoutes.get("/:id/builder", async (c) => {
|
|
|
9869
10493
|
if (!form) {
|
|
9870
10494
|
return c.html("<p>Form not found</p>", 404);
|
|
9871
10495
|
}
|
|
9872
|
-
const turnstileService = new
|
|
10496
|
+
const turnstileService = new chunk5UXU3LP4_cjs.TurnstileService(db);
|
|
9873
10497
|
const turnstileSettings = await turnstileService.getSettings();
|
|
9874
10498
|
const pageData = {
|
|
9875
10499
|
id: form.id,
|
|
@@ -9892,6 +10516,7 @@ adminFormsRoutes.get("/:id/builder", async (c) => {
|
|
|
9892
10516
|
};
|
|
9893
10517
|
return c.html(renderFormBuilderPage(pageData));
|
|
9894
10518
|
} catch (error) {
|
|
10519
|
+
if (isTableMissing(error)) return c.html("<p>Forms storage not configured \u2014 run database migrations</p>", 503);
|
|
9895
10520
|
console.error("Error showing form builder:", error);
|
|
9896
10521
|
return c.html("<p>Error loading form builder</p>", 500);
|
|
9897
10522
|
}
|
|
@@ -9921,6 +10546,7 @@ adminFormsRoutes.put("/:id", async (c) => {
|
|
|
9921
10546
|
).run();
|
|
9922
10547
|
return c.json({ success: true, message: "Form saved successfully" });
|
|
9923
10548
|
} catch (error) {
|
|
10549
|
+
if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
|
|
9924
10550
|
console.error("Error updating form:", error);
|
|
9925
10551
|
return c.json({ error: "Failed to save form" }, 500);
|
|
9926
10552
|
}
|
|
@@ -9942,6 +10568,7 @@ adminFormsRoutes.delete("/:id", async (c) => {
|
|
|
9942
10568
|
await db.prepare("DELETE FROM forms WHERE id = ?").bind(formId).run();
|
|
9943
10569
|
return c.json({ success: true, message: "Form deleted successfully" });
|
|
9944
10570
|
} catch (error) {
|
|
10571
|
+
if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
|
|
9945
10572
|
console.error("Error deleting form:", error);
|
|
9946
10573
|
return c.json({ error: "Failed to delete form" }, 500);
|
|
9947
10574
|
}
|
|
@@ -10002,6 +10629,7 @@ adminFormsRoutes.get("/:id/submissions", async (c) => {
|
|
|
10002
10629
|
`;
|
|
10003
10630
|
return c.html(html4);
|
|
10004
10631
|
} catch (error) {
|
|
10632
|
+
if (isTableMissing(error)) return c.html("<p>Forms storage not configured \u2014 run database migrations</p>", 503);
|
|
10005
10633
|
console.error("Error loading submissions:", error);
|
|
10006
10634
|
return c.html("<p>Error loading submissions</p>", 500);
|
|
10007
10635
|
}
|
|
@@ -10022,6 +10650,7 @@ function sanitizeDeep(value) {
|
|
|
10022
10650
|
}
|
|
10023
10651
|
return value;
|
|
10024
10652
|
}
|
|
10653
|
+
var isTableMissing2 = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: form");
|
|
10025
10654
|
var publicFormsRoutes = new hono.Hono();
|
|
10026
10655
|
publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
|
|
10027
10656
|
try {
|
|
@@ -10033,7 +10662,7 @@ publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
|
|
|
10033
10662
|
if (!form) {
|
|
10034
10663
|
return c.json({ error: "Form not found" }, 404);
|
|
10035
10664
|
}
|
|
10036
|
-
const turnstileService = new
|
|
10665
|
+
const turnstileService = new chunk5UXU3LP4_cjs.TurnstileService(db);
|
|
10037
10666
|
const globalSettings = await turnstileService.getSettings();
|
|
10038
10667
|
const formSettings = form.turnstile_settings ? JSON.parse(form.turnstile_settings) : { inherit: true };
|
|
10039
10668
|
const enabled = form.turnstile_enabled === 1 || formSettings.inherit && globalSettings?.enabled;
|
|
@@ -10049,6 +10678,7 @@ publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
|
|
|
10049
10678
|
appearance: formSettings.appearance || globalSettings.appearance || "always"
|
|
10050
10679
|
});
|
|
10051
10680
|
} catch (error) {
|
|
10681
|
+
if (isTableMissing2(error)) return c.json({ enabled: false });
|
|
10052
10682
|
console.error("Error fetching Turnstile config:", error);
|
|
10053
10683
|
return c.json({ error: "Failed to fetch config" }, 500);
|
|
10054
10684
|
}
|
|
@@ -10076,6 +10706,7 @@ publicFormsRoutes.get("/:identifier/schema", async (c) => {
|
|
|
10076
10706
|
submitUrl: `/api/forms/${form.id}/submit`
|
|
10077
10707
|
});
|
|
10078
10708
|
} catch (error) {
|
|
10709
|
+
if (isTableMissing2(error)) return c.json({ error: "Form not found" }, 404);
|
|
10079
10710
|
console.error("Error fetching form schema:", error);
|
|
10080
10711
|
return c.json({ error: "Failed to fetch form schema" }, 500);
|
|
10081
10712
|
}
|
|
@@ -10442,6 +11073,7 @@ publicFormsRoutes.get("/:name", async (c) => {
|
|
|
10442
11073
|
`;
|
|
10443
11074
|
return c.html(html4);
|
|
10444
11075
|
} catch (error) {
|
|
11076
|
+
if (isTableMissing2(error)) return c.html("<h1>Form not found</h1><p>This form does not exist or is not publicly available.</p>", 404);
|
|
10445
11077
|
console.error("Error rendering form:", error);
|
|
10446
11078
|
return c.html("<p>Error loading form</p>", 500);
|
|
10447
11079
|
}
|
|
@@ -10460,7 +11092,7 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
|
|
|
10460
11092
|
const turnstileEnabled = form.turnstile_enabled === 1;
|
|
10461
11093
|
const turnstileSettings = form.turnstile_settings ? JSON.parse(form.turnstile_settings) : { inherit: true };
|
|
10462
11094
|
if (turnstileEnabled || turnstileSettings.inherit) {
|
|
10463
|
-
const turnstileService = new
|
|
11095
|
+
const turnstileService = new chunk5UXU3LP4_cjs.TurnstileService(db);
|
|
10464
11096
|
const globalEnabled = await turnstileService.isEnabled();
|
|
10465
11097
|
if (globalEnabled || turnstileEnabled) {
|
|
10466
11098
|
const turnstileToken = body.data?.turnstile || body.turnstile;
|
|
@@ -10515,13 +11147,14 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
|
|
|
10515
11147
|
message: "Form submitted successfully"
|
|
10516
11148
|
});
|
|
10517
11149
|
} catch (error) {
|
|
11150
|
+
if (isTableMissing2(error)) return c.json({ error: "Form not found" }, 404);
|
|
10518
11151
|
console.error("Error submitting form:", error);
|
|
10519
11152
|
return c.json({ error: "Failed to submit form" }, 500);
|
|
10520
11153
|
}
|
|
10521
11154
|
});
|
|
10522
11155
|
|
|
10523
11156
|
// src/plugins/core-plugins/forms-plugin/index.ts
|
|
10524
|
-
var formsPlugin =
|
|
11157
|
+
var formsPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
10525
11158
|
id: "forms",
|
|
10526
11159
|
version: "1.0.0",
|
|
10527
11160
|
name: "Forms",
|
|
@@ -10539,9 +11172,9 @@ var formsPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
10539
11172
|
activate: async () => console.info("\u2705 Forms plugin activated"),
|
|
10540
11173
|
deactivate: async () => console.info("\u274C Forms plugin deactivated")
|
|
10541
11174
|
});
|
|
10542
|
-
|
|
11175
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
10543
11176
|
var adminRbacRoutes = new hono.Hono();
|
|
10544
|
-
adminRbacRoutes.use("*",
|
|
11177
|
+
adminRbacRoutes.use("*", chunkFCLKX2OS_cjs.requireRbac("rbac", "manage"));
|
|
10545
11178
|
var esc = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
10546
11179
|
var TABS2 = `
|
|
10547
11180
|
<div class="border-b border-zinc-950/10 dark:border-white/10 mb-6">
|
|
@@ -10551,7 +11184,7 @@ var TABS2 = `
|
|
|
10551
11184
|
</nav>
|
|
10552
11185
|
</div>`;
|
|
10553
11186
|
adminRbacRoutes.get("/", async (c) => {
|
|
10554
|
-
const rbac = new
|
|
11187
|
+
const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
|
|
10555
11188
|
const [roles, verbs, resources, grants] = await Promise.all([
|
|
10556
11189
|
rbac.getRoles(),
|
|
10557
11190
|
rbac.getVerbs(),
|
|
@@ -10662,7 +11295,7 @@ adminRbacRoutes.get("/", async (c) => {
|
|
|
10662
11295
|
${r.is_system ? `<code class="text-xs text-zinc-500 dark:text-zinc-400">${esc(r.name)}</code><span class="rounded-full bg-zinc-100 dark:bg-white/10 px-2 py-0.5 text-[11px] text-zinc-500 dark:text-zinc-400">system</span>` : `<input form="roles-bulk-form" class="${inpSm} w-28" name="name_${esc(r.id)}" value="${esc(r.name)}" required>`}
|
|
10663
11296
|
<label class="ml-auto inline-flex items-center gap-2 rounded-md bg-white/5 px-2.5 py-1 text-xs font-medium text-zinc-700 dark:text-zinc-300 ring-1 ring-inset ring-zinc-500/20">
|
|
10664
11297
|
<input form="roles-bulk-form" type="checkbox" name="portal_${esc(r.id)}" value="1" ${portalChecked ? "checked" : ""} ${portalDisabled ? "disabled" : ""} class="h-3.5 w-3.5 rounded border-zinc-400 text-cyan-600 focus:ring-cyan-500">
|
|
10665
|
-
|
|
11298
|
+
Admin Panel
|
|
10666
11299
|
</label>
|
|
10667
11300
|
<a href="/admin/tenants/roles/${esc(r.name)}" data-role-tenants="${esc(r.name)}" class="text-xs text-cyan-600 dark:text-cyan-400 hover:underline" title="Per-tenant assignments of this role">tenants</a>
|
|
10668
11301
|
${r.is_system ? "" : `<button form="delete-role-${esc(r.id)}" type="submit" onclick="return confirm('Delete role ${esc(r.name)}?')" class="text-xs text-red-600 dark:text-red-400 hover:underline">delete</button>`}
|
|
@@ -10766,7 +11399,7 @@ adminRbacRoutes.get("/", async (c) => {
|
|
|
10766
11399
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
|
10767
11400
|
<div class="${card}">
|
|
10768
11401
|
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-3">Roles</h3>
|
|
10769
|
-
<p class="mb-3 text-xs text-zinc-500 dark:text-zinc-400">Use <strong>
|
|
11402
|
+
<p class="mb-3 text-xs text-zinc-500 dark:text-zinc-400">Use <strong>Admin Panel</strong> to allow a role into the admin backend. Resource permissions are configured in the <strong>Matrix</strong> tab.</p>
|
|
10770
11403
|
${roleList}
|
|
10771
11404
|
</div>
|
|
10772
11405
|
<div class="${card}">
|
|
@@ -10845,11 +11478,11 @@ adminRbacRoutes.get("/", async (c) => {
|
|
|
10845
11478
|
</script>`;
|
|
10846
11479
|
const u = c.get("user");
|
|
10847
11480
|
return c.html(
|
|
10848
|
-
|
|
11481
|
+
chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
10849
11482
|
title: "Roles & Permissions",
|
|
10850
11483
|
pageTitle: "Roles & Permissions",
|
|
10851
11484
|
currentPath: "/admin/users",
|
|
10852
|
-
version:
|
|
11485
|
+
version: chunkAOUVUF32_cjs.getCoreVersion(),
|
|
10853
11486
|
user: u ? { name: u.email || "Admin", email: u.email || "", role: u.role || "admin" } : void 0,
|
|
10854
11487
|
content: content2
|
|
10855
11488
|
})
|
|
@@ -10873,7 +11506,7 @@ adminRbacRoutes.post("/grants", async (c) => {
|
|
|
10873
11506
|
pairsByRole.get(roleId).push({ resource, verb, scope });
|
|
10874
11507
|
}
|
|
10875
11508
|
}
|
|
10876
|
-
const rbac = new
|
|
11509
|
+
const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
|
|
10877
11510
|
for (const id of saveRoleIds) {
|
|
10878
11511
|
await rbac.setRoleGrants(id, pairsByRole.get(id) || []);
|
|
10879
11512
|
}
|
|
@@ -10894,7 +11527,7 @@ adminRbacRoutes.post("/grants", async (c) => {
|
|
|
10894
11527
|
adminRbacRoutes.post("/roles/bulk", async (c) => {
|
|
10895
11528
|
const form = await c.req.formData();
|
|
10896
11529
|
const roleIds = String(form.get("role_ids") || "").split(",").filter(Boolean);
|
|
10897
|
-
const rbac = new
|
|
11530
|
+
const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
|
|
10898
11531
|
for (const roleId of roleIds) {
|
|
10899
11532
|
const displayName = String(form.get(`display_name_${roleId}`) || "").trim();
|
|
10900
11533
|
const nameVal = form.get(`name_${roleId}`) ? String(form.get(`name_${roleId}`)).trim() : void 0;
|
|
@@ -10919,7 +11552,7 @@ adminRbacRoutes.post("/roles", async (c) => {
|
|
|
10919
11552
|
const displayName = String(form.get("display_name") || "").trim();
|
|
10920
11553
|
if (name && displayName) {
|
|
10921
11554
|
try {
|
|
10922
|
-
await new
|
|
11555
|
+
await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).createRole(name, displayName);
|
|
10923
11556
|
} catch {
|
|
10924
11557
|
}
|
|
10925
11558
|
}
|
|
@@ -10934,7 +11567,7 @@ adminRbacRoutes.post("/roles/:id", async (c) => {
|
|
|
10934
11567
|
const portalAccess = form.get("portal_access") === "1";
|
|
10935
11568
|
if (displayName) {
|
|
10936
11569
|
try {
|
|
10937
|
-
const rbac = new
|
|
11570
|
+
const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
|
|
10938
11571
|
if (roleId !== "role-admin") {
|
|
10939
11572
|
await rbac.updateRoleAndPortalAccess(roleId, displayName, name, portalAccess, description);
|
|
10940
11573
|
} else {
|
|
@@ -10946,7 +11579,7 @@ adminRbacRoutes.post("/roles/:id", async (c) => {
|
|
|
10946
11579
|
return c.redirect(`/admin/rbac#roles-verbs`);
|
|
10947
11580
|
});
|
|
10948
11581
|
adminRbacRoutes.post("/roles/:id/delete", async (c) => {
|
|
10949
|
-
await new
|
|
11582
|
+
await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).deleteRole(c.req.param("id"));
|
|
10950
11583
|
return c.redirect("/admin/rbac#roles-verbs");
|
|
10951
11584
|
});
|
|
10952
11585
|
adminRbacRoutes.post("/verbs", async (c) => {
|
|
@@ -10954,18 +11587,18 @@ adminRbacRoutes.post("/verbs", async (c) => {
|
|
|
10954
11587
|
const name = String(form.get("name") || "").trim();
|
|
10955
11588
|
if (name) {
|
|
10956
11589
|
try {
|
|
10957
|
-
await new
|
|
11590
|
+
await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).createVerb(name);
|
|
10958
11591
|
} catch {
|
|
10959
11592
|
}
|
|
10960
11593
|
}
|
|
10961
11594
|
return c.redirect("/admin/rbac#roles-verbs");
|
|
10962
11595
|
});
|
|
10963
11596
|
adminRbacRoutes.post("/verbs/:id/delete", async (c) => {
|
|
10964
|
-
await new
|
|
11597
|
+
await new chunkLTZ5WYOK_cjs.RbacService(c.env.DB).deleteVerb(c.req.param("id"));
|
|
10965
11598
|
return c.redirect("/admin/rbac#roles-verbs");
|
|
10966
11599
|
});
|
|
10967
11600
|
adminRbacRoutes.get("/check", async (c) => {
|
|
10968
|
-
const rbac = new
|
|
11601
|
+
const rbac = new chunkLTZ5WYOK_cjs.RbacService(c.env.DB);
|
|
10969
11602
|
const resource = c.req.query("resource") || "";
|
|
10970
11603
|
const verb = c.req.query("verb") || "";
|
|
10971
11604
|
const roleId = c.req.query("role");
|
|
@@ -10986,7 +11619,7 @@ adminRbacRoutes.get("/check", async (c) => {
|
|
|
10986
11619
|
});
|
|
10987
11620
|
|
|
10988
11621
|
// src/middleware/plugin-menu.ts
|
|
10989
|
-
var REGISTRY_MENU_PLUGINS = Object.values(
|
|
11622
|
+
var REGISTRY_MENU_PLUGINS = Object.values(chunkKVBHB7QP_cjs.PLUGIN_REGISTRY).filter((p) => p.adminMenu !== null).map((p) => ({
|
|
10990
11623
|
id: p.id,
|
|
10991
11624
|
label: p.adminMenu.label,
|
|
10992
11625
|
path: p.adminMenu.path,
|
|
@@ -11064,14 +11697,24 @@ function pluginMenuMiddleware() {
|
|
|
11064
11697
|
}
|
|
11065
11698
|
} catch {
|
|
11066
11699
|
}
|
|
11067
|
-
|
|
11700
|
+
const user = c.get("user");
|
|
11701
|
+
const singletonItems = chunk5UXU3LP4_cjs.resolvePluginMenuItems(user ? { role: user.role } : void 0);
|
|
11702
|
+
const existingPaths = new Set(activeMenuItems.map((i) => i.path));
|
|
11703
|
+
for (const item of singletonItems) {
|
|
11704
|
+
if (!existingPaths.has(item.path)) {
|
|
11705
|
+
activeMenuItems.push({ label: item.label, path: item.path, icon: item.icon, order: item.order });
|
|
11706
|
+
}
|
|
11707
|
+
}
|
|
11708
|
+
activeMenuItems.sort((a, b) => a.order - b.order);
|
|
11709
|
+
c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || m.icon || "" })));
|
|
11068
11710
|
await next();
|
|
11069
|
-
|
|
11711
|
+
const finalItems = c.get("pluginMenuItems") ?? [];
|
|
11712
|
+
if (finalItems.length > 0 && c.res.headers.get("content-type")?.includes("text/html")) {
|
|
11070
11713
|
const status = c.res.status;
|
|
11071
11714
|
const headers = new Headers(c.res.headers);
|
|
11072
11715
|
const html4 = await c.res.text();
|
|
11073
11716
|
if (html4.includes(MARKER)) {
|
|
11074
|
-
const renderedItems =
|
|
11717
|
+
const renderedItems = finalItems.map((item) => renderMenuItem(item, path)).join("");
|
|
11075
11718
|
const newHtml = html4.split(MARKER).join(renderedItems);
|
|
11076
11719
|
c.res = new Response(newHtml, { status, headers });
|
|
11077
11720
|
} else {
|
|
@@ -11080,17 +11723,17 @@ function pluginMenuMiddleware() {
|
|
|
11080
11723
|
}
|
|
11081
11724
|
};
|
|
11082
11725
|
}
|
|
11083
|
-
|
|
11084
|
-
var
|
|
11085
|
-
|
|
11086
|
-
|
|
11726
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
11727
|
+
var adminRoutes6 = new hono.Hono();
|
|
11728
|
+
adminRoutes6.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
11729
|
+
adminRoutes6.use("*", async (c, next) => {
|
|
11087
11730
|
const user = c.get("user");
|
|
11088
11731
|
if (user?.role !== "admin") {
|
|
11089
11732
|
return c.text("Access denied", 403);
|
|
11090
11733
|
}
|
|
11091
11734
|
return next();
|
|
11092
11735
|
});
|
|
11093
|
-
|
|
11736
|
+
adminRoutes6.get("/", async (c) => {
|
|
11094
11737
|
const user = c.get("user");
|
|
11095
11738
|
const db = c.env.DB;
|
|
11096
11739
|
let totalRequests = 0;
|
|
@@ -11198,7 +11841,7 @@ adminRoutes5.get("/", async (c) => {
|
|
|
11198
11841
|
</div>
|
|
11199
11842
|
</div>
|
|
11200
11843
|
`;
|
|
11201
|
-
return c.html(
|
|
11844
|
+
return c.html(chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
11202
11845
|
title: "Analytics",
|
|
11203
11846
|
pageTitle: "Analytics Dashboard",
|
|
11204
11847
|
currentPath: "/admin/analytics",
|
|
@@ -11229,12 +11872,13 @@ var QUERYABLE_FIELDS2 = [
|
|
|
11229
11872
|
var EventTrackingService = class {
|
|
11230
11873
|
constructor(db) {
|
|
11231
11874
|
this.db = db;
|
|
11232
|
-
this.docsService = new
|
|
11875
|
+
this.docsService = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
11233
11876
|
queryableFields: QUERYABLE_FIELDS2,
|
|
11234
11877
|
maxVersionsPerRoot: 1,
|
|
11235
11878
|
tenantId: TENANT2
|
|
11236
11879
|
});
|
|
11237
11880
|
}
|
|
11881
|
+
db;
|
|
11238
11882
|
docsService;
|
|
11239
11883
|
async trackEvent(input) {
|
|
11240
11884
|
const doc = await this.docsService.create({
|
|
@@ -11437,7 +12081,7 @@ apiRoutes4.get("/stats", async (c) => {
|
|
|
11437
12081
|
});
|
|
11438
12082
|
|
|
11439
12083
|
// src/plugins/core-plugins/analytics/index.ts
|
|
11440
|
-
var analyticsPlugin =
|
|
12084
|
+
var analyticsPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
11441
12085
|
id: "core-analytics",
|
|
11442
12086
|
version: "1.0.0",
|
|
11443
12087
|
name: "Analytics",
|
|
@@ -11446,7 +12090,7 @@ var analyticsPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
11446
12090
|
author: { name: "SonicJS Team", email: "team@sonicjs.com" },
|
|
11447
12091
|
register(app2) {
|
|
11448
12092
|
app2.route("/api/events", apiRoutes4);
|
|
11449
|
-
app2.route("/admin/analytics",
|
|
12093
|
+
app2.route("/admin/analytics", adminRoutes6);
|
|
11450
12094
|
},
|
|
11451
12095
|
menu: [
|
|
11452
12096
|
{
|
|
@@ -11584,7 +12228,7 @@ function esc2(s) {
|
|
|
11584
12228
|
return (s || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
11585
12229
|
}
|
|
11586
12230
|
async function getVariablesMap(db) {
|
|
11587
|
-
let variables =
|
|
12231
|
+
let variables = chunk7RUW244J_cjs.getVariablesCached();
|
|
11588
12232
|
if (variables) return variables;
|
|
11589
12233
|
try {
|
|
11590
12234
|
const { results } = await db.prepare(
|
|
@@ -11594,7 +12238,7 @@ async function getVariablesMap(db) {
|
|
|
11594
12238
|
for (const row of results || []) {
|
|
11595
12239
|
variables.set(row.key, row.value);
|
|
11596
12240
|
}
|
|
11597
|
-
|
|
12241
|
+
chunk7RUW244J_cjs.setVariablesCache(variables);
|
|
11598
12242
|
return variables;
|
|
11599
12243
|
} catch {
|
|
11600
12244
|
return /* @__PURE__ */ new Map();
|
|
@@ -11663,7 +12307,7 @@ apiRoutes5.post("/", async (c) => {
|
|
|
11663
12307
|
await db.prepare(
|
|
11664
12308
|
"INSERT INTO global_variables (key, value, description, category, is_active) VALUES (?, ?, ?, ?, ?)"
|
|
11665
12309
|
).bind(key, value || "", description || "", category || "general", isActive !== false ? 1 : 0).run();
|
|
11666
|
-
|
|
12310
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11667
12311
|
const created = await db.prepare("SELECT * FROM global_variables WHERE key = ?").bind(key).first();
|
|
11668
12312
|
return c.json({ success: true, data: formatVariable(created) }, 201);
|
|
11669
12313
|
} catch {
|
|
@@ -11708,7 +12352,7 @@ apiRoutes5.put("/:id", async (c) => {
|
|
|
11708
12352
|
updates.push("updated_at = strftime('%s', 'now')");
|
|
11709
12353
|
params.push(id);
|
|
11710
12354
|
await db.prepare(`UPDATE global_variables SET ${updates.join(", ")} WHERE id = ?`).bind(...params).run();
|
|
11711
|
-
|
|
12355
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11712
12356
|
const updated = await db.prepare("SELECT * FROM global_variables WHERE id = ?").bind(id).first();
|
|
11713
12357
|
return c.json({ success: true, data: formatVariable(updated) });
|
|
11714
12358
|
} catch {
|
|
@@ -11722,14 +12366,14 @@ apiRoutes5.delete("/:id", async (c) => {
|
|
|
11722
12366
|
const existing = await db.prepare("SELECT id FROM global_variables WHERE id = ?").bind(id).first();
|
|
11723
12367
|
if (!existing) return c.json({ error: "Variable not found" }, 404);
|
|
11724
12368
|
await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(id).run();
|
|
11725
|
-
|
|
12369
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11726
12370
|
return c.json({ success: true });
|
|
11727
12371
|
} catch {
|
|
11728
12372
|
return c.json({ success: false, error: "Failed to delete variable" }, 500);
|
|
11729
12373
|
}
|
|
11730
12374
|
});
|
|
11731
|
-
var
|
|
11732
|
-
|
|
12375
|
+
var adminRoutes7 = new hono.Hono();
|
|
12376
|
+
adminRoutes7.use("*", async (c, next) => {
|
|
11733
12377
|
try {
|
|
11734
12378
|
const db = c.env?.DB;
|
|
11735
12379
|
if (db) {
|
|
@@ -11740,7 +12384,7 @@ adminRoutes6.use("*", async (c, next) => {
|
|
|
11740
12384
|
}
|
|
11741
12385
|
await next();
|
|
11742
12386
|
});
|
|
11743
|
-
|
|
12387
|
+
adminRoutes7.get("/", async (c) => {
|
|
11744
12388
|
const db = c.env.DB;
|
|
11745
12389
|
let variables = [];
|
|
11746
12390
|
try {
|
|
@@ -11770,7 +12414,7 @@ adminRoutes6.get("/", async (c) => {
|
|
|
11770
12414
|
}
|
|
11771
12415
|
return c.html(renderAdminPage(variables, { editorActive, activeEditorName, enableEditorIntegration }));
|
|
11772
12416
|
});
|
|
11773
|
-
|
|
12417
|
+
adminRoutes7.put("/:id", async (c) => {
|
|
11774
12418
|
const db = c.env.DB;
|
|
11775
12419
|
const id = c.req.param("id");
|
|
11776
12420
|
let body;
|
|
@@ -11782,19 +12426,19 @@ adminRoutes6.put("/:id", async (c) => {
|
|
|
11782
12426
|
const value = body.value;
|
|
11783
12427
|
if (value !== void 0) {
|
|
11784
12428
|
await db.prepare("UPDATE global_variables SET value = ?, updated_at = strftime('%s', 'now') WHERE id = ?").bind(value, id).run();
|
|
11785
|
-
|
|
12429
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11786
12430
|
}
|
|
11787
12431
|
return c.html('<span class="text-green-400 text-xs">Saved</span>');
|
|
11788
12432
|
});
|
|
11789
|
-
|
|
12433
|
+
adminRoutes7.post("/:id/toggle", async (c) => {
|
|
11790
12434
|
const db = c.env.DB;
|
|
11791
12435
|
const id = c.req.param("id");
|
|
11792
12436
|
await db.prepare("UPDATE global_variables SET is_active = CASE WHEN is_active = 1 THEN 0 ELSE 1 END, updated_at = strftime('%s', 'now') WHERE id = ?").bind(id).run();
|
|
11793
|
-
|
|
12437
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11794
12438
|
c.header("HX-Redirect", "/admin/global-variables");
|
|
11795
12439
|
return c.body(null, 204);
|
|
11796
12440
|
});
|
|
11797
|
-
|
|
12441
|
+
adminRoutes7.post("/", async (c) => {
|
|
11798
12442
|
const db = c.env.DB;
|
|
11799
12443
|
const form = await c.req.parseBody();
|
|
11800
12444
|
const key = (form.key || "").trim();
|
|
@@ -11811,11 +12455,11 @@ adminRoutes6.post("/", async (c) => {
|
|
|
11811
12455
|
await db.prepare(
|
|
11812
12456
|
"INSERT INTO global_variables (key, value, description, category) VALUES (?, ?, ?, ?)"
|
|
11813
12457
|
).bind(key, value, description, category).run();
|
|
11814
|
-
|
|
12458
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11815
12459
|
c.header("HX-Redirect", "/admin/global-variables");
|
|
11816
12460
|
return c.body(null, 204);
|
|
11817
12461
|
});
|
|
11818
|
-
|
|
12462
|
+
adminRoutes7.post("/settings/editor-integration", async (c) => {
|
|
11819
12463
|
const db = c.env.DB;
|
|
11820
12464
|
try {
|
|
11821
12465
|
const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'global-variables'").first();
|
|
@@ -11827,10 +12471,10 @@ adminRoutes6.post("/settings/editor-integration", async (c) => {
|
|
|
11827
12471
|
return c.json({ success: false, error: "Failed to update setting" }, 500);
|
|
11828
12472
|
}
|
|
11829
12473
|
});
|
|
11830
|
-
|
|
12474
|
+
adminRoutes7.delete("/:id", async (c) => {
|
|
11831
12475
|
const db = c.env.DB;
|
|
11832
12476
|
await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(c.req.param("id")).run();
|
|
11833
|
-
|
|
12477
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
11834
12478
|
return c.html("");
|
|
11835
12479
|
});
|
|
11836
12480
|
function renderAdminPage(variables, editorStatus = { editorActive: false, activeEditorName: "", enableEditorIntegration: true }) {
|
|
@@ -12148,7 +12792,7 @@ function renderAdminPage(variables, editorStatus = { editorActive: false, active
|
|
|
12148
12792
|
</div>
|
|
12149
12793
|
` });
|
|
12150
12794
|
}
|
|
12151
|
-
var globalVariablesPlugin =
|
|
12795
|
+
var globalVariablesPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
12152
12796
|
id: "global-variables",
|
|
12153
12797
|
version: "1.1.0",
|
|
12154
12798
|
name: "Global Variables",
|
|
@@ -12158,7 +12802,7 @@ var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
12158
12802
|
capabilities: ["hooks.content:subscribe"],
|
|
12159
12803
|
register(app2) {
|
|
12160
12804
|
app2.route("/api/global-variables", apiRoutes5);
|
|
12161
|
-
app2.route("/admin/global-variables",
|
|
12805
|
+
app2.route("/admin/global-variables", adminRoutes7);
|
|
12162
12806
|
},
|
|
12163
12807
|
menu: [
|
|
12164
12808
|
{ label: "Global Variables", path: "/admin/global-variables", icon: "bolt", order: 45, permissions: ["global-variables:view"] }
|
|
@@ -12171,7 +12815,7 @@ var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
12171
12815
|
if (!db || !data) return data;
|
|
12172
12816
|
const variables = await getVariablesMap(db);
|
|
12173
12817
|
if (variables.size === 0) return data;
|
|
12174
|
-
return
|
|
12818
|
+
return chunk7RUW244J_cjs.resolveVariablesInObject(data, variables);
|
|
12175
12819
|
} catch {
|
|
12176
12820
|
return data;
|
|
12177
12821
|
}
|
|
@@ -12189,7 +12833,7 @@ var globalVariablesPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
12189
12833
|
},
|
|
12190
12834
|
activate: async () => console.info("[GlobalVariables] Plugin activated"),
|
|
12191
12835
|
deactivate: async () => {
|
|
12192
|
-
|
|
12836
|
+
chunk7RUW244J_cjs.invalidateVariablesCache();
|
|
12193
12837
|
console.info("[GlobalVariables] Plugin deactivated, cache cleared");
|
|
12194
12838
|
},
|
|
12195
12839
|
uninstall: async (ctx) => {
|
|
@@ -12479,8 +13123,8 @@ apiRoutes6.delete("/:id", async (c) => {
|
|
|
12479
13123
|
return c.json({ success: false, error: "Failed to delete shortcode" }, 500);
|
|
12480
13124
|
}
|
|
12481
13125
|
});
|
|
12482
|
-
var
|
|
12483
|
-
|
|
13126
|
+
var adminRoutes8 = new hono.Hono();
|
|
13127
|
+
adminRoutes8.use("*", async (c, next) => {
|
|
12484
13128
|
try {
|
|
12485
13129
|
const db = c.env?.DB;
|
|
12486
13130
|
if (db) {
|
|
@@ -12491,7 +13135,7 @@ adminRoutes7.use("*", async (c, next) => {
|
|
|
12491
13135
|
}
|
|
12492
13136
|
await next();
|
|
12493
13137
|
});
|
|
12494
|
-
|
|
13138
|
+
adminRoutes8.get("/", async (c) => {
|
|
12495
13139
|
const db = c.env.DB;
|
|
12496
13140
|
let shortcodes = [];
|
|
12497
13141
|
try {
|
|
@@ -12521,7 +13165,7 @@ adminRoutes7.get("/", async (c) => {
|
|
|
12521
13165
|
}
|
|
12522
13166
|
return c.html(renderAdminPage2(shortcodes, { editorActive, activeEditorName, enableEditorIntegration }));
|
|
12523
13167
|
});
|
|
12524
|
-
|
|
13168
|
+
adminRoutes8.post("/", async (c) => {
|
|
12525
13169
|
const db = c.env.DB;
|
|
12526
13170
|
const form = await c.req.parseBody();
|
|
12527
13171
|
const name = (form.name || "").trim();
|
|
@@ -12542,7 +13186,7 @@ adminRoutes7.post("/", async (c) => {
|
|
|
12542
13186
|
c.header("HX-Redirect", "/admin/shortcodes");
|
|
12543
13187
|
return c.body(null, 204);
|
|
12544
13188
|
});
|
|
12545
|
-
|
|
13189
|
+
adminRoutes8.post("/settings/editor-integration", async (c) => {
|
|
12546
13190
|
const db = c.env.DB;
|
|
12547
13191
|
try {
|
|
12548
13192
|
const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'shortcodes'").first();
|
|
@@ -12554,7 +13198,7 @@ adminRoutes7.post("/settings/editor-integration", async (c) => {
|
|
|
12554
13198
|
return c.json({ success: false, error: "Failed to update setting" }, 500);
|
|
12555
13199
|
}
|
|
12556
13200
|
});
|
|
12557
|
-
|
|
13201
|
+
adminRoutes8.delete("/:id", async (c) => {
|
|
12558
13202
|
await c.env.DB.prepare("DELETE FROM shortcodes WHERE id = ?").bind(c.req.param("id")).run();
|
|
12559
13203
|
return c.html("");
|
|
12560
13204
|
});
|
|
@@ -12755,7 +13399,7 @@ function renderAdminPage2(shortcodes, editorStatus = { editorActive: false, acti
|
|
|
12755
13399
|
</div>
|
|
12756
13400
|
` });
|
|
12757
13401
|
}
|
|
12758
|
-
var shortcodesPlugin =
|
|
13402
|
+
var shortcodesPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
12759
13403
|
id: "shortcodes",
|
|
12760
13404
|
version: "1.0.0",
|
|
12761
13405
|
name: "Shortcodes",
|
|
@@ -12765,7 +13409,7 @@ var shortcodesPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
12765
13409
|
capabilities: ["hooks.content:subscribe"],
|
|
12766
13410
|
register(app2) {
|
|
12767
13411
|
app2.route("/api/shortcodes", apiRoutes6);
|
|
12768
|
-
app2.route("/admin/shortcodes",
|
|
13412
|
+
app2.route("/admin/shortcodes", adminRoutes8);
|
|
12769
13413
|
},
|
|
12770
13414
|
menu: [
|
|
12771
13415
|
{ label: "Shortcodes", path: "/admin/shortcodes", icon: "bolt", order: 46, permissions: ["shortcodes:view"] }
|
|
@@ -12839,7 +13483,7 @@ helloWorldRoutes.get("/", async (c) => {
|
|
|
12839
13483
|
</html>
|
|
12840
13484
|
`);
|
|
12841
13485
|
});
|
|
12842
|
-
var helloWorldPlugin =
|
|
13486
|
+
var helloWorldPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
12843
13487
|
id: "hello-world",
|
|
12844
13488
|
version: "1.0.0",
|
|
12845
13489
|
name: "Hello World",
|
|
@@ -12874,6 +13518,9 @@ var helloWorldPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
12874
13518
|
console.info("\u274C Hello World plugin deactivated");
|
|
12875
13519
|
}
|
|
12876
13520
|
});
|
|
13521
|
+
function createHelloWorldPlugin() {
|
|
13522
|
+
return helloWorldPlugin;
|
|
13523
|
+
}
|
|
12877
13524
|
|
|
12878
13525
|
// src/plugins/core-plugins/multi-tenant-plugin/manifest.json
|
|
12879
13526
|
var manifest_default2 = {
|
|
@@ -12883,7 +13530,7 @@ var manifest_default2 = {
|
|
|
12883
13530
|
author: "SonicJS Team"};
|
|
12884
13531
|
|
|
12885
13532
|
// src/plugins/core-plugins/multi-tenant-plugin/templates/tenants-list.template.ts
|
|
12886
|
-
|
|
13533
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
12887
13534
|
function statusBadge2(status) {
|
|
12888
13535
|
return status === "active" ? '<span class="inline-flex items-center rounded-md bg-emerald-500/10 px-2 py-1 text-xs font-medium text-emerald-600 dark:text-emerald-400">Active</span>' : '<span class="inline-flex items-center rounded-md bg-zinc-500/10 px-2 py-1 text-xs font-medium text-zinc-600 dark:text-zinc-400">Inactive</span>';
|
|
12889
13536
|
}
|
|
@@ -12956,7 +13603,7 @@ function renderTenantsList(data) {
|
|
|
12956
13603
|
</table>
|
|
12957
13604
|
</div>
|
|
12958
13605
|
</div>`;
|
|
12959
|
-
return
|
|
13606
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
12960
13607
|
title: "Tenants - SonicJS",
|
|
12961
13608
|
pageTitle: "Tenants",
|
|
12962
13609
|
currentPath: "/admin/tenants",
|
|
@@ -12975,7 +13622,7 @@ function renderTenantsInactive(data) {
|
|
|
12975
13622
|
<a href="/admin/plugins" class="mt-6 inline-flex items-center rounded-lg bg-zinc-950 px-3.5 py-2 text-sm font-semibold text-white hover:bg-zinc-800 dark:bg-white dark:text-zinc-950 dark:hover:bg-zinc-200">Go to Plugins</a>
|
|
12976
13623
|
</div>
|
|
12977
13624
|
</div>`;
|
|
12978
|
-
return
|
|
13625
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
12979
13626
|
title: "Tenants - SonicJS",
|
|
12980
13627
|
pageTitle: "Tenants",
|
|
12981
13628
|
currentPath: "/admin/tenants",
|
|
@@ -12986,7 +13633,7 @@ function renderTenantsInactive(data) {
|
|
|
12986
13633
|
}
|
|
12987
13634
|
|
|
12988
13635
|
// src/plugins/core-plugins/multi-tenant-plugin/templates/tenant-form.template.ts
|
|
12989
|
-
|
|
13636
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
12990
13637
|
function fieldErrors(errors, field) {
|
|
12991
13638
|
const list = errors?.[field];
|
|
12992
13639
|
if (!list || list.length === 0) return "";
|
|
@@ -13054,7 +13701,7 @@ function renderTenantForm(data) {
|
|
|
13054
13701
|
</form>
|
|
13055
13702
|
</div>
|
|
13056
13703
|
</div>`;
|
|
13057
|
-
return
|
|
13704
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
13058
13705
|
title: `${data.isEdit ? "Edit Tenant" : "New Tenant"} - SonicJS`,
|
|
13059
13706
|
pageTitle: data.isEdit ? "Edit Tenant" : "New Tenant",
|
|
13060
13707
|
currentPath: "/admin/tenants",
|
|
@@ -13065,9 +13712,9 @@ function renderTenantForm(data) {
|
|
|
13065
13712
|
}
|
|
13066
13713
|
|
|
13067
13714
|
// src/plugins/core-plugins/multi-tenant-plugin/templates/tenant-members.template.ts
|
|
13068
|
-
|
|
13715
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
13069
13716
|
function roleOptions(selected) {
|
|
13070
|
-
return
|
|
13717
|
+
return chunk7RUW244J_cjs.VALID_MEMBER_ROLES.map(
|
|
13071
13718
|
(r) => `<option value="${r}" ${r === selected ? "selected" : ""}>${r}</option>`
|
|
13072
13719
|
).join("");
|
|
13073
13720
|
}
|
|
@@ -13129,7 +13776,7 @@ function renderInvitations(slug, invitations) {
|
|
|
13129
13776
|
<div>
|
|
13130
13777
|
<label for="invite-role" class="mb-1 block text-xs font-medium text-zinc-500 dark:text-zinc-400">Role</label>
|
|
13131
13778
|
<select id="invite-role" name="role" class="rounded-lg border border-zinc-950/10 bg-white px-2 py-2 text-sm text-zinc-950 dark:border-white/10 dark:bg-zinc-800 dark:text-white">
|
|
13132
|
-
${
|
|
13779
|
+
${chunk7RUW244J_cjs.VALID_MEMBER_ROLES.map((r) => `<option value="${r}" ${r === "viewer" ? "selected" : ""}>${r}</option>`).join("")}
|
|
13133
13780
|
</select>
|
|
13134
13781
|
</div>
|
|
13135
13782
|
<button type="submit" data-send-invite class="rounded-lg bg-zinc-950 px-3.5 py-2 text-sm font-semibold text-white hover:bg-zinc-800 dark:bg-white dark:text-zinc-950 dark:hover:bg-zinc-200">Invite</button>
|
|
@@ -13212,7 +13859,7 @@ function renderTenantMembers(data) {
|
|
|
13212
13859
|
|
|
13213
13860
|
${renderInvitations(data.slug, data.invitations)}
|
|
13214
13861
|
</div>`;
|
|
13215
|
-
return
|
|
13862
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
13216
13863
|
title: `Members - ${data.tenantName} - SonicJS`,
|
|
13217
13864
|
pageTitle: "Tenant Members",
|
|
13218
13865
|
currentPath: "/admin/tenants",
|
|
@@ -13223,9 +13870,9 @@ function renderTenantMembers(data) {
|
|
|
13223
13870
|
}
|
|
13224
13871
|
|
|
13225
13872
|
// src/plugins/core-plugins/multi-tenant-plugin/templates/user-memberships.template.ts
|
|
13226
|
-
|
|
13873
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
13227
13874
|
function roleOptions2(selected) {
|
|
13228
|
-
return
|
|
13875
|
+
return chunk7RUW244J_cjs.VALID_MEMBER_ROLES.map(
|
|
13229
13876
|
(r) => `<option value="${r}" ${r === selected ? "selected" : ""}>${r}</option>`
|
|
13230
13877
|
).join("");
|
|
13231
13878
|
}
|
|
@@ -13298,7 +13945,7 @@ function renderUserMemberships(data) {
|
|
|
13298
13945
|
</table>
|
|
13299
13946
|
</div>
|
|
13300
13947
|
</div>`;
|
|
13301
|
-
return
|
|
13948
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
13302
13949
|
title: `Tenant memberships - ${data.userEmail} - SonicJS`,
|
|
13303
13950
|
pageTitle: "Tenant memberships",
|
|
13304
13951
|
currentPath: "/admin/users",
|
|
@@ -13309,7 +13956,7 @@ function renderUserMemberships(data) {
|
|
|
13309
13956
|
}
|
|
13310
13957
|
|
|
13311
13958
|
// src/plugins/core-plugins/multi-tenant-plugin/templates/role-usage.template.ts
|
|
13312
|
-
|
|
13959
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
13313
13960
|
function renderRoleUsage(data) {
|
|
13314
13961
|
const role = chunkMNWKYY5E_cjs.escapeHtml(data.roleName);
|
|
13315
13962
|
const rows = data.assignments.length ? data.assignments.map((a) => `
|
|
@@ -13344,7 +13991,7 @@ function renderRoleUsage(data) {
|
|
|
13344
13991
|
</table>
|
|
13345
13992
|
</div>
|
|
13346
13993
|
</div>`;
|
|
13347
|
-
return
|
|
13994
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
13348
13995
|
title: `Role usage - ${data.roleName} - SonicJS`,
|
|
13349
13996
|
pageTitle: "Role usage",
|
|
13350
13997
|
currentPath: "/admin/tenants",
|
|
@@ -13387,7 +14034,7 @@ function zodToFieldErrors(error) {
|
|
|
13387
14034
|
}
|
|
13388
14035
|
async function isMultiTenantActive(db) {
|
|
13389
14036
|
try {
|
|
13390
|
-
const plugin2 = await new
|
|
14037
|
+
const plugin2 = await new chunkKVBHB7QP_cjs.PluginService(db).getPlugin(chunkKVBHB7QP_cjs.MULTI_TENANT_PLUGIN_ID);
|
|
13391
14038
|
return plugin2?.status === "active";
|
|
13392
14039
|
} catch {
|
|
13393
14040
|
return false;
|
|
@@ -13395,7 +14042,7 @@ async function isMultiTenantActive(db) {
|
|
|
13395
14042
|
}
|
|
13396
14043
|
function createTenantAdminRoutes() {
|
|
13397
14044
|
const routes2 = new hono.Hono();
|
|
13398
|
-
routes2.use("*",
|
|
14045
|
+
routes2.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
13399
14046
|
routes2.use("*", async (c, next) => {
|
|
13400
14047
|
const user = c.get("user");
|
|
13401
14048
|
if (user?.role !== "admin") {
|
|
@@ -13409,7 +14056,7 @@ function createTenantAdminRoutes() {
|
|
|
13409
14056
|
const form = await c.req.formData();
|
|
13410
14057
|
const slug = String(form.get("tenant") ?? "").trim().toLowerCase();
|
|
13411
14058
|
const redirect = String(form.get("redirect") ?? "");
|
|
13412
|
-
const svc = new
|
|
14059
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13413
14060
|
const tenant = await svc.getTenantBySlug(slug);
|
|
13414
14061
|
if (!tenant || tenant.status !== "active") {
|
|
13415
14062
|
return c.json({ error: "Unknown or inactive tenant" }, 400);
|
|
@@ -13419,7 +14066,7 @@ function createTenantAdminRoutes() {
|
|
|
13419
14066
|
if (!user.isSuperAdmin && !await svc.isMember(user.userId, slug)) {
|
|
13420
14067
|
return c.json({ error: "You are not a member of this tenant" }, 403);
|
|
13421
14068
|
}
|
|
13422
|
-
cookie.setCookie(c,
|
|
14069
|
+
cookie.setCookie(c, chunkKVBHB7QP_cjs.TENANT_COOKIE, slug, {
|
|
13423
14070
|
path: "/",
|
|
13424
14071
|
httpOnly: true,
|
|
13425
14072
|
sameSite: "Lax",
|
|
@@ -13436,7 +14083,7 @@ function createTenantAdminRoutes() {
|
|
|
13436
14083
|
if (!user) return c.redirect("/auth/login");
|
|
13437
14084
|
const token = c.req.query("token") ?? "";
|
|
13438
14085
|
try {
|
|
13439
|
-
const { slug } = await new
|
|
14086
|
+
const { slug } = await new chunk7RUW244J_cjs.TenantService(db).acceptInvitation(token, user.userId, user.email);
|
|
13440
14087
|
return c.redirect(`/admin/tenants/${slug}/members?message=Invitation accepted`);
|
|
13441
14088
|
} catch (error) {
|
|
13442
14089
|
const message = error instanceof Error ? error.message : "Failed to accept invitation";
|
|
@@ -13464,7 +14111,7 @@ function createTenantAdminRoutes() {
|
|
|
13464
14111
|
const userId = c.req.param("userId");
|
|
13465
14112
|
const target = await db.prepare("SELECT id, email FROM auth_user WHERE id = ?").bind(userId).first();
|
|
13466
14113
|
if (!target?.id) return c.redirect("/admin/users?message=User not found&type=error");
|
|
13467
|
-
const svc = new
|
|
14114
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13468
14115
|
const [memberships, allTenants] = await Promise.all([svc.listUserMemberships(userId), svc.listTenants()]);
|
|
13469
14116
|
const memberSlugs = new Set(memberships.map((m) => m.slug));
|
|
13470
14117
|
const availableTenants = allTenants.filter((t) => t.status === "active" && !memberSlugs.has(t.slug)).map((t) => ({ slug: t.slug, name: t.name }));
|
|
@@ -13489,10 +14136,10 @@ function createTenantAdminRoutes() {
|
|
|
13489
14136
|
const slug = String(form.get("slug") ?? "").trim().toLowerCase();
|
|
13490
14137
|
const role = String(form.get("role") ?? "viewer");
|
|
13491
14138
|
const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
|
|
13492
|
-
if (!
|
|
14139
|
+
if (!chunk7RUW244J_cjs.isValidMemberRole(role)) throw new Error(`Invalid role '${role}'`);
|
|
13493
14140
|
const target = await db.prepare("SELECT email FROM auth_user WHERE id = ?").bind(userId).first();
|
|
13494
14141
|
if (!target) throw new Error("User not found");
|
|
13495
|
-
const svc = new
|
|
14142
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13496
14143
|
if (!await svc.getTenantBySlug(slug)) throw new Error("Tenant not found");
|
|
13497
14144
|
if (await svc.isMember(userId, slug)) throw new Error(`Already a member of '${slug}'`);
|
|
13498
14145
|
await svc.addMember(slug, userId, role, target.email ?? null);
|
|
@@ -13511,7 +14158,7 @@ function createTenantAdminRoutes() {
|
|
|
13511
14158
|
const form = await c.req.formData();
|
|
13512
14159
|
const role = String(form.get("role") ?? "");
|
|
13513
14160
|
const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
|
|
13514
|
-
await new
|
|
14161
|
+
await new chunk7RUW244J_cjs.TenantService(db).setMemberRole(slug, userId, role);
|
|
13515
14162
|
return c.redirect(`${redirectTo}?message=Role updated`);
|
|
13516
14163
|
} catch (error) {
|
|
13517
14164
|
const message = error instanceof Error ? error.message : "Failed to update role";
|
|
@@ -13526,7 +14173,7 @@ function createTenantAdminRoutes() {
|
|
|
13526
14173
|
try {
|
|
13527
14174
|
const form = await c.req.formData();
|
|
13528
14175
|
const redirectTo = String(form.get("_redirect") ?? "") || `/admin/tenants/users/${userId}`;
|
|
13529
|
-
await new
|
|
14176
|
+
await new chunk7RUW244J_cjs.TenantService(db).removeMember(slug, userId);
|
|
13530
14177
|
return c.redirect(`${redirectTo}?message=Removed from ${encodeURIComponent(slug)}`);
|
|
13531
14178
|
} catch (error) {
|
|
13532
14179
|
const message = error instanceof Error ? error.message : "Failed to remove membership";
|
|
@@ -13541,7 +14188,7 @@ function createTenantAdminRoutes() {
|
|
|
13541
14188
|
return c.html(renderTenantsInactive({ user: userShape(cur), version }));
|
|
13542
14189
|
}
|
|
13543
14190
|
const roleName = c.req.param("roleName");
|
|
13544
|
-
const assignments = await new
|
|
14191
|
+
const assignments = await new chunk7RUW244J_cjs.TenantService(db).listAssignmentsByRole(roleName);
|
|
13545
14192
|
return c.html(renderRoleUsage({ roleName, assignments, user: userShape(cur), version }));
|
|
13546
14193
|
});
|
|
13547
14194
|
routes2.get("/", async (c) => {
|
|
@@ -13551,7 +14198,7 @@ function createTenantAdminRoutes() {
|
|
|
13551
14198
|
if (!await isMultiTenantActive(db)) {
|
|
13552
14199
|
return c.html(renderTenantsInactive({ user: userShape(user), version }));
|
|
13553
14200
|
}
|
|
13554
|
-
const svc = new
|
|
14201
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13555
14202
|
await svc.ensureDefaultTenant();
|
|
13556
14203
|
const tenants = await svc.listTenants();
|
|
13557
14204
|
const [docRes, memberRes] = await db.batch([
|
|
@@ -13590,7 +14237,7 @@ function createTenantAdminRoutes() {
|
|
|
13590
14237
|
formEntries = Object.fromEntries(form.entries());
|
|
13591
14238
|
const validated = tenantFormSchema.parse(formEntries);
|
|
13592
14239
|
if (!validated.slug) throw new zod.z.ZodError([{ code: "custom", message: "Slug is required", path: ["slug"] }]);
|
|
13593
|
-
const svc = new
|
|
14240
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13594
14241
|
await svc.createTenant({
|
|
13595
14242
|
name: validated.name,
|
|
13596
14243
|
slug: validated.slug,
|
|
@@ -13615,7 +14262,7 @@ function createTenantAdminRoutes() {
|
|
|
13615
14262
|
if (!await isMultiTenantActive(db)) {
|
|
13616
14263
|
return c.html(renderTenantsInactive({ user: userShape(user), version }));
|
|
13617
14264
|
}
|
|
13618
|
-
const tenant = await new
|
|
14265
|
+
const tenant = await new chunk7RUW244J_cjs.TenantService(db).getTenantBySlug(c.req.param("slug"));
|
|
13619
14266
|
if (!tenant) return c.redirect("/admin/tenants?message=Tenant not found&type=error");
|
|
13620
14267
|
return c.html(renderTenantForm({ tenant, isEdit: true, user: userShape(user), version }));
|
|
13621
14268
|
});
|
|
@@ -13625,7 +14272,7 @@ function createTenantAdminRoutes() {
|
|
|
13625
14272
|
const version = c.get("appVersion");
|
|
13626
14273
|
const slug = c.req.param("slug");
|
|
13627
14274
|
if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
|
|
13628
|
-
const svc = new
|
|
14275
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13629
14276
|
try {
|
|
13630
14277
|
const form = await c.req.formData();
|
|
13631
14278
|
const validated = tenantFormSchema.parse(Object.fromEntries(form.entries()));
|
|
@@ -13650,7 +14297,7 @@ function createTenantAdminRoutes() {
|
|
|
13650
14297
|
const slug = c.req.param("slug");
|
|
13651
14298
|
if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
|
|
13652
14299
|
try {
|
|
13653
|
-
await new
|
|
14300
|
+
await new chunk7RUW244J_cjs.TenantService(db).deleteTenant(slug);
|
|
13654
14301
|
return c.redirect("/admin/tenants?message=Tenant deleted successfully");
|
|
13655
14302
|
} catch (error) {
|
|
13656
14303
|
const message = error instanceof Error ? error.message : "Failed to delete tenant";
|
|
@@ -13665,7 +14312,7 @@ function createTenantAdminRoutes() {
|
|
|
13665
14312
|
return c.html(renderTenantsInactive({ user: userShape(user), version }));
|
|
13666
14313
|
}
|
|
13667
14314
|
const slug = c.req.param("slug");
|
|
13668
|
-
const svc = new
|
|
14315
|
+
const svc = new chunk7RUW244J_cjs.TenantService(db);
|
|
13669
14316
|
const tenant = await svc.getTenantBySlug(slug);
|
|
13670
14317
|
if (!tenant) return c.redirect("/admin/tenants?message=Tenant not found&type=error");
|
|
13671
14318
|
const [members, invitations] = await Promise.all([svc.listMembers(slug), svc.listInvitations(slug)]);
|
|
@@ -13691,7 +14338,7 @@ function createTenantAdminRoutes() {
|
|
|
13691
14338
|
const form = await c.req.formData();
|
|
13692
14339
|
const email = String(form.get("email") ?? "");
|
|
13693
14340
|
const role = String(form.get("role") ?? "viewer");
|
|
13694
|
-
await new
|
|
14341
|
+
await new chunk7RUW244J_cjs.TenantService(db).addMemberByEmail(slug, email, role);
|
|
13695
14342
|
return c.redirect(`/admin/tenants/${slug}/members?message=Member added`);
|
|
13696
14343
|
} catch (error) {
|
|
13697
14344
|
const message = error instanceof Error ? error.message : "Failed to add member";
|
|
@@ -13706,7 +14353,7 @@ function createTenantAdminRoutes() {
|
|
|
13706
14353
|
try {
|
|
13707
14354
|
const form = await c.req.formData();
|
|
13708
14355
|
const role = String(form.get("role") ?? "");
|
|
13709
|
-
await new
|
|
14356
|
+
await new chunk7RUW244J_cjs.TenantService(db).setMemberRole(slug, userId, role);
|
|
13710
14357
|
return c.redirect(`/admin/tenants/${slug}/members?message=Role updated`);
|
|
13711
14358
|
} catch (error) {
|
|
13712
14359
|
const message = error instanceof Error ? error.message : "Failed to update role";
|
|
@@ -13719,7 +14366,7 @@ function createTenantAdminRoutes() {
|
|
|
13719
14366
|
const userId = c.req.param("userId");
|
|
13720
14367
|
if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
|
|
13721
14368
|
try {
|
|
13722
|
-
await new
|
|
14369
|
+
await new chunk7RUW244J_cjs.TenantService(db).removeMember(slug, userId);
|
|
13723
14370
|
return c.redirect(`/admin/tenants/${slug}/members?message=Member removed`);
|
|
13724
14371
|
} catch (error) {
|
|
13725
14372
|
const message = error instanceof Error ? error.message : "Failed to remove member";
|
|
@@ -13735,12 +14382,12 @@ function createTenantAdminRoutes() {
|
|
|
13735
14382
|
const form = await c.req.formData();
|
|
13736
14383
|
const email = String(form.get("email") ?? "");
|
|
13737
14384
|
const role = String(form.get("role") ?? "viewer");
|
|
13738
|
-
const token = await new
|
|
14385
|
+
const token = await new chunk7RUW244J_cjs.TenantService(db).createInvitation(slug, email, role, user?.userId ?? null);
|
|
13739
14386
|
const origin = c.req.header("origin") || new URL(c.req.url).origin;
|
|
13740
14387
|
const acceptUrl = `${origin}/join/invite?token=${encodeURIComponent(token)}`;
|
|
13741
14388
|
let note;
|
|
13742
14389
|
let noteType = "";
|
|
13743
|
-
const svc2 =
|
|
14390
|
+
const svc2 = chunk7RUW244J_cjs.hasEmailService() ? chunk7RUW244J_cjs.getEmailService() : null;
|
|
13744
14391
|
const hasRealProvider = !!svc2 && svc2.getProviderName() !== "console";
|
|
13745
14392
|
if (hasRealProvider) {
|
|
13746
14393
|
const result = await svc2.send({
|
|
@@ -13781,7 +14428,7 @@ function createTenantAdminRoutes() {
|
|
|
13781
14428
|
WHERE i.id = ? AND t.slug = ? AND i.status = 'pending'`
|
|
13782
14429
|
).bind(id, slug).first();
|
|
13783
14430
|
if (!inv) throw new Error("Invitation not found or already used");
|
|
13784
|
-
const svc2 =
|
|
14431
|
+
const svc2 = chunk7RUW244J_cjs.hasEmailService() ? chunk7RUW244J_cjs.getEmailService() : null;
|
|
13785
14432
|
const hasRealProvider = !!svc2 && svc2.getProviderName() !== "console";
|
|
13786
14433
|
if (!hasRealProvider) throw new Error("No email plugin active");
|
|
13787
14434
|
const origin = c.req.header("origin") || new URL(c.req.url).origin;
|
|
@@ -13806,7 +14453,7 @@ function createTenantAdminRoutes() {
|
|
|
13806
14453
|
const id = c.req.param("id");
|
|
13807
14454
|
if (!await isMultiTenantActive(db)) return c.json({ error: "Multi-tenant plugin is not active" }, 403);
|
|
13808
14455
|
try {
|
|
13809
|
-
await new
|
|
14456
|
+
await new chunk7RUW244J_cjs.TenantService(db).revokeInvitation(slug, id);
|
|
13810
14457
|
return c.redirect(`/admin/tenants/${slug}/members?message=Invitation revoked`);
|
|
13811
14458
|
} catch (error) {
|
|
13812
14459
|
const message = error instanceof Error ? error.message : "Failed to revoke invitation";
|
|
@@ -14036,7 +14683,7 @@ function createJoinRoutes() {
|
|
|
14036
14683
|
if (existing) return rerender("An account with this email already exists. Please sign in instead.");
|
|
14037
14684
|
try {
|
|
14038
14685
|
const userId = crypto.randomUUID();
|
|
14039
|
-
const passwordHash = await
|
|
14686
|
+
const passwordHash = await chunkFCLKX2OS_cjs.AuthManager.hashPassword(password);
|
|
14040
14687
|
const now = Date.now();
|
|
14041
14688
|
const nowSec = Math.floor(now / 1e3);
|
|
14042
14689
|
await db.batch([
|
|
@@ -14049,8 +14696,8 @@ function createJoinRoutes() {
|
|
|
14049
14696
|
VALUES (?, ?, ?, 'credential', ?, ?, ?)`
|
|
14050
14697
|
).bind(`cred-${userId}`, userId, userId, passwordHash, nowSec, nowSec)
|
|
14051
14698
|
]);
|
|
14052
|
-
await new
|
|
14053
|
-
const auth =
|
|
14699
|
+
await new chunk7RUW244J_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
|
|
14700
|
+
const auth = chunkGMMCCIQO_cjs.createAuth(c.env);
|
|
14054
14701
|
const origin = new URL(c.req.url).origin;
|
|
14055
14702
|
const baReq = new Request(`${origin}/auth/sign-in/email`, {
|
|
14056
14703
|
method: "POST",
|
|
@@ -14105,7 +14752,7 @@ function createJoinRoutes() {
|
|
|
14105
14752
|
version
|
|
14106
14753
|
}), 400);
|
|
14107
14754
|
try {
|
|
14108
|
-
const auth =
|
|
14755
|
+
const auth = chunkGMMCCIQO_cjs.createAuth(c.env);
|
|
14109
14756
|
const origin = new URL(c.req.url).origin;
|
|
14110
14757
|
const baReq = new Request(`${origin}/auth/sign-in/email`, {
|
|
14111
14758
|
method: "POST",
|
|
@@ -14117,7 +14764,7 @@ function createJoinRoutes() {
|
|
|
14117
14764
|
const baBody = await baRes.json();
|
|
14118
14765
|
const userId = baBody?.user?.id;
|
|
14119
14766
|
if (!userId) return rerender("Sign-in succeeded but could not read user ID.");
|
|
14120
|
-
await new
|
|
14767
|
+
await new chunk7RUW244J_cjs.TenantService(db).acceptInvitation(token, userId, inv.email);
|
|
14121
14768
|
const headers = new Headers({ Location: "/admin?message=Welcome! You have joined " + encodeURIComponent(inv.tenantName) });
|
|
14122
14769
|
copyBaCookies(baRes, headers);
|
|
14123
14770
|
return new Response(null, { status: 302, headers });
|
|
@@ -14131,7 +14778,7 @@ function createJoinRoutes() {
|
|
|
14131
14778
|
|
|
14132
14779
|
// src/plugins/core-plugins/multi-tenant-plugin/index.ts
|
|
14133
14780
|
var TENANT_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3.75 21h16.5M4.5 3h15M5.25 3v18m13.5-18v18M9 6.75h1.5m-1.5 3h1.5m-1.5 3h1.5m3-6H15m-1.5 3H15m-1.5 3H15M9 21v-3.375c0-.621.504-1.125 1.125-1.125h3.75c.621 0 1.125.504 1.125 1.125V21"/></svg>`;
|
|
14134
|
-
var multiTenantPlugin =
|
|
14781
|
+
var multiTenantPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
14135
14782
|
id: manifest_default2.id,
|
|
14136
14783
|
version: "1.0.0",
|
|
14137
14784
|
name: manifest_default2.name,
|
|
@@ -14146,30 +14793,30 @@ var multiTenantPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
14146
14793
|
{ label: "Tenants", path: "/admin/tenants", icon: TENANT_ICON, order: 80 }
|
|
14147
14794
|
],
|
|
14148
14795
|
activate: async () => {
|
|
14149
|
-
|
|
14796
|
+
chunkKVBHB7QP_cjs.invalidateTenantCache();
|
|
14150
14797
|
console.info("\u2705 Multi-Tenant plugin activated");
|
|
14151
14798
|
},
|
|
14152
14799
|
deactivate: async () => {
|
|
14153
|
-
|
|
14800
|
+
chunkKVBHB7QP_cjs.invalidateTenantCache();
|
|
14154
14801
|
console.info("\u274C Multi-Tenant plugin deactivated");
|
|
14155
14802
|
}
|
|
14156
14803
|
});
|
|
14157
14804
|
var routes = new hono.Hono();
|
|
14158
|
-
routes.use("*",
|
|
14159
|
-
routes.use("*",
|
|
14805
|
+
routes.use("*", chunkFCLKX2OS_cjs.requireAuth());
|
|
14806
|
+
routes.use("*", chunkFCLKX2OS_cjs.requireRole(["admin", "editor"]));
|
|
14160
14807
|
routes.get("/:rootId", async (c) => {
|
|
14161
14808
|
const { rootId } = c.req.param();
|
|
14162
14809
|
const db = c.env.DB;
|
|
14163
|
-
const scope = await
|
|
14810
|
+
const scope = await chunk7RUW244J_cjs.resolveDocScope(c, db, { rootId });
|
|
14164
14811
|
if (!scope) {
|
|
14165
14812
|
return c.html('<p class="text-zinc-500 dark:text-zinc-400 p-4">Document not found.</p>', 404);
|
|
14166
14813
|
}
|
|
14167
14814
|
if (!scope.docType?.settings?.versioning) {
|
|
14168
14815
|
return c.html('<p class="text-zinc-500 dark:text-zinc-400 p-4">Versioning not enabled for this type.</p>', 404);
|
|
14169
14816
|
}
|
|
14170
|
-
const denied = await
|
|
14817
|
+
const denied = await chunk7RUW244J_cjs.denyIfNotAllowed(c, db, rootId, "read", scope.docType?.settings, scope.tenantId);
|
|
14171
14818
|
if (denied) return denied;
|
|
14172
|
-
const repo = new
|
|
14819
|
+
const repo = new chunk7RUW244J_cjs.DocumentRepository(db, scope.tenantId);
|
|
14173
14820
|
const versions = await repo.getVersionHistory(rootId);
|
|
14174
14821
|
const safeRootIdAttr = chunkMNWKYY5E_cjs.escapeHtml(rootId);
|
|
14175
14822
|
const rows = versions.map((v) => {
|
|
@@ -14262,14 +14909,14 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
|
|
|
14262
14909
|
const { rootId, versionNumber } = c.req.param();
|
|
14263
14910
|
const db = c.env.DB;
|
|
14264
14911
|
const user = c.get("user");
|
|
14265
|
-
const scope = await
|
|
14912
|
+
const scope = await chunk7RUW244J_cjs.resolveDocScope(c, db, { rootId });
|
|
14266
14913
|
if (!scope) {
|
|
14267
14914
|
return c.json({ error: "Document not found" }, 404);
|
|
14268
14915
|
}
|
|
14269
14916
|
if (!scope.docType?.settings?.versioning) {
|
|
14270
14917
|
return c.json({ error: "Versioning not enabled for this type" }, 404);
|
|
14271
14918
|
}
|
|
14272
|
-
const denied = await
|
|
14919
|
+
const denied = await chunk7RUW244J_cjs.denyIfNotAllowed(c, db, rootId, "update", scope.docType?.settings, scope.tenantId);
|
|
14273
14920
|
if (denied) return denied;
|
|
14274
14921
|
const row = await db.prepare("SELECT * FROM documents WHERE root_id = ? AND tenant_id = ? AND version_number = ? LIMIT 1").bind(rootId, scope.tenantId, Number(versionNumber)).first();
|
|
14275
14922
|
if (!row) {
|
|
@@ -14279,7 +14926,7 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
|
|
|
14279
14926
|
const title = row.title ?? null;
|
|
14280
14927
|
const slug = row.slug ?? null;
|
|
14281
14928
|
const docType = scope.docType;
|
|
14282
|
-
const svc = new
|
|
14929
|
+
const svc = new chunkLTZ5WYOK_cjs.DocumentsService(db, {
|
|
14283
14930
|
queryableFields: docType?.queryableFields ?? [],
|
|
14284
14931
|
typeSchemaVersion: docType?.schemaVersion ?? 1,
|
|
14285
14932
|
maxVersionsPerRoot: docType?.settings?.maxVersionsPerRoot ?? 50,
|
|
@@ -14292,7 +14939,7 @@ routes.post("/:rootId/restore/:versionNumber", async (c) => {
|
|
|
14292
14939
|
var routes_default = routes;
|
|
14293
14940
|
|
|
14294
14941
|
// src/plugins/core-plugins/versioning-plugin/index.ts
|
|
14295
|
-
var versioningPlugin =
|
|
14942
|
+
var versioningPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
14296
14943
|
id: "versioning",
|
|
14297
14944
|
version: "1.0.0",
|
|
14298
14945
|
name: "Versioning",
|
|
@@ -14369,8 +15016,8 @@ function createMagicLinkAuthPlugin() {
|
|
|
14369
15016
|
const baseUrl = new URL(c.req.url).origin;
|
|
14370
15017
|
const magicLink = `${baseUrl}/auth/magic-link/verify?token=${token}`;
|
|
14371
15018
|
try {
|
|
14372
|
-
if (
|
|
14373
|
-
await
|
|
15019
|
+
if (chunk7RUW244J_cjs.hasEmailService()) {
|
|
15020
|
+
await chunk7RUW244J_cjs.getEmailService().send({
|
|
14374
15021
|
to: normalizedEmail,
|
|
14375
15022
|
subject: "Your Magic Link to Sign In",
|
|
14376
15023
|
flow: "magic-link",
|
|
@@ -14447,19 +15094,19 @@ function createMagicLinkAuthPlugin() {
|
|
|
14447
15094
|
SET used = 1, used_at = ?
|
|
14448
15095
|
WHERE id = ?
|
|
14449
15096
|
`).bind(Date.now(), magicLink.id).run();
|
|
14450
|
-
const tokenTtl = await
|
|
14451
|
-
const jwtToken = await
|
|
15097
|
+
const tokenTtl = await chunkFCLKX2OS_cjs.getJwtExpirySecondsFromDb(c.env.DB, c.env);
|
|
15098
|
+
const jwtToken = await chunkFCLKX2OS_cjs.AuthManager.generateToken(
|
|
14452
15099
|
user.id,
|
|
14453
15100
|
user.email,
|
|
14454
15101
|
user.role,
|
|
14455
15102
|
c.env.JWT_SECRET,
|
|
14456
15103
|
tokenTtl
|
|
14457
15104
|
);
|
|
14458
|
-
|
|
15105
|
+
chunkFCLKX2OS_cjs.AuthManager.setAuthCookie(c, jwtToken, { maxAge: tokenTtl });
|
|
14459
15106
|
await db.prepare(`
|
|
14460
15107
|
UPDATE auth_user SET last_login_at = ? WHERE id = ?
|
|
14461
15108
|
`).bind(Date.now(), user.id).run();
|
|
14462
|
-
|
|
15109
|
+
chunk7RUW244J_cjs.dispatchHookEvent(
|
|
14463
15110
|
c,
|
|
14464
15111
|
"auth:magic-link:consumed",
|
|
14465
15112
|
{ user: { id: user.id, email: user.email, role: user.role } },
|
|
@@ -14944,7 +15591,7 @@ async function warmCollections(db) {
|
|
|
14944
15591
|
const collectionCache = chunkYA3TJ65D_cjs.getCacheService(config);
|
|
14945
15592
|
let count = 0;
|
|
14946
15593
|
try {
|
|
14947
|
-
const results =
|
|
15594
|
+
const results = chunkKVBHB7QP_cjs.getCollectionRegistry().listActive().map(chunkKVBHB7QP_cjs.collectionRecordToRow);
|
|
14948
15595
|
for (const collection of results) {
|
|
14949
15596
|
const key = collectionCache.generateKey("item", collection.id);
|
|
14950
15597
|
await collectionCache.set(key, collection);
|
|
@@ -15011,7 +15658,7 @@ async function warmNamespace(namespace, entries) {
|
|
|
15011
15658
|
}
|
|
15012
15659
|
|
|
15013
15660
|
// src/templates/pages/admin-cache.template.ts
|
|
15014
|
-
|
|
15661
|
+
chunkK623Q6WD_cjs.init_admin_layout_catalyst_template();
|
|
15015
15662
|
function renderCacheDashboard(data) {
|
|
15016
15663
|
const pageContent = `
|
|
15017
15664
|
<div class="space-y-6">
|
|
@@ -15215,7 +15862,7 @@ function renderCacheDashboard(data) {
|
|
|
15215
15862
|
</script>
|
|
15216
15863
|
|
|
15217
15864
|
<!-- Confirmation Dialogs -->
|
|
15218
|
-
${
|
|
15865
|
+
${chunk7RUW244J_cjs.renderConfirmationDialog({
|
|
15219
15866
|
id: "clear-all-cache-confirm",
|
|
15220
15867
|
title: "Clear All Cache",
|
|
15221
15868
|
message: "Are you sure you want to clear all cache entries? This cannot be undone.",
|
|
@@ -15226,7 +15873,7 @@ function renderCacheDashboard(data) {
|
|
|
15226
15873
|
onConfirm: "performClearAllCaches()"
|
|
15227
15874
|
})}
|
|
15228
15875
|
|
|
15229
|
-
${
|
|
15876
|
+
${chunk7RUW244J_cjs.renderConfirmationDialog({
|
|
15230
15877
|
id: "clear-namespace-cache-confirm",
|
|
15231
15878
|
title: "Clear Namespace Cache",
|
|
15232
15879
|
message: "Clear cache for this namespace?",
|
|
@@ -15237,7 +15884,7 @@ function renderCacheDashboard(data) {
|
|
|
15237
15884
|
onConfirm: "performClearNamespaceCache()"
|
|
15238
15885
|
})}
|
|
15239
15886
|
|
|
15240
|
-
${
|
|
15887
|
+
${chunk7RUW244J_cjs.getConfirmationDialogScript()}
|
|
15241
15888
|
`;
|
|
15242
15889
|
const layoutData = {
|
|
15243
15890
|
title: "Cache System",
|
|
@@ -15247,7 +15894,7 @@ function renderCacheDashboard(data) {
|
|
|
15247
15894
|
version: data.version,
|
|
15248
15895
|
content: pageContent
|
|
15249
15896
|
};
|
|
15250
|
-
return
|
|
15897
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst(layoutData);
|
|
15251
15898
|
}
|
|
15252
15899
|
function renderCollectionSettingsTab(collections) {
|
|
15253
15900
|
if (collections.length === 0) {
|
|
@@ -15503,7 +16150,7 @@ app.get("/", async (c) => {
|
|
|
15503
16150
|
const totalRequests = totalHits + totalMisses;
|
|
15504
16151
|
const overallHitRate = totalRequests > 0 ? totalHits / totalRequests * 100 : 0;
|
|
15505
16152
|
const DEFAULT_TTL = chunkYA3TJ65D_cjs.CACHE_CONFIGS.api?.ttl ?? 300;
|
|
15506
|
-
const collections =
|
|
16153
|
+
const collections = chunkKVBHB7QP_cjs.getCollectionRegistry().listActive().filter((r) => !r.internal).map((r) => {
|
|
15507
16154
|
const cacheOverride = r.cache;
|
|
15508
16155
|
const cacheEnabled = cacheOverride?.enabled !== false;
|
|
15509
16156
|
const hasCustomTtl = typeof cacheOverride?.ttl === "number";
|
|
@@ -16040,16 +16687,17 @@ var faviconSvg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
|
16040
16687
|
// src/app.ts
|
|
16041
16688
|
function createSonicJSApp(config = {}) {
|
|
16042
16689
|
const app2 = new hono.Hono();
|
|
16043
|
-
const appVersion = config.version ||
|
|
16690
|
+
const appVersion = config.version || chunkAOUVUF32_cjs.getCoreVersion();
|
|
16044
16691
|
const appName = config.name || "SonicJS AI";
|
|
16045
|
-
const hookSystem = new
|
|
16692
|
+
const hookSystem = new chunk5UXU3LP4_cjs.HookSystemImpl();
|
|
16046
16693
|
chunkJ6JTWD2A_cjs.setHookSystem(hookSystem);
|
|
16047
16694
|
const magicLinkPlugin = createMagicLinkAuthPlugin();
|
|
16048
16695
|
const corePluginsBeforeCatchAll = [
|
|
16049
16696
|
securityAuditPlugin,
|
|
16697
|
+
apiKeysPlugin,
|
|
16050
16698
|
aiSearchPlugin,
|
|
16051
16699
|
oauthProvidersPlugin,
|
|
16052
|
-
|
|
16700
|
+
chunk7RUW244J_cjs.userProfilesPlugin,
|
|
16053
16701
|
otpLoginPlugin,
|
|
16054
16702
|
analyticsPlugin,
|
|
16055
16703
|
stripePlugin,
|
|
@@ -16059,23 +16707,23 @@ function createSonicJSApp(config = {}) {
|
|
|
16059
16707
|
shortcodesPlugin,
|
|
16060
16708
|
helloWorldPlugin,
|
|
16061
16709
|
multiTenantPlugin,
|
|
16062
|
-
|
|
16710
|
+
chunk7RUW244J_cjs.lexicalEditorPlugin,
|
|
16063
16711
|
versioningPlugin
|
|
16064
16712
|
];
|
|
16065
16713
|
const corePluginsAfterCatchAll = [emailPluginV3, magicLinkPlugin, emailReconciliationPlugin];
|
|
16066
|
-
const wirePlugins =
|
|
16714
|
+
const wirePlugins = chunk5UXU3LP4_cjs.createPluginWirer(
|
|
16067
16715
|
() => [...corePluginsBeforeCatchAll, ...corePluginsAfterCatchAll, ...config.plugins?.register ?? []],
|
|
16068
16716
|
// The capability-gated `ctx.cap.email` resolves to the app EmailService, which
|
|
16069
16717
|
// is initialized (below) just before wiring on the first request.
|
|
16070
16718
|
() => ({
|
|
16071
16719
|
hooks: hookSystem,
|
|
16072
16720
|
env: firstRequestEnv,
|
|
16073
|
-
providers: { email: () =>
|
|
16721
|
+
providers: { email: () => chunk7RUW244J_cjs.getEmailService() }
|
|
16074
16722
|
})
|
|
16075
16723
|
);
|
|
16076
16724
|
let firstRequestEnv;
|
|
16077
16725
|
const initEmailService = async (env = {}) => {
|
|
16078
|
-
if (
|
|
16726
|
+
if (chunk7RUW244J_cjs.hasEmailService()) return;
|
|
16079
16727
|
let provider;
|
|
16080
16728
|
let defaultFrom = config.email?.from;
|
|
16081
16729
|
let defaultReplyTo;
|
|
@@ -16110,14 +16758,14 @@ function createSonicJSApp(config = {}) {
|
|
|
16110
16758
|
}
|
|
16111
16759
|
}
|
|
16112
16760
|
defaultFrom = defaultFrom || env.DEFAULT_FROM_EMAIL || "noreply@sonicjs.local";
|
|
16113
|
-
|
|
16761
|
+
chunk7RUW244J_cjs.setEmailService(new EmailService({ provider, defaultFrom, defaultReplyTo, db: env.DB }));
|
|
16114
16762
|
};
|
|
16115
16763
|
app2.use("*", async (c, next) => {
|
|
16116
16764
|
c.set("appVersion", appVersion);
|
|
16117
16765
|
await next();
|
|
16118
16766
|
});
|
|
16119
|
-
app2.use("*",
|
|
16120
|
-
app2.use("*",
|
|
16767
|
+
app2.use("*", chunkFCLKX2OS_cjs.metricsMiddleware());
|
|
16768
|
+
app2.use("*", chunkFCLKX2OS_cjs.bootstrapMiddleware(config));
|
|
16121
16769
|
const boot = async (env) => {
|
|
16122
16770
|
if (config.plugins?.disableAll) return;
|
|
16123
16771
|
firstRequestEnv = env;
|
|
@@ -16144,13 +16792,24 @@ function createSonicJSApp(config = {}) {
|
|
|
16144
16792
|
app2.use("*", async (_c, next) => {
|
|
16145
16793
|
await next();
|
|
16146
16794
|
});
|
|
16147
|
-
app2.use("*",
|
|
16148
|
-
|
|
16795
|
+
app2.use("*", cors.cors({
|
|
16796
|
+
origin: (origin, c) => {
|
|
16797
|
+
const allowed = c.env?.CORS_ORIGINS;
|
|
16798
|
+
if (!allowed) return null;
|
|
16799
|
+
const list = allowed.split(",").map((s) => s.trim());
|
|
16800
|
+
return list.includes(origin) ? origin : null;
|
|
16801
|
+
},
|
|
16802
|
+
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
16803
|
+
allowHeaders: ["Content-Type", "Authorization", "X-API-Key"],
|
|
16804
|
+
credentials: true
|
|
16805
|
+
}));
|
|
16806
|
+
app2.use("*", chunkFCLKX2OS_cjs.securityHeadersMiddleware());
|
|
16807
|
+
app2.use("*", chunkFCLKX2OS_cjs.csrfProtection());
|
|
16149
16808
|
app2.use("*", async (c, next) => {
|
|
16150
16809
|
try {
|
|
16151
16810
|
const reqUrl = new URL(c.req.url);
|
|
16152
16811
|
const requestBaseURL = `${reqUrl.protocol}//${reqUrl.host}`;
|
|
16153
|
-
const auth =
|
|
16812
|
+
const auth = chunkGMMCCIQO_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
|
|
16154
16813
|
const session = await auth.api.getSession({ headers: c.req.raw.headers });
|
|
16155
16814
|
if (session?.user) {
|
|
16156
16815
|
const u = session.user;
|
|
@@ -16177,14 +16836,15 @@ function createSonicJSApp(config = {}) {
|
|
|
16177
16836
|
}
|
|
16178
16837
|
await next();
|
|
16179
16838
|
});
|
|
16839
|
+
app2.use("*", apiKeyAuthMiddleware());
|
|
16180
16840
|
if (config.middleware?.afterAuth) {
|
|
16181
16841
|
for (const middleware of config.middleware.afterAuth) {
|
|
16182
16842
|
app2.use("*", middleware);
|
|
16183
16843
|
}
|
|
16184
16844
|
}
|
|
16185
|
-
app2.use("*",
|
|
16186
|
-
app2.use("/admin/*",
|
|
16187
|
-
app2.use("/admin/*",
|
|
16845
|
+
app2.use("*", chunkKVBHB7QP_cjs.tenantMiddleware());
|
|
16846
|
+
app2.use("/admin/*", chunkFCLKX2OS_cjs.requireAuth());
|
|
16847
|
+
app2.use("/admin/*", chunkFCLKX2OS_cjs.requireRbac("portal", "access"));
|
|
16188
16848
|
app2.use("/admin/*", pluginMenuMiddleware());
|
|
16189
16849
|
const NAV_LANDING = [
|
|
16190
16850
|
{ path: "/admin/content", perm: "content:read" },
|
|
@@ -16201,7 +16861,7 @@ function createSonicJSApp(config = {}) {
|
|
|
16201
16861
|
if (!user?.userId) return next();
|
|
16202
16862
|
let perms = [];
|
|
16203
16863
|
try {
|
|
16204
|
-
const { RbacService: RbacService2 } = await import('./rbac-
|
|
16864
|
+
const { RbacService: RbacService2 } = await import('./rbac-7QZ4JZ2E.cjs');
|
|
16205
16865
|
perms = await new RbacService2(c.env.DB, c.env.CACHE_KV).permissionsForUser(user.userId);
|
|
16206
16866
|
} catch {
|
|
16207
16867
|
return next();
|
|
@@ -16230,43 +16890,43 @@ function createSonicJSApp(config = {}) {
|
|
|
16230
16890
|
});
|
|
16231
16891
|
app2.route("/api/security-audit", apiRoutes2);
|
|
16232
16892
|
app2.route("/admin/plugins/security-audit", adminRoutes3);
|
|
16233
|
-
app2.route("/api/media",
|
|
16234
|
-
app2.route("/api/system",
|
|
16235
|
-
app2.route("/api/documents",
|
|
16236
|
-
app2.route("/api",
|
|
16237
|
-
app2.route("/admin/documents",
|
|
16238
|
-
|
|
16239
|
-
app2.route("/admin/api",
|
|
16240
|
-
app2.route("/admin/collections",
|
|
16241
|
-
app2.route("/admin/settings",
|
|
16242
|
-
app2.route("/admin/api-reference",
|
|
16893
|
+
app2.route("/api/media", chunk7RUW244J_cjs.api_media_default);
|
|
16894
|
+
app2.route("/api/system", chunk7RUW244J_cjs.api_system_default);
|
|
16895
|
+
app2.route("/api/documents", chunk7RUW244J_cjs.apiDocumentsRoutes);
|
|
16896
|
+
app2.route("/api", chunk7RUW244J_cjs.api_default);
|
|
16897
|
+
app2.route("/admin/documents", chunk7RUW244J_cjs.adminDocumentsRoutes);
|
|
16898
|
+
chunk5UXU3LP4_cjs.registerPluginRoutes(app2, [formsPlugin], { source: "core" });
|
|
16899
|
+
app2.route("/admin/api", chunk7RUW244J_cjs.admin_api_default);
|
|
16900
|
+
app2.route("/admin/collections", chunk7RUW244J_cjs.adminCollectionsRoutes);
|
|
16901
|
+
app2.route("/admin/settings", chunk7RUW244J_cjs.adminSettingsRoutes);
|
|
16902
|
+
app2.route("/admin/api-reference", chunk7RUW244J_cjs.router2);
|
|
16243
16903
|
app2.route("/admin/database-tools", createDatabaseToolsAdminRoutes());
|
|
16244
|
-
app2.route("/admin/content",
|
|
16245
|
-
app2.route("/admin/media",
|
|
16904
|
+
app2.route("/admin/content", chunk7RUW244J_cjs.admin_content_default);
|
|
16905
|
+
app2.route("/admin/media", chunk7RUW244J_cjs.adminMediaRoutes);
|
|
16246
16906
|
app2.use("/auth/*", securityAuditMiddleware());
|
|
16247
16907
|
if (!config.plugins?.disableAll) {
|
|
16248
|
-
|
|
16908
|
+
chunk5UXU3LP4_cjs.registerPluginRoutes(app2, corePluginsBeforeCatchAll, { source: "core" });
|
|
16249
16909
|
app2.route("/admin/cache", cache_default.getRoutes());
|
|
16250
16910
|
if (config.plugins?.register && config.plugins.register.length > 0) {
|
|
16251
|
-
|
|
16911
|
+
chunk5UXU3LP4_cjs.registerPluginRoutes(app2, config.plugins.register, { source: "user" });
|
|
16252
16912
|
}
|
|
16253
16913
|
}
|
|
16254
16914
|
app2.route("/api/events", apiRoutes4);
|
|
16255
|
-
app2.route("/admin/dashboard",
|
|
16256
|
-
app2.route("/admin/plugins",
|
|
16257
|
-
app2.route("/admin/logs",
|
|
16915
|
+
app2.route("/admin/dashboard", chunk7RUW244J_cjs.router);
|
|
16916
|
+
app2.route("/admin/plugins", chunk7RUW244J_cjs.adminPluginRoutes);
|
|
16917
|
+
app2.route("/admin/logs", chunk7RUW244J_cjs.adminLogsRoutes);
|
|
16258
16918
|
app2.route("/admin/rbac", adminRbacRoutes);
|
|
16259
|
-
app2.route("/admin",
|
|
16260
|
-
app2.route("/auth",
|
|
16919
|
+
app2.route("/admin", chunk7RUW244J_cjs.userRoutes);
|
|
16920
|
+
app2.route("/auth", chunk7RUW244J_cjs.auth_default);
|
|
16261
16921
|
app2.on(["GET", "POST"], "/auth/*", (c) => {
|
|
16262
16922
|
const reqUrl = new URL(c.req.url);
|
|
16263
16923
|
const requestBaseURL = `${reqUrl.protocol}//${reqUrl.host}`;
|
|
16264
|
-
const auth =
|
|
16924
|
+
const auth = chunkGMMCCIQO_cjs.createAuth(c.env, config.auth?.extendBetterAuth, requestBaseURL);
|
|
16265
16925
|
return auth.handler(c.req.raw);
|
|
16266
16926
|
});
|
|
16267
|
-
app2.route("/",
|
|
16927
|
+
app2.route("/", chunk7RUW244J_cjs.test_cleanup_default);
|
|
16268
16928
|
if (!config.plugins?.disableAll) {
|
|
16269
|
-
|
|
16929
|
+
chunk5UXU3LP4_cjs.registerPluginRoutes(app2, corePluginsAfterCatchAll, { source: "core" });
|
|
16270
16930
|
}
|
|
16271
16931
|
if (!config.plugins?.disableAll) {
|
|
16272
16932
|
const allMountedPlugins = [
|
|
@@ -16275,8 +16935,11 @@ function createSonicJSApp(config = {}) {
|
|
|
16275
16935
|
...corePluginsAfterCatchAll,
|
|
16276
16936
|
...config.plugins?.register ?? []
|
|
16277
16937
|
];
|
|
16278
|
-
|
|
16279
|
-
|
|
16938
|
+
const userPlugins = (config.plugins?.register ?? []).filter(
|
|
16939
|
+
(p) => !chunkKVBHB7QP_cjs.PLUGIN_REGISTRY[p.id]
|
|
16940
|
+
);
|
|
16941
|
+
chunk5UXU3LP4_cjs.setPluginMenu(userPlugins.flatMap((p) => p.menu ?? []));
|
|
16942
|
+
chunkA4KUJ3LD_cjs.setPluginDefinitions(allMountedPlugins);
|
|
16280
16943
|
}
|
|
16281
16944
|
app2.get("/favicon.svg", (c) => {
|
|
16282
16945
|
return new Response(faviconSvg, {
|
|
@@ -16329,7 +16992,7 @@ function createSonicJSApp(config = {}) {
|
|
|
16329
16992
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16330
16993
|
});
|
|
16331
16994
|
});
|
|
16332
|
-
|
|
16995
|
+
chunk36Z3AKX3_cjs.setAppInstance(app2);
|
|
16333
16996
|
app2.notFound((c) => {
|
|
16334
16997
|
return c.json({ error: "Not Found", status: 404 }, 404);
|
|
16335
16998
|
});
|
|
@@ -17140,9 +17803,11 @@ var RedirectService = class {
|
|
|
17140
17803
|
this.cloudflareService = new CloudflareBulkService(env);
|
|
17141
17804
|
}
|
|
17142
17805
|
}
|
|
17806
|
+
db;
|
|
17807
|
+
env;
|
|
17143
17808
|
cloudflareService = null;
|
|
17144
17809
|
getDocService() {
|
|
17145
|
-
return new
|
|
17810
|
+
return new chunkLTZ5WYOK_cjs.DocumentsService(this.db, {
|
|
17146
17811
|
queryableFields: REDIRECT_QUERYABLE_FIELDS,
|
|
17147
17812
|
maxVersionsPerRoot: 1,
|
|
17148
17813
|
tenantId: TENANT3
|
|
@@ -17258,7 +17923,7 @@ var RedirectService = class {
|
|
|
17258
17923
|
async batchCreate(rows, userId) {
|
|
17259
17924
|
const now = Math.floor(Date.now() / 1e3);
|
|
17260
17925
|
const statements = rows.map((r) => {
|
|
17261
|
-
const id =
|
|
17926
|
+
const id = chunkKIGVVO6N_cjs.nanoid();
|
|
17262
17927
|
const data = JSON.stringify({
|
|
17263
17928
|
source: r.source,
|
|
17264
17929
|
destination: r.destination,
|
|
@@ -18445,7 +19110,7 @@ function renderLayout(title, content2) {
|
|
|
18445
19110
|
}
|
|
18446
19111
|
</style>
|
|
18447
19112
|
`;
|
|
18448
|
-
return
|
|
19113
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
18449
19114
|
title,
|
|
18450
19115
|
currentPath: "/admin/redirects",
|
|
18451
19116
|
content: customStyles + content2.toString()
|
|
@@ -18810,7 +19475,7 @@ function getFormScripts() {
|
|
|
18810
19475
|
`;
|
|
18811
19476
|
}
|
|
18812
19477
|
function renderLayout2(title, content2) {
|
|
18813
|
-
return
|
|
19478
|
+
return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst({
|
|
18814
19479
|
title,
|
|
18815
19480
|
currentPath: "/admin/redirects",
|
|
18816
19481
|
content: content2.toString()
|
|
@@ -19768,7 +20433,7 @@ function createRedirectApiRoutes() {
|
|
|
19768
20433
|
});
|
|
19769
20434
|
return api;
|
|
19770
20435
|
}
|
|
19771
|
-
var redirectPlugin =
|
|
20436
|
+
var redirectPlugin = chunkA4KUJ3LD_cjs.definePlugin({
|
|
19772
20437
|
id: manifest_default3.id,
|
|
19773
20438
|
version: manifest_default3.version,
|
|
19774
20439
|
name: manifest_default3.name,
|
|
@@ -19786,7 +20451,7 @@ var redirectPlugin = chunkXW56B23A_cjs.definePlugin({
|
|
|
19786
20451
|
async onBoot(ctx) {
|
|
19787
20452
|
const db = ctx.env?.DB;
|
|
19788
20453
|
if (!db) return;
|
|
19789
|
-
const registry = new
|
|
20454
|
+
const registry = new chunkFCLKX2OS_cjs.DocumentTypeRegistry(db);
|
|
19790
20455
|
await registry.register({
|
|
19791
20456
|
id: "redirect",
|
|
19792
20457
|
name: "redirect",
|
|
@@ -19902,99 +20567,103 @@ function createDb(d1$1) {
|
|
|
19902
20567
|
}
|
|
19903
20568
|
|
|
19904
20569
|
// src/index.ts
|
|
19905
|
-
var VERSION =
|
|
20570
|
+
var VERSION = chunkAOUVUF32_cjs.package_default.version;
|
|
19906
20571
|
|
|
20572
|
+
Object.defineProperty(exports, "DocumentRepository", {
|
|
20573
|
+
enumerable: true,
|
|
20574
|
+
get: function () { return chunk7RUW244J_cjs.DocumentRepository; }
|
|
20575
|
+
});
|
|
19907
20576
|
Object.defineProperty(exports, "ROUTES_INFO", {
|
|
19908
20577
|
enumerable: true,
|
|
19909
|
-
get: function () { return
|
|
20578
|
+
get: function () { return chunk7RUW244J_cjs.ROUTES_INFO; }
|
|
19910
20579
|
});
|
|
19911
20580
|
Object.defineProperty(exports, "adminApiRoutes", {
|
|
19912
20581
|
enumerable: true,
|
|
19913
|
-
get: function () { return
|
|
20582
|
+
get: function () { return chunk7RUW244J_cjs.admin_api_default; }
|
|
19914
20583
|
});
|
|
19915
20584
|
Object.defineProperty(exports, "adminCheckboxRoutes", {
|
|
19916
20585
|
enumerable: true,
|
|
19917
|
-
get: function () { return
|
|
20586
|
+
get: function () { return chunk7RUW244J_cjs.adminCheckboxRoutes; }
|
|
19918
20587
|
});
|
|
19919
20588
|
Object.defineProperty(exports, "adminCollectionsRoutes", {
|
|
19920
20589
|
enumerable: true,
|
|
19921
|
-
get: function () { return
|
|
20590
|
+
get: function () { return chunk7RUW244J_cjs.adminCollectionsRoutes; }
|
|
19922
20591
|
});
|
|
19923
20592
|
Object.defineProperty(exports, "adminContentRoutes", {
|
|
19924
20593
|
enumerable: true,
|
|
19925
|
-
get: function () { return
|
|
20594
|
+
get: function () { return chunk7RUW244J_cjs.admin_content_default; }
|
|
19926
20595
|
});
|
|
19927
20596
|
Object.defineProperty(exports, "adminDashboardRoutes", {
|
|
19928
20597
|
enumerable: true,
|
|
19929
|
-
get: function () { return
|
|
20598
|
+
get: function () { return chunk7RUW244J_cjs.router; }
|
|
19930
20599
|
});
|
|
19931
20600
|
Object.defineProperty(exports, "adminLogsRoutes", {
|
|
19932
20601
|
enumerable: true,
|
|
19933
|
-
get: function () { return
|
|
20602
|
+
get: function () { return chunk7RUW244J_cjs.adminLogsRoutes; }
|
|
19934
20603
|
});
|
|
19935
20604
|
Object.defineProperty(exports, "adminMediaRoutes", {
|
|
19936
20605
|
enumerable: true,
|
|
19937
|
-
get: function () { return
|
|
20606
|
+
get: function () { return chunk7RUW244J_cjs.adminMediaRoutes; }
|
|
19938
20607
|
});
|
|
19939
20608
|
Object.defineProperty(exports, "adminPluginRoutes", {
|
|
19940
20609
|
enumerable: true,
|
|
19941
|
-
get: function () { return
|
|
20610
|
+
get: function () { return chunk7RUW244J_cjs.adminPluginRoutes; }
|
|
19942
20611
|
});
|
|
19943
20612
|
Object.defineProperty(exports, "adminSettingsRoutes", {
|
|
19944
20613
|
enumerable: true,
|
|
19945
|
-
get: function () { return
|
|
20614
|
+
get: function () { return chunk7RUW244J_cjs.adminSettingsRoutes; }
|
|
19946
20615
|
});
|
|
19947
20616
|
Object.defineProperty(exports, "adminUsersRoutes", {
|
|
19948
20617
|
enumerable: true,
|
|
19949
|
-
get: function () { return
|
|
20618
|
+
get: function () { return chunk7RUW244J_cjs.userRoutes; }
|
|
19950
20619
|
});
|
|
19951
20620
|
Object.defineProperty(exports, "apiContentCrudRoutes", {
|
|
19952
20621
|
enumerable: true,
|
|
19953
|
-
get: function () { return
|
|
20622
|
+
get: function () { return chunk7RUW244J_cjs.api_content_crud_default; }
|
|
19954
20623
|
});
|
|
19955
20624
|
Object.defineProperty(exports, "apiMediaRoutes", {
|
|
19956
20625
|
enumerable: true,
|
|
19957
|
-
get: function () { return
|
|
20626
|
+
get: function () { return chunk7RUW244J_cjs.api_media_default; }
|
|
19958
20627
|
});
|
|
19959
20628
|
Object.defineProperty(exports, "apiRoutes", {
|
|
19960
20629
|
enumerable: true,
|
|
19961
|
-
get: function () { return
|
|
20630
|
+
get: function () { return chunk7RUW244J_cjs.api_default; }
|
|
19962
20631
|
});
|
|
19963
20632
|
Object.defineProperty(exports, "apiSystemRoutes", {
|
|
19964
20633
|
enumerable: true,
|
|
19965
|
-
get: function () { return
|
|
20634
|
+
get: function () { return chunk7RUW244J_cjs.api_system_default; }
|
|
19966
20635
|
});
|
|
19967
20636
|
Object.defineProperty(exports, "authRoutes", {
|
|
19968
20637
|
enumerable: true,
|
|
19969
|
-
get: function () { return
|
|
20638
|
+
get: function () { return chunk7RUW244J_cjs.auth_default; }
|
|
19970
20639
|
});
|
|
19971
20640
|
Object.defineProperty(exports, "createUserProfilesPlugin", {
|
|
19972
20641
|
enumerable: true,
|
|
19973
|
-
get: function () { return
|
|
20642
|
+
get: function () { return chunk7RUW244J_cjs.createUserProfilesPlugin; }
|
|
19974
20643
|
});
|
|
19975
20644
|
Object.defineProperty(exports, "defineUserProfile", {
|
|
19976
20645
|
enumerable: true,
|
|
19977
|
-
get: function () { return
|
|
20646
|
+
get: function () { return chunk7RUW244J_cjs.defineUserProfile; }
|
|
19978
20647
|
});
|
|
19979
20648
|
Object.defineProperty(exports, "getUserProfileConfig", {
|
|
19980
20649
|
enumerable: true,
|
|
19981
|
-
get: function () { return
|
|
20650
|
+
get: function () { return chunk7RUW244J_cjs.getUserProfileConfig; }
|
|
19982
20651
|
});
|
|
19983
20652
|
Object.defineProperty(exports, "userProfilesPlugin", {
|
|
19984
20653
|
enumerable: true,
|
|
19985
|
-
get: function () { return
|
|
20654
|
+
get: function () { return chunk7RUW244J_cjs.userProfilesPlugin; }
|
|
19986
20655
|
});
|
|
19987
20656
|
Object.defineProperty(exports, "Logger", {
|
|
19988
20657
|
enumerable: true,
|
|
19989
|
-
get: function () { return
|
|
20658
|
+
get: function () { return chunk36Z3AKX3_cjs.Logger; }
|
|
19990
20659
|
});
|
|
19991
20660
|
Object.defineProperty(exports, "getLogger", {
|
|
19992
20661
|
enumerable: true,
|
|
19993
|
-
get: function () { return
|
|
20662
|
+
get: function () { return chunk36Z3AKX3_cjs.getLogger; }
|
|
19994
20663
|
});
|
|
19995
20664
|
Object.defineProperty(exports, "initLogger", {
|
|
19996
20665
|
enumerable: true,
|
|
19997
|
-
get: function () { return
|
|
20666
|
+
get: function () { return chunk36Z3AKX3_cjs.initLogger; }
|
|
19998
20667
|
});
|
|
19999
20668
|
Object.defineProperty(exports, "apiTokens", {
|
|
20000
20669
|
enumerable: true,
|
|
@@ -20138,251 +20807,259 @@ Object.defineProperty(exports, "workflowHistory", {
|
|
|
20138
20807
|
});
|
|
20139
20808
|
Object.defineProperty(exports, "AuthManager", {
|
|
20140
20809
|
enumerable: true,
|
|
20141
|
-
get: function () { return
|
|
20810
|
+
get: function () { return chunkFCLKX2OS_cjs.AuthManager; }
|
|
20142
20811
|
});
|
|
20143
20812
|
Object.defineProperty(exports, "PermissionManager", {
|
|
20144
20813
|
enumerable: true,
|
|
20145
|
-
get: function () { return
|
|
20814
|
+
get: function () { return chunkFCLKX2OS_cjs.PermissionManager; }
|
|
20146
20815
|
});
|
|
20147
20816
|
Object.defineProperty(exports, "bootstrapDocumentTypes", {
|
|
20148
20817
|
enumerable: true,
|
|
20149
|
-
get: function () { return
|
|
20818
|
+
get: function () { return chunkFCLKX2OS_cjs.bootstrapDocumentTypes; }
|
|
20150
20819
|
});
|
|
20151
20820
|
Object.defineProperty(exports, "bootstrapMiddleware", {
|
|
20152
20821
|
enumerable: true,
|
|
20153
|
-
get: function () { return
|
|
20822
|
+
get: function () { return chunkFCLKX2OS_cjs.bootstrapMiddleware; }
|
|
20154
20823
|
});
|
|
20155
20824
|
Object.defineProperty(exports, "cacheHeaders", {
|
|
20156
20825
|
enumerable: true,
|
|
20157
|
-
get: function () { return
|
|
20826
|
+
get: function () { return chunkFCLKX2OS_cjs.cacheHeaders; }
|
|
20158
20827
|
});
|
|
20159
20828
|
Object.defineProperty(exports, "compressionMiddleware", {
|
|
20160
20829
|
enumerable: true,
|
|
20161
|
-
get: function () { return
|
|
20830
|
+
get: function () { return chunkFCLKX2OS_cjs.compressionMiddleware; }
|
|
20162
20831
|
});
|
|
20163
20832
|
Object.defineProperty(exports, "detailedLoggingMiddleware", {
|
|
20164
20833
|
enumerable: true,
|
|
20165
|
-
get: function () { return
|
|
20834
|
+
get: function () { return chunkFCLKX2OS_cjs.detailedLoggingMiddleware; }
|
|
20166
20835
|
});
|
|
20167
20836
|
Object.defineProperty(exports, "getActivePlugins", {
|
|
20168
20837
|
enumerable: true,
|
|
20169
|
-
get: function () { return
|
|
20838
|
+
get: function () { return chunkFCLKX2OS_cjs.getActivePlugins; }
|
|
20170
20839
|
});
|
|
20171
20840
|
Object.defineProperty(exports, "isPluginActive", {
|
|
20172
20841
|
enumerable: true,
|
|
20173
|
-
get: function () { return
|
|
20842
|
+
get: function () { return chunkFCLKX2OS_cjs.isPluginActive; }
|
|
20174
20843
|
});
|
|
20175
20844
|
Object.defineProperty(exports, "logActivity", {
|
|
20176
20845
|
enumerable: true,
|
|
20177
|
-
get: function () { return
|
|
20846
|
+
get: function () { return chunkFCLKX2OS_cjs.logActivity; }
|
|
20178
20847
|
});
|
|
20179
20848
|
Object.defineProperty(exports, "loggingMiddleware", {
|
|
20180
20849
|
enumerable: true,
|
|
20181
|
-
get: function () { return
|
|
20850
|
+
get: function () { return chunkFCLKX2OS_cjs.loggingMiddleware; }
|
|
20182
20851
|
});
|
|
20183
20852
|
Object.defineProperty(exports, "optionalAuth", {
|
|
20184
20853
|
enumerable: true,
|
|
20185
|
-
get: function () { return
|
|
20854
|
+
get: function () { return chunkFCLKX2OS_cjs.optionalAuth; }
|
|
20186
20855
|
});
|
|
20187
20856
|
Object.defineProperty(exports, "performanceLoggingMiddleware", {
|
|
20188
20857
|
enumerable: true,
|
|
20189
|
-
get: function () { return
|
|
20858
|
+
get: function () { return chunkFCLKX2OS_cjs.performanceLoggingMiddleware; }
|
|
20190
20859
|
});
|
|
20191
20860
|
Object.defineProperty(exports, "requireActivePlugin", {
|
|
20192
20861
|
enumerable: true,
|
|
20193
|
-
get: function () { return
|
|
20862
|
+
get: function () { return chunkFCLKX2OS_cjs.requireActivePlugin; }
|
|
20194
20863
|
});
|
|
20195
20864
|
Object.defineProperty(exports, "requireActivePlugins", {
|
|
20196
20865
|
enumerable: true,
|
|
20197
|
-
get: function () { return
|
|
20866
|
+
get: function () { return chunkFCLKX2OS_cjs.requireActivePlugins; }
|
|
20198
20867
|
});
|
|
20199
20868
|
Object.defineProperty(exports, "requireAnyPermission", {
|
|
20200
20869
|
enumerable: true,
|
|
20201
|
-
get: function () { return
|
|
20870
|
+
get: function () { return chunkFCLKX2OS_cjs.requireAnyPermission; }
|
|
20202
20871
|
});
|
|
20203
20872
|
Object.defineProperty(exports, "requireAuth", {
|
|
20204
20873
|
enumerable: true,
|
|
20205
|
-
get: function () { return
|
|
20874
|
+
get: function () { return chunkFCLKX2OS_cjs.requireAuth; }
|
|
20206
20875
|
});
|
|
20207
20876
|
Object.defineProperty(exports, "requirePermission", {
|
|
20208
20877
|
enumerable: true,
|
|
20209
|
-
get: function () { return
|
|
20878
|
+
get: function () { return chunkFCLKX2OS_cjs.requirePermission; }
|
|
20210
20879
|
});
|
|
20211
20880
|
Object.defineProperty(exports, "requireRole", {
|
|
20212
20881
|
enumerable: true,
|
|
20213
|
-
get: function () { return
|
|
20882
|
+
get: function () { return chunkFCLKX2OS_cjs.requireRole; }
|
|
20214
20883
|
});
|
|
20215
20884
|
Object.defineProperty(exports, "securityHeaders", {
|
|
20216
20885
|
enumerable: true,
|
|
20217
|
-
get: function () { return
|
|
20886
|
+
get: function () { return chunkFCLKX2OS_cjs.securityHeadersMiddleware; }
|
|
20218
20887
|
});
|
|
20219
20888
|
Object.defineProperty(exports, "securityLoggingMiddleware", {
|
|
20220
20889
|
enumerable: true,
|
|
20221
|
-
get: function () { return
|
|
20890
|
+
get: function () { return chunkFCLKX2OS_cjs.securityLoggingMiddleware; }
|
|
20891
|
+
});
|
|
20892
|
+
Object.defineProperty(exports, "DocumentsService", {
|
|
20893
|
+
enumerable: true,
|
|
20894
|
+
get: function () { return chunkLTZ5WYOK_cjs.DocumentsService; }
|
|
20222
20895
|
});
|
|
20223
20896
|
Object.defineProperty(exports, "RbacService", {
|
|
20224
20897
|
enumerable: true,
|
|
20225
|
-
get: function () { return
|
|
20898
|
+
get: function () { return chunkLTZ5WYOK_cjs.RbacService; }
|
|
20226
20899
|
});
|
|
20227
20900
|
Object.defineProperty(exports, "PluginBootstrapService", {
|
|
20228
20901
|
enumerable: true,
|
|
20229
|
-
get: function () { return
|
|
20902
|
+
get: function () { return chunkKVBHB7QP_cjs.PluginBootstrapService; }
|
|
20230
20903
|
});
|
|
20231
20904
|
Object.defineProperty(exports, "PluginServiceClass", {
|
|
20232
20905
|
enumerable: true,
|
|
20233
|
-
get: function () { return
|
|
20906
|
+
get: function () { return chunkKVBHB7QP_cjs.PluginService; }
|
|
20234
20907
|
});
|
|
20235
20908
|
Object.defineProperty(exports, "getAvailableCollectionNames", {
|
|
20236
20909
|
enumerable: true,
|
|
20237
|
-
get: function () { return
|
|
20910
|
+
get: function () { return chunkKVBHB7QP_cjs.getAvailableCollectionNames; }
|
|
20238
20911
|
});
|
|
20239
20912
|
Object.defineProperty(exports, "loadCollectionConfig", {
|
|
20240
20913
|
enumerable: true,
|
|
20241
|
-
get: function () { return
|
|
20914
|
+
get: function () { return chunkKVBHB7QP_cjs.loadCollectionConfig; }
|
|
20242
20915
|
});
|
|
20243
20916
|
Object.defineProperty(exports, "loadCollectionConfigs", {
|
|
20244
20917
|
enumerable: true,
|
|
20245
|
-
get: function () { return
|
|
20918
|
+
get: function () { return chunkKVBHB7QP_cjs.loadCollectionConfigs; }
|
|
20246
20919
|
});
|
|
20247
20920
|
Object.defineProperty(exports, "registerCollections", {
|
|
20248
20921
|
enumerable: true,
|
|
20249
|
-
get: function () { return
|
|
20922
|
+
get: function () { return chunkKVBHB7QP_cjs.registerCollections; }
|
|
20250
20923
|
});
|
|
20251
20924
|
Object.defineProperty(exports, "validateCollectionConfig", {
|
|
20252
20925
|
enumerable: true,
|
|
20253
|
-
get: function () { return
|
|
20926
|
+
get: function () { return chunkKVBHB7QP_cjs.validateCollectionConfig; }
|
|
20254
20927
|
});
|
|
20255
20928
|
Object.defineProperty(exports, "MigrationService", {
|
|
20256
20929
|
enumerable: true,
|
|
20257
|
-
get: function () { return
|
|
20930
|
+
get: function () { return chunkOJC4G5JE_cjs.MigrationService; }
|
|
20258
20931
|
});
|
|
20259
20932
|
Object.defineProperty(exports, "renderFilterBar", {
|
|
20260
20933
|
enumerable: true,
|
|
20261
|
-
get: function () { return
|
|
20934
|
+
get: function () { return chunkCRGUD4KC_cjs.renderFilterBar; }
|
|
20262
20935
|
});
|
|
20263
20936
|
Object.defineProperty(exports, "getConfirmationDialogScript", {
|
|
20264
20937
|
enumerable: true,
|
|
20265
|
-
get: function () { return
|
|
20938
|
+
get: function () { return chunkPXNTCCPE_cjs.getConfirmationDialogScript; }
|
|
20266
20939
|
});
|
|
20267
20940
|
Object.defineProperty(exports, "renderAlert", {
|
|
20268
20941
|
enumerable: true,
|
|
20269
|
-
get: function () { return
|
|
20942
|
+
get: function () { return chunkPXNTCCPE_cjs.renderAlert; }
|
|
20270
20943
|
});
|
|
20271
20944
|
Object.defineProperty(exports, "renderConfirmationDialog", {
|
|
20272
20945
|
enumerable: true,
|
|
20273
|
-
get: function () { return
|
|
20946
|
+
get: function () { return chunkPXNTCCPE_cjs.renderConfirmationDialog; }
|
|
20274
20947
|
});
|
|
20275
20948
|
Object.defineProperty(exports, "renderForm", {
|
|
20276
20949
|
enumerable: true,
|
|
20277
|
-
get: function () { return
|
|
20950
|
+
get: function () { return chunkPXNTCCPE_cjs.renderForm; }
|
|
20278
20951
|
});
|
|
20279
20952
|
Object.defineProperty(exports, "renderFormField", {
|
|
20280
20953
|
enumerable: true,
|
|
20281
|
-
get: function () { return
|
|
20954
|
+
get: function () { return chunkPXNTCCPE_cjs.renderFormField; }
|
|
20282
20955
|
});
|
|
20283
20956
|
Object.defineProperty(exports, "renderPagination", {
|
|
20284
20957
|
enumerable: true,
|
|
20285
|
-
get: function () { return
|
|
20958
|
+
get: function () { return chunkPXNTCCPE_cjs.renderPagination; }
|
|
20286
20959
|
});
|
|
20287
20960
|
Object.defineProperty(exports, "renderTable", {
|
|
20288
20961
|
enumerable: true,
|
|
20289
|
-
get: function () { return
|
|
20962
|
+
get: function () { return chunkPXNTCCPE_cjs.renderTable; }
|
|
20963
|
+
});
|
|
20964
|
+
Object.defineProperty(exports, "renderAdminLayoutCatalyst", {
|
|
20965
|
+
enumerable: true,
|
|
20966
|
+
get: function () { return chunkK623Q6WD_cjs.renderAdminLayoutCatalyst; }
|
|
20290
20967
|
});
|
|
20291
20968
|
Object.defineProperty(exports, "HookSystemImpl", {
|
|
20292
20969
|
enumerable: true,
|
|
20293
|
-
get: function () { return
|
|
20970
|
+
get: function () { return chunk5UXU3LP4_cjs.HookSystemImpl; }
|
|
20294
20971
|
});
|
|
20295
20972
|
Object.defineProperty(exports, "HookUtils", {
|
|
20296
20973
|
enumerable: true,
|
|
20297
|
-
get: function () { return
|
|
20974
|
+
get: function () { return chunk5UXU3LP4_cjs.HookUtils; }
|
|
20298
20975
|
});
|
|
20299
20976
|
Object.defineProperty(exports, "PluginDependencyCycleError", {
|
|
20300
20977
|
enumerable: true,
|
|
20301
|
-
get: function () { return
|
|
20978
|
+
get: function () { return chunk5UXU3LP4_cjs.PluginDependencyCycleError; }
|
|
20302
20979
|
});
|
|
20303
20980
|
Object.defineProperty(exports, "PluginManagerClass", {
|
|
20304
20981
|
enumerable: true,
|
|
20305
|
-
get: function () { return
|
|
20982
|
+
get: function () { return chunk5UXU3LP4_cjs.PluginManager; }
|
|
20306
20983
|
});
|
|
20307
20984
|
Object.defineProperty(exports, "PluginRegistryImpl", {
|
|
20308
20985
|
enumerable: true,
|
|
20309
|
-
get: function () { return
|
|
20986
|
+
get: function () { return chunk5UXU3LP4_cjs.PluginRegistryImpl; }
|
|
20310
20987
|
});
|
|
20311
20988
|
Object.defineProperty(exports, "PluginValidatorClass", {
|
|
20312
20989
|
enumerable: true,
|
|
20313
|
-
get: function () { return
|
|
20990
|
+
get: function () { return chunk5UXU3LP4_cjs.PluginValidator; }
|
|
20314
20991
|
});
|
|
20315
20992
|
Object.defineProperty(exports, "RegisterPluginsError", {
|
|
20316
20993
|
enumerable: true,
|
|
20317
|
-
get: function () { return
|
|
20994
|
+
get: function () { return chunk5UXU3LP4_cjs.RegisterPluginsError; }
|
|
20318
20995
|
});
|
|
20319
20996
|
Object.defineProperty(exports, "ScopedHookSystemClass", {
|
|
20320
20997
|
enumerable: true,
|
|
20321
|
-
get: function () { return
|
|
20998
|
+
get: function () { return chunk5UXU3LP4_cjs.ScopedHookSystem; }
|
|
20322
20999
|
});
|
|
20323
21000
|
Object.defineProperty(exports, "collectCronSchedules", {
|
|
20324
21001
|
enumerable: true,
|
|
20325
|
-
get: function () { return
|
|
21002
|
+
get: function () { return chunk5UXU3LP4_cjs.collectCronSchedules; }
|
|
20326
21003
|
});
|
|
20327
21004
|
Object.defineProperty(exports, "collectCrons", {
|
|
20328
21005
|
enumerable: true,
|
|
20329
|
-
get: function () { return
|
|
21006
|
+
get: function () { return chunk5UXU3LP4_cjs.collectCrons; }
|
|
20330
21007
|
});
|
|
20331
21008
|
Object.defineProperty(exports, "createScheduledHandler", {
|
|
20332
21009
|
enumerable: true,
|
|
20333
|
-
get: function () { return
|
|
21010
|
+
get: function () { return chunk5UXU3LP4_cjs.createScheduledHandler; }
|
|
20334
21011
|
});
|
|
20335
21012
|
Object.defineProperty(exports, "dispatchCronTick", {
|
|
20336
21013
|
enumerable: true,
|
|
20337
|
-
get: function () { return
|
|
21014
|
+
get: function () { return chunk5UXU3LP4_cjs.dispatchCronTick; }
|
|
20338
21015
|
});
|
|
20339
21016
|
Object.defineProperty(exports, "getPluginMenu", {
|
|
20340
21017
|
enumerable: true,
|
|
20341
|
-
get: function () { return
|
|
21018
|
+
get: function () { return chunk5UXU3LP4_cjs.getPluginMenu; }
|
|
20342
21019
|
});
|
|
20343
21020
|
Object.defineProperty(exports, "registerPlugins", {
|
|
20344
21021
|
enumerable: true,
|
|
20345
|
-
get: function () { return
|
|
21022
|
+
get: function () { return chunk5UXU3LP4_cjs.registerPlugins; }
|
|
20346
21023
|
});
|
|
20347
21024
|
Object.defineProperty(exports, "resetPluginMenu", {
|
|
20348
21025
|
enumerable: true,
|
|
20349
|
-
get: function () { return
|
|
21026
|
+
get: function () { return chunk5UXU3LP4_cjs.resetPluginMenu; }
|
|
20350
21027
|
});
|
|
20351
21028
|
Object.defineProperty(exports, "resolvePluginMenuItems", {
|
|
20352
21029
|
enumerable: true,
|
|
20353
|
-
get: function () { return
|
|
21030
|
+
get: function () { return chunk5UXU3LP4_cjs.resolvePluginMenuItems; }
|
|
20354
21031
|
});
|
|
20355
21032
|
Object.defineProperty(exports, "setPluginMenu", {
|
|
20356
21033
|
enumerable: true,
|
|
20357
|
-
get: function () { return
|
|
21034
|
+
get: function () { return chunk5UXU3LP4_cjs.setPluginMenu; }
|
|
20358
21035
|
});
|
|
20359
21036
|
Object.defineProperty(exports, "topoSort", {
|
|
20360
21037
|
enumerable: true,
|
|
20361
|
-
get: function () { return
|
|
21038
|
+
get: function () { return chunk5UXU3LP4_cjs.topoSort; }
|
|
20362
21039
|
});
|
|
20363
21040
|
Object.defineProperty(exports, "applySchemaDefaults", {
|
|
20364
21041
|
enumerable: true,
|
|
20365
|
-
get: function () { return
|
|
21042
|
+
get: function () { return chunkA4KUJ3LD_cjs.applySchemaDefaults; }
|
|
20366
21043
|
});
|
|
20367
21044
|
Object.defineProperty(exports, "definePlugin", {
|
|
20368
21045
|
enumerable: true,
|
|
20369
|
-
get: function () { return
|
|
21046
|
+
get: function () { return chunkA4KUJ3LD_cjs.definePlugin; }
|
|
20370
21047
|
});
|
|
20371
21048
|
Object.defineProperty(exports, "isDefinedPlugin", {
|
|
20372
21049
|
enumerable: true,
|
|
20373
|
-
get: function () { return
|
|
21050
|
+
get: function () { return chunkA4KUJ3LD_cjs.isDefinedPlugin; }
|
|
20374
21051
|
});
|
|
20375
21052
|
Object.defineProperty(exports, "parseConfigSchema", {
|
|
20376
21053
|
enumerable: true,
|
|
20377
|
-
get: function () { return
|
|
21054
|
+
get: function () { return chunkA4KUJ3LD_cjs.parseConfigSchema; }
|
|
20378
21055
|
});
|
|
20379
21056
|
Object.defineProperty(exports, "parseFormDataToSettings", {
|
|
20380
21057
|
enumerable: true,
|
|
20381
|
-
get: function () { return
|
|
21058
|
+
get: function () { return chunkA4KUJ3LD_cjs.parseFormDataToSettings; }
|
|
20382
21059
|
});
|
|
20383
21060
|
Object.defineProperty(exports, "renderSchemaFields", {
|
|
20384
21061
|
enumerable: true,
|
|
20385
|
-
get: function () { return
|
|
21062
|
+
get: function () { return chunkA4KUJ3LD_cjs.renderSchemaFields; }
|
|
20386
21063
|
});
|
|
20387
21064
|
Object.defineProperty(exports, "getHookSystem", {
|
|
20388
21065
|
enumerable: true,
|
|
@@ -20430,11 +21107,11 @@ Object.defineProperty(exports, "metricsTracker", {
|
|
|
20430
21107
|
});
|
|
20431
21108
|
Object.defineProperty(exports, "SONICJS_VERSION", {
|
|
20432
21109
|
enumerable: true,
|
|
20433
|
-
get: function () { return
|
|
21110
|
+
get: function () { return chunkAOUVUF32_cjs.SONICJS_VERSION; }
|
|
20434
21111
|
});
|
|
20435
21112
|
Object.defineProperty(exports, "getCoreVersion", {
|
|
20436
21113
|
enumerable: true,
|
|
20437
|
-
get: function () { return
|
|
21114
|
+
get: function () { return chunkAOUVUF32_cjs.getCoreVersion; }
|
|
20438
21115
|
});
|
|
20439
21116
|
Object.defineProperty(exports, "escapeHtml", {
|
|
20440
21117
|
enumerable: true,
|
|
@@ -20457,11 +21134,13 @@ exports.CloudflareEmailProvider = CloudflareEmailProvider2;
|
|
|
20457
21134
|
exports.OAuthService = OAuthService;
|
|
20458
21135
|
exports.VERSION = VERSION;
|
|
20459
21136
|
exports.createDb = createDb;
|
|
21137
|
+
exports.createHelloWorldPlugin = createHelloWorldPlugin;
|
|
20460
21138
|
exports.createOAuthProvidersPlugin = createOAuthProvidersPlugin;
|
|
20461
21139
|
exports.createRedirectPlugin = createRedirectPlugin;
|
|
20462
21140
|
exports.createSonicJSApp = createSonicJSApp;
|
|
20463
21141
|
exports.emailReconciliationPlugin = emailReconciliationPlugin;
|
|
20464
21142
|
exports.generateTriggersComment = generateTriggersComment;
|
|
21143
|
+
exports.helloWorldPlugin = helloWorldPlugin;
|
|
20465
21144
|
exports.oauthProvidersPlugin = oauthProvidersPlugin;
|
|
20466
21145
|
exports.parseCronTriggers = parseCronTriggers;
|
|
20467
21146
|
exports.redirectPlugin = redirectPlugin;
|