@infuro/cms-core 1.0.16 → 1.0.18
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 +739 -724
- package/dist/admin.cjs +1 -1
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.js +1 -1
- package/dist/admin.js.map +1 -1
- package/dist/api.cjs +132 -57
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +132 -57
- package/dist/api.js.map +1 -1
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/cli.cjs +21 -6
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +21 -6
- package/dist/cli.js.map +1 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js.map +1 -1
- package/dist/{index-h42MoUNq.d.cts → index-D2C1O9b4.d.cts} +8 -1
- package/dist/{index-C85X7cc7.d.ts → index-GMn7-9PX.d.ts} +8 -1
- package/dist/index.cjs +135 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +135 -57
- package/dist/index.js.map +1 -1
- package/dist/migrations/1772178563554-InitialSchema.ts +304 -304
- package/dist/migrations/1772178563555-ChatAndKnowledgeBase.ts +55 -55
- package/dist/migrations/1772178563556-KnowledgeBaseVector.ts +16 -16
- package/dist/migrations/1774300000000-RbacSeedGroupsAndPermissionUnique.ts +24 -24
- package/dist/migrations/1774300000001-SeedAdministratorUsersPermission.ts +35 -35
- package/dist/migrations/1774400000000-CustomerAdminAccessContactUser.ts +37 -37
- package/dist/migrations/1774400000001-StorefrontCartWishlist.ts +100 -100
- package/dist/migrations/1774400000002-WishlistGuestId.ts +29 -29
- package/dist/migrations/1774500000000-ProductCollectionHsn.ts +15 -15
- package/dist/migrations/1774600000000-OrderKindParentOrderNumber.ts +36 -36
- package/dist/migrations/1774800000000-OtpChallengesUserPhone.ts +41 -41
- package/dist/migrations/1774900000000-MessageTemplates.ts +39 -39
- package/dist/migrations/1775000000000-ProductUomTypeOrderItemSnapshots.ts +29 -29
- package/dist/migrations/1775200000000-MediaDriveFolders.ts +38 -38
- package/dist/migrations/README.md +3 -3
- package/dist/theme.cjs.map +1 -1
- package/dist/theme.js.map +1 -1
- package/package.json +13 -6
- package/src/admin/admin.css +72 -72
package/dist/index.cjs
CHANGED
|
@@ -4544,7 +4544,7 @@ function createFormSubmissionHandler(config) {
|
|
|
4544
4544
|
};
|
|
4545
4545
|
}
|
|
4546
4546
|
function createUsersApiHandlers(config) {
|
|
4547
|
-
const { dataSource, entityMap, json, requireAuth, requireEntityPermission, baseUrl, getCms, getCompanyDetails } = config;
|
|
4547
|
+
const { dataSource, entityMap, json, requireAuth, requireEntityPermission, baseUrl, getCms, getCompanyDetails, getSessionUser } = config;
|
|
4548
4548
|
async function trySendInviteEmail(toEmail, inviteLink, inviteeName) {
|
|
4549
4549
|
if (!getCms) return;
|
|
4550
4550
|
try {
|
|
@@ -4580,7 +4580,10 @@ function createUsersApiHandlers(config) {
|
|
|
4580
4580
|
const sortField = url.searchParams.get("sortField") || "createdAt";
|
|
4581
4581
|
const sortOrder = url.searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
|
|
4582
4582
|
const search = url.searchParams.get("search");
|
|
4583
|
-
const where = search ? [
|
|
4583
|
+
const where = search ? [
|
|
4584
|
+
{ name: (0, import_typeorm5.ILike)(`%${search}%`), deleted: false },
|
|
4585
|
+
{ email: (0, import_typeorm5.ILike)(`%${search}%`), deleted: false }
|
|
4586
|
+
] : { deleted: false };
|
|
4584
4587
|
const [data, total] = await userRepo().findAndCount({
|
|
4585
4588
|
skip,
|
|
4586
4589
|
take: limit,
|
|
@@ -4645,7 +4648,7 @@ function createUsersApiHandlers(config) {
|
|
|
4645
4648
|
}
|
|
4646
4649
|
try {
|
|
4647
4650
|
const user = await userRepo().findOne({
|
|
4648
|
-
where: { id: parseInt(id, 10) },
|
|
4651
|
+
where: { id: parseInt(id, 10), deleted: false },
|
|
4649
4652
|
relations: ["group"],
|
|
4650
4653
|
select: ["id", "name", "email", "blocked", "createdAt", "updatedAt", "groupId"]
|
|
4651
4654
|
});
|
|
@@ -4663,11 +4666,14 @@ function createUsersApiHandlers(config) {
|
|
|
4663
4666
|
if (pe) return pe;
|
|
4664
4667
|
}
|
|
4665
4668
|
try {
|
|
4669
|
+
const uid = parseInt(id, 10);
|
|
4670
|
+
const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });
|
|
4671
|
+
if (!existing) return json({ error: "Not found" }, { status: 404 });
|
|
4666
4672
|
const body = await req.json();
|
|
4667
4673
|
const { password: _p, ...safe } = body;
|
|
4668
|
-
await userRepo().update(
|
|
4674
|
+
await userRepo().update(uid, safe);
|
|
4669
4675
|
const updated = await userRepo().findOne({
|
|
4670
|
-
where: { id:
|
|
4676
|
+
where: { id: uid, deleted: false },
|
|
4671
4677
|
relations: ["group"],
|
|
4672
4678
|
select: ["id", "name", "email", "blocked", "createdAt", "updatedAt", "groupId"]
|
|
4673
4679
|
});
|
|
@@ -4684,8 +4690,23 @@ function createUsersApiHandlers(config) {
|
|
|
4684
4690
|
if (pe) return pe;
|
|
4685
4691
|
}
|
|
4686
4692
|
try {
|
|
4687
|
-
const
|
|
4688
|
-
|
|
4693
|
+
const uid = parseInt(id, 10);
|
|
4694
|
+
const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });
|
|
4695
|
+
if (!existing) return json({ error: "User not found" }, { status: 404 });
|
|
4696
|
+
let deletedBy = null;
|
|
4697
|
+
if (getSessionUser) {
|
|
4698
|
+
try {
|
|
4699
|
+
const u = await getSessionUser();
|
|
4700
|
+
if (u?.id) {
|
|
4701
|
+
const n = Number(u.id);
|
|
4702
|
+
if (Number.isFinite(n)) deletedBy = n;
|
|
4703
|
+
}
|
|
4704
|
+
} catch {
|
|
4705
|
+
}
|
|
4706
|
+
}
|
|
4707
|
+
const payload = { deleted: true, deletedAt: /* @__PURE__ */ new Date() };
|
|
4708
|
+
if (deletedBy != null) payload.deletedBy = deletedBy;
|
|
4709
|
+
await userRepo().update(uid, payload);
|
|
4689
4710
|
return json({ message: "User deleted successfully" });
|
|
4690
4711
|
} catch {
|
|
4691
4712
|
return json({ error: "Server Error" }, { status: 500 });
|
|
@@ -4699,7 +4720,10 @@ function createUsersApiHandlers(config) {
|
|
|
4699
4720
|
if (pe) return pe;
|
|
4700
4721
|
}
|
|
4701
4722
|
try {
|
|
4702
|
-
const user = await userRepo().findOne({
|
|
4723
|
+
const user = await userRepo().findOne({
|
|
4724
|
+
where: { id: parseInt(id, 10), deleted: false },
|
|
4725
|
+
select: ["email", "name"]
|
|
4726
|
+
});
|
|
4703
4727
|
if (!user) return json({ error: "User not found" }, { status: 404 });
|
|
4704
4728
|
const emailToken = Buffer.from(user.email).toString("base64");
|
|
4705
4729
|
const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;
|
|
@@ -7945,6 +7969,28 @@ function buildSearchWhereClause(repo, search) {
|
|
|
7945
7969
|
if (ors.length === 0) return {};
|
|
7946
7970
|
return ors.length === 1 ? ors[0] : ors;
|
|
7947
7971
|
}
|
|
7972
|
+
function entityHasSoftDelete(repo) {
|
|
7973
|
+
return repo.metadata.columns.some((c) => c.propertyName === "deleted");
|
|
7974
|
+
}
|
|
7975
|
+
function mergeDeletedFalseWhere(repo, where) {
|
|
7976
|
+
if (!entityHasSoftDelete(repo)) return where;
|
|
7977
|
+
const d = { deleted: false };
|
|
7978
|
+
if (Array.isArray(where)) {
|
|
7979
|
+
if (where.length === 0) return [d];
|
|
7980
|
+
return where.map((w) => ({ ...w, ...d }));
|
|
7981
|
+
}
|
|
7982
|
+
return Object.keys(where).length > 0 ? { ...where, ...d } : d;
|
|
7983
|
+
}
|
|
7984
|
+
function buildSoftDeletePayload(meta, deletedBy) {
|
|
7985
|
+
const payload = { deleted: true };
|
|
7986
|
+
if (meta.columns.some((c) => c.propertyName === "deletedAt")) {
|
|
7987
|
+
payload.deletedAt = /* @__PURE__ */ new Date();
|
|
7988
|
+
}
|
|
7989
|
+
if (deletedBy != null && meta.columns.some((c) => c.propertyName === "deletedBy")) {
|
|
7990
|
+
payload.deletedBy = deletedBy;
|
|
7991
|
+
}
|
|
7992
|
+
return payload;
|
|
7993
|
+
}
|
|
7948
7994
|
function makeContactErpSync(dataSource, entityMap, getCms) {
|
|
7949
7995
|
return async function syncContactRowToErp(row) {
|
|
7950
7996
|
if (!getCms) return;
|
|
@@ -7969,10 +8015,11 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7969
8015
|
async function authz(req, resource, action) {
|
|
7970
8016
|
const authError = await requireAuth(req);
|
|
7971
8017
|
if (authError) return authError;
|
|
7972
|
-
if (reqPerm) {
|
|
7973
|
-
|
|
7974
|
-
if (pe) return pe;
|
|
8018
|
+
if (!reqPerm) {
|
|
8019
|
+
return json({ error: "Forbidden", reason: "entity_rbac_required", entity: resource, action }, { status: 403 });
|
|
7975
8020
|
}
|
|
8021
|
+
const pe = await reqPerm(req, resource, action);
|
|
8022
|
+
if (pe) return pe;
|
|
7976
8023
|
return null;
|
|
7977
8024
|
}
|
|
7978
8025
|
return {
|
|
@@ -8008,7 +8055,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8008
8055
|
return json({ total: 0, page, limit, totalPages: 0, data: [] });
|
|
8009
8056
|
}
|
|
8010
8057
|
}
|
|
8011
|
-
const qb = repo2.createQueryBuilder("order").leftJoinAndSelect("order.contact", "contact").leftJoinAndSelect("order.items", "items").leftJoinAndSelect("items.product", "product").leftJoinAndSelect("product.collection", "collection").orderBy(`order.${sortField2}`, sortOrderOrders).skip(skip).take(limit);
|
|
8058
|
+
const qb = repo2.createQueryBuilder("order").leftJoinAndSelect("order.contact", "contact").leftJoinAndSelect("order.items", "items").leftJoinAndSelect("items.product", "product").leftJoinAndSelect("product.collection", "collection").andWhere("order.deleted = :orderDel", { orderDel: false }).orderBy(`order.${sortField2}`, sortOrderOrders).skip(skip).take(limit);
|
|
8012
8059
|
if (search && typeof search === "string" && search.trim()) {
|
|
8013
8060
|
const term = `%${search.trim()}%`;
|
|
8014
8061
|
qb.andWhere(
|
|
@@ -8046,7 +8093,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8046
8093
|
const dateTo = searchParams.get("dateTo")?.trim();
|
|
8047
8094
|
const methodFilter = searchParams.get("method")?.trim();
|
|
8048
8095
|
const orderNumberParam = searchParams.get("orderNumber")?.trim();
|
|
8049
|
-
const qb = repo2.createQueryBuilder("payment").leftJoinAndSelect("payment.order", "ord").leftJoinAndSelect("ord.contact", "orderContact").leftJoinAndSelect("payment.contact", "contact").orderBy(`payment.${sortField2}`, sortOrderPayments).skip(skip).take(limit);
|
|
8096
|
+
const qb = repo2.createQueryBuilder("payment").leftJoinAndSelect("payment.order", "ord").leftJoinAndSelect("ord.contact", "orderContact").leftJoinAndSelect("payment.contact", "contact").andWhere("payment.deleted = :payDel", { payDel: false }).orderBy(`payment.${sortField2}`, sortOrderPayments).skip(skip).take(limit);
|
|
8050
8097
|
if (search && typeof search === "string" && search.trim()) {
|
|
8051
8098
|
const term = `%${search.trim()}%`;
|
|
8052
8099
|
qb.andWhere(
|
|
@@ -8077,7 +8124,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8077
8124
|
const repo2 = dataSource.getRepository(entity);
|
|
8078
8125
|
const statusFilter = searchParams.get("status")?.trim();
|
|
8079
8126
|
const inventory = searchParams.get("inventory")?.trim();
|
|
8080
|
-
const productWhere = {};
|
|
8127
|
+
const productWhere = { deleted: false };
|
|
8081
8128
|
if (statusFilter) productWhere.status = statusFilter;
|
|
8082
8129
|
if (inventory === "in_stock") productWhere.quantity = (0, import_typeorm44.MoreThan)(0);
|
|
8083
8130
|
if (inventory === "out_of_stock") productWhere.quantity = 0;
|
|
@@ -8100,7 +8147,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8100
8147
|
const typeFilter2 = searchParams.get("type")?.trim();
|
|
8101
8148
|
const orderIdParam = searchParams.get("orderId")?.trim();
|
|
8102
8149
|
const includeSummary = searchParams.get("includeSummary") === "1";
|
|
8103
|
-
const qb = repo2.createQueryBuilder("contact").orderBy(`contact.${sortField2}`, sortOrderContacts).skip(skip).take(limit);
|
|
8150
|
+
const qb = repo2.createQueryBuilder("contact").andWhere("contact.deleted = :contactDel", { contactDel: false }).orderBy(`contact.${sortField2}`, sortOrderContacts).skip(skip).take(limit);
|
|
8104
8151
|
if (search && typeof search === "string" && search.trim()) {
|
|
8105
8152
|
const term = `%${search.trim()}%`;
|
|
8106
8153
|
qb.andWhere("(contact.name ILIKE :term OR contact.email ILIKE :term OR contact.phone ILIKE :term)", { term });
|
|
@@ -8141,9 +8188,9 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8141
8188
|
if (parentIdParam != null && parentIdParam !== "") {
|
|
8142
8189
|
const n = Number(parentIdParam);
|
|
8143
8190
|
if (!Number.isFinite(n)) return json({ error: "Invalid parentId" }, { status: 400 });
|
|
8144
|
-
qb.where("m.parentId = :pid", { pid: n });
|
|
8191
|
+
qb.where("m.deleted = :mediaDel AND m.parentId = :pid", { mediaDel: false, pid: n });
|
|
8145
8192
|
} else {
|
|
8146
|
-
qb.where("m.parentId IS NULL");
|
|
8193
|
+
qb.where("m.deleted = :mediaDel AND m.parentId IS NULL", { mediaDel: false });
|
|
8147
8194
|
}
|
|
8148
8195
|
if (search && typeof search === "string" && search.trim()) {
|
|
8149
8196
|
qb.andWhere("m.filename ILIKE :search", { search: `%${search.trim()}%` });
|
|
@@ -8187,6 +8234,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8187
8234
|
where = extraWhere;
|
|
8188
8235
|
}
|
|
8189
8236
|
}
|
|
8237
|
+
where = mergeDeletedFalseWhere(repo, where);
|
|
8190
8238
|
const [data, total] = await repo.findAndCount({
|
|
8191
8239
|
skip,
|
|
8192
8240
|
take: limit,
|
|
@@ -8354,15 +8402,16 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8354
8402
|
};
|
|
8355
8403
|
}
|
|
8356
8404
|
function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
8357
|
-
const { requireAuth, json, requireEntityPermission: reqPerm, getCms } = options;
|
|
8405
|
+
const { requireAuth, json, requireEntityPermission: reqPerm, getCms, getDeletedByUserId } = options;
|
|
8358
8406
|
const syncContactRowToErp = makeContactErpSync(dataSource, entityMap, getCms);
|
|
8359
8407
|
async function authz(req, resource, action) {
|
|
8360
8408
|
const authError = await requireAuth(req);
|
|
8361
8409
|
if (authError) return authError;
|
|
8362
|
-
if (reqPerm) {
|
|
8363
|
-
|
|
8364
|
-
if (pe) return pe;
|
|
8410
|
+
if (!reqPerm) {
|
|
8411
|
+
return json({ error: "Forbidden", reason: "entity_rbac_required", entity: resource, action }, { status: 403 });
|
|
8365
8412
|
}
|
|
8413
|
+
const pe = await reqPerm(req, resource, action);
|
|
8414
|
+
if (pe) return pe;
|
|
8366
8415
|
return null;
|
|
8367
8416
|
}
|
|
8368
8417
|
return {
|
|
@@ -8374,7 +8423,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8374
8423
|
const repo = dataSource.getRepository(entity);
|
|
8375
8424
|
if (resource === "orders") {
|
|
8376
8425
|
const order = await repo.findOne({
|
|
8377
|
-
where: { id: Number(id) },
|
|
8426
|
+
where: { id: Number(id), deleted: false },
|
|
8378
8427
|
relations: ["contact", "billingAddress", "shippingAddress", "items", "items.product", "items.product.collection", "payments"]
|
|
8379
8428
|
});
|
|
8380
8429
|
if (!order) return json({ message: "Not found" }, { status: 404 });
|
|
@@ -8386,7 +8435,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8386
8435
|
}
|
|
8387
8436
|
if (resource === "contacts") {
|
|
8388
8437
|
const contact = await repo.findOne({
|
|
8389
|
-
where: { id: Number(id) },
|
|
8438
|
+
where: { id: Number(id), deleted: false },
|
|
8390
8439
|
relations: ["form_submissions", "form_submissions.form", "orders", "payments", "addresses"]
|
|
8391
8440
|
});
|
|
8392
8441
|
if (!contact) return json({ message: "Not found" }, { status: 404 });
|
|
@@ -8408,7 +8457,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8408
8457
|
}
|
|
8409
8458
|
if (resource === "payments") {
|
|
8410
8459
|
const payment = await repo.findOne({
|
|
8411
|
-
where: { id: Number(id) },
|
|
8460
|
+
where: { id: Number(id), deleted: false },
|
|
8412
8461
|
relations: ["order", "order.contact", "contact"]
|
|
8413
8462
|
});
|
|
8414
8463
|
if (!payment) return json({ message: "Not found" }, { status: 404 });
|
|
@@ -8416,12 +8465,13 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8416
8465
|
}
|
|
8417
8466
|
if (resource === "blogs") {
|
|
8418
8467
|
const blog = await repo.findOne({
|
|
8419
|
-
where: { id: Number(id) },
|
|
8468
|
+
where: { id: Number(id), deleted: false },
|
|
8420
8469
|
relations: ["category", "seo", "tags"]
|
|
8421
8470
|
});
|
|
8422
8471
|
return blog ? json(blog) : json({ message: "Not found" }, { status: 404 });
|
|
8423
8472
|
}
|
|
8424
|
-
const
|
|
8473
|
+
const idWhere = entityHasSoftDelete(repo) ? { id: Number(id), deleted: false } : { id: Number(id) };
|
|
8474
|
+
const item = await repo.findOne({ where: idWhere });
|
|
8425
8475
|
return item ? json(item) : json({ message: "Not found" }, { status: 404 });
|
|
8426
8476
|
},
|
|
8427
8477
|
async PUT(req, resource, id) {
|
|
@@ -8433,7 +8483,9 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8433
8483
|
const repo = dataSource.getRepository(entity);
|
|
8434
8484
|
const numericId = Number(id);
|
|
8435
8485
|
if (resource === "blogs" && rawBody && typeof rawBody === "object" && entityMap.categories && entityMap.seos && entityMap.tags) {
|
|
8436
|
-
const existing = await repo.findOne({
|
|
8486
|
+
const existing = await repo.findOne({
|
|
8487
|
+
where: { id: numericId, deleted: false }
|
|
8488
|
+
});
|
|
8437
8489
|
if (!existing) return json({ message: "Not found" }, { status: 404 });
|
|
8438
8490
|
const updatePayload2 = pickColumnUpdates(repo, rawBody);
|
|
8439
8491
|
if ("category" in rawBody) {
|
|
@@ -8509,6 +8561,12 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8509
8561
|
});
|
|
8510
8562
|
return updated2 ? json(updated2) : json({ message: "Not found" }, { status: 404 });
|
|
8511
8563
|
}
|
|
8564
|
+
if (entityHasSoftDelete(repo)) {
|
|
8565
|
+
const cur = await repo.findOne({
|
|
8566
|
+
where: { id: numericId, deleted: false }
|
|
8567
|
+
});
|
|
8568
|
+
if (!cur) return json({ message: "Not found" }, { status: 404 });
|
|
8569
|
+
}
|
|
8512
8570
|
const updatePayload = rawBody && typeof rawBody === "object" ? pickColumnUpdates(repo, rawBody) : {};
|
|
8513
8571
|
if (resource === "media") {
|
|
8514
8572
|
const u = updatePayload;
|
|
@@ -8535,7 +8593,24 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8535
8593
|
const entity = entityMap[resource];
|
|
8536
8594
|
if (!entity) return json({ error: "Invalid resource" }, { status: 400 });
|
|
8537
8595
|
const repo = dataSource.getRepository(entity);
|
|
8538
|
-
const
|
|
8596
|
+
const numericId = Number(id);
|
|
8597
|
+
if (entityHasSoftDelete(repo)) {
|
|
8598
|
+
const existing = await repo.findOne({
|
|
8599
|
+
where: { id: numericId, deleted: false }
|
|
8600
|
+
});
|
|
8601
|
+
if (!existing) return json({ message: "Not found" }, { status: 404 });
|
|
8602
|
+
let deletedBy = null;
|
|
8603
|
+
if (getDeletedByUserId) {
|
|
8604
|
+
try {
|
|
8605
|
+
deletedBy = await getDeletedByUserId(req);
|
|
8606
|
+
} catch {
|
|
8607
|
+
deletedBy = null;
|
|
8608
|
+
}
|
|
8609
|
+
}
|
|
8610
|
+
await repo.update(numericId, buildSoftDeletePayload(repo.metadata, deletedBy));
|
|
8611
|
+
return json({ message: "Deleted successfully" }, { status: 200 });
|
|
8612
|
+
}
|
|
8613
|
+
const result = await repo.delete(numericId);
|
|
8539
8614
|
if (result.affected === 0) return json({ message: "Not found" }, { status: 404 });
|
|
8540
8615
|
return json({ message: "Deleted successfully" }, { status: 200 });
|
|
8541
8616
|
}
|
|
@@ -8963,9 +9038,10 @@ function createCmsApiHandler(config) {
|
|
|
8963
9038
|
userProfile,
|
|
8964
9039
|
settings: settingsConfig,
|
|
8965
9040
|
chat: chatConfig,
|
|
8966
|
-
requireEntityPermission:
|
|
9041
|
+
requireEntityPermission: userRequireEntityPermission,
|
|
8967
9042
|
getSessionUser
|
|
8968
9043
|
} = config;
|
|
9044
|
+
const requireEntityPermissionEffective = userRequireEntityPermission ?? (async (_req, entity, action) => config.json({ error: "Forbidden", reason: "entity_rbac_required", entity, action }, { status: 403 }));
|
|
8969
9045
|
const analytics = analyticsConfig ?? (getCms ? {
|
|
8970
9046
|
json: config.json,
|
|
8971
9047
|
requireAuth: async () => null,
|
|
@@ -9003,12 +9079,20 @@ function createCmsApiHandler(config) {
|
|
|
9003
9079
|
const crudOpts = {
|
|
9004
9080
|
requireAuth: config.requireAuth,
|
|
9005
9081
|
json: config.json,
|
|
9006
|
-
requireEntityPermission:
|
|
9007
|
-
getCms
|
|
9082
|
+
requireEntityPermission: requireEntityPermissionEffective,
|
|
9083
|
+
getCms,
|
|
9084
|
+
...getSessionUser ? {
|
|
9085
|
+
getDeletedByUserId: async () => {
|
|
9086
|
+
const u = await getSessionUser();
|
|
9087
|
+
if (!u?.id) return null;
|
|
9088
|
+
const n = Number(u.id);
|
|
9089
|
+
return Number.isFinite(n) ? n : null;
|
|
9090
|
+
}
|
|
9091
|
+
} : {}
|
|
9008
9092
|
};
|
|
9009
9093
|
const crud = createCrudHandler(dataSource, entityMap, crudOpts);
|
|
9010
9094
|
const crudById = createCrudByIdHandler(dataSource, entityMap, crudOpts);
|
|
9011
|
-
const mergePerm = (c) => !c ? void 0 :
|
|
9095
|
+
const mergePerm = (c) => !c ? void 0 : { ...c, requireEntityPermission: requireEntityPermissionEffective };
|
|
9012
9096
|
const adminRoles = getSessionUser && createAdminRolesHandlers({
|
|
9013
9097
|
dataSource,
|
|
9014
9098
|
entityMap,
|
|
@@ -9024,12 +9108,7 @@ function createCmsApiHandler(config) {
|
|
|
9024
9108
|
json: config.json,
|
|
9025
9109
|
requireAuth: config.requireAuth
|
|
9026
9110
|
}
|
|
9027
|
-
)
|
|
9028
|
-
dataSource,
|
|
9029
|
-
entityMap,
|
|
9030
|
-
json: config.json,
|
|
9031
|
-
requireAuth: config.requireAuth
|
|
9032
|
-
};
|
|
9111
|
+
);
|
|
9033
9112
|
const ecommerceAnalyticsGet = createEcommerceAnalyticsHandler(ecommerceAnalyticsResolved);
|
|
9034
9113
|
const analyticsHandlers = analytics ? createAnalyticsHandlers(analytics) : null;
|
|
9035
9114
|
const uploadMerged = upload ? {
|
|
@@ -9048,7 +9127,11 @@ function createCmsApiHandler(config) {
|
|
|
9048
9127
|
const usersApiMerged = usersApi && getCms ? {
|
|
9049
9128
|
...usersApi,
|
|
9050
9129
|
getCms: usersApi.getCms ?? getCms,
|
|
9051
|
-
getCompanyDetails: usersApi.getCompanyDetails ?? config.getCompanyDetails
|
|
9130
|
+
getCompanyDetails: usersApi.getCompanyDetails ?? config.getCompanyDetails,
|
|
9131
|
+
...getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}
|
|
9132
|
+
} : usersApi ? {
|
|
9133
|
+
...usersApi,
|
|
9134
|
+
...getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}
|
|
9052
9135
|
} : usersApi;
|
|
9053
9136
|
const usersHandlers = usersApiMerged ? createUsersApiHandlers(mergePerm(usersApiMerged) ?? usersApiMerged) : null;
|
|
9054
9137
|
const avatarPost = userAvatar ? createUserAvatarHandler(userAvatar) : null;
|
|
@@ -9059,7 +9142,7 @@ function createCmsApiHandler(config) {
|
|
|
9059
9142
|
entityMap,
|
|
9060
9143
|
json: config.json,
|
|
9061
9144
|
requireAuth: config.requireAuth,
|
|
9062
|
-
requireEntityPermission:
|
|
9145
|
+
requireEntityPermission: requireEntityPermissionEffective
|
|
9063
9146
|
});
|
|
9064
9147
|
const chatHandlers = chatConfig ? createChatHandlers(chatConfig) : null;
|
|
9065
9148
|
function resolveResource(segment) {
|
|
@@ -9068,12 +9151,10 @@ function createCmsApiHandler(config) {
|
|
|
9068
9151
|
}
|
|
9069
9152
|
return {
|
|
9070
9153
|
async handle(method, path, req) {
|
|
9071
|
-
const perm = reqEntityPerm;
|
|
9072
9154
|
async function analyticsGate() {
|
|
9073
9155
|
const a = await config.requireAuth(req);
|
|
9074
9156
|
if (a) return a;
|
|
9075
|
-
|
|
9076
|
-
return null;
|
|
9157
|
+
return requireEntityPermissionEffective(req, "analytics", "read");
|
|
9077
9158
|
}
|
|
9078
9159
|
if (path[0] === "admin" && path[1] === "roles") {
|
|
9079
9160
|
if (!adminRoles) return config.json({ error: "Not found" }, { status: 404 });
|
|
@@ -9157,19 +9238,17 @@ function createCmsApiHandler(config) {
|
|
|
9157
9238
|
const group = path[1];
|
|
9158
9239
|
const isPublic = settingsConfig?.publicGetGroups?.includes(group);
|
|
9159
9240
|
if (method === "GET") {
|
|
9160
|
-
if (!isPublic
|
|
9241
|
+
if (!isPublic) {
|
|
9161
9242
|
const a = await config.requireAuth(req);
|
|
9162
9243
|
if (a) return a;
|
|
9163
|
-
const pe = await
|
|
9244
|
+
const pe = await requireEntityPermissionEffective(req, "settings", "read");
|
|
9164
9245
|
if (pe) return pe;
|
|
9165
9246
|
}
|
|
9166
9247
|
return settingsHandlers.GET(req, group);
|
|
9167
9248
|
}
|
|
9168
9249
|
if (method === "PUT") {
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
if (pe) return pe;
|
|
9172
|
-
}
|
|
9250
|
+
const pe = await requireEntityPermissionEffective(req, "settings", "update");
|
|
9251
|
+
if (pe) return pe;
|
|
9173
9252
|
return settingsHandlers.PUT(req, group);
|
|
9174
9253
|
}
|
|
9175
9254
|
}
|
|
@@ -9185,10 +9264,8 @@ function createCmsApiHandler(config) {
|
|
|
9185
9264
|
if (path[0] === "orders" && path.length === 3 && path[2] === "invoice" && method === "GET" && getCms) {
|
|
9186
9265
|
const a = await config.requireAuth(req);
|
|
9187
9266
|
if (a) return a;
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
if (pe) return pe;
|
|
9191
|
-
}
|
|
9267
|
+
const pe = await requireEntityPermissionEffective(req, "orders", "read");
|
|
9268
|
+
if (pe) return pe;
|
|
9192
9269
|
const cms = await getCms();
|
|
9193
9270
|
const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await Promise.resolve().then(() => (init_erp_order_invoice(), erp_order_invoice_exports));
|
|
9194
9271
|
const oid = Number(path[1]);
|
|
@@ -9198,10 +9275,8 @@ function createCmsApiHandler(config) {
|
|
|
9198
9275
|
if (path[0] === "orders" && path.length === 3 && path[2] === "repost-erp" && getCms) {
|
|
9199
9276
|
const a = await config.requireAuth(req);
|
|
9200
9277
|
if (a) return a;
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
if (pe) return pe;
|
|
9204
|
-
}
|
|
9278
|
+
const pe = await requireEntityPermissionEffective(req, "orders", method === "GET" ? "read" : "update");
|
|
9279
|
+
if (pe) return pe;
|
|
9205
9280
|
const oid = Number(path[1]);
|
|
9206
9281
|
if (!Number.isFinite(oid)) return config.json({ error: "Invalid id" }, { status: 400 });
|
|
9207
9282
|
const cms = await getCms();
|
|
@@ -10658,6 +10733,9 @@ var DEFAULT_ADMIN_NAV = [
|
|
|
10658
10733
|
{ href: "/admin/submissions", label: "Submissions" },
|
|
10659
10734
|
{ href: "/admin/pages", label: "Pages" }
|
|
10660
10735
|
];
|
|
10736
|
+
|
|
10737
|
+
// src/index.ts
|
|
10738
|
+
console.log("\u{1F525} USING LOCAL CMS CORE (index.ts loaded) \u{1F525}");
|
|
10661
10739
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10662
10740
|
0 && (module.exports = {
|
|
10663
10741
|
ADMIN_GROUP_NAME,
|