@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.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CompanyDetails, T as TemplateContext, E as EmailTemplateResult, a as EmailTemplateName, O as OrderPlacedLineItem, S as StorageService, b as EntityMap$2 } from './index-
|
|
2
|
-
export { A as AnalyticsHandlerConfig, c as AuthHandlersConfig, B as BlogBySlugConfig, d as ChangePasswordConfig, e as CmsApiHandlerConfig, f as CmsGetter, g as CrudHandlerOptions, D as DashboardStatsConfig, h as EcommerceAnalyticsConfig, F as ForgotPasswordConfig, i as FormBySlugConfig, G as GetPublicSettingsGroupConfig, j as GetPublicSettingsGroupDataSource, I as InviteAcceptConfig, k as SetPasswordConfig, l as SettingsApiConfig, m as SocialLinkItem, n as StorefrontApiConfig, o as StorefrontOtpFlags, U as UploadHandlerConfig, p as UserAuthApiConfig, q as UserAvatarConfig, r as UserProfileConfig, s as UsersApiConfig, t as createAnalyticsHandlers, u as createBlogBySlugHandler, v as createChangePasswordHandler, w as createCmsApiHandler, x as createCrudByIdHandler, y as createCrudHandler, z as createDashboardStatsHandler, H as createEcommerceAnalyticsHandler, J as createForgotPasswordHandler, K as createFormBySlugHandler, L as createInviteAcceptHandler, M as createMediaZipExtractHandler, N as createSetPasswordHandler, P as createSettingsApiHandlers, Q as createStorefrontApiHandler, R as createUploadHandler, V as createUserAuthApiRouter, W as createUserAvatarHandler, X as createUserProfileHandler, Y as createUsersApiHandlers, Z as getCompanyDetailsFromSettings, _ as getPublicSettingsGroup, $ as mergeEmailLayoutCompanyDetails } from './index-
|
|
1
|
+
import { C as CompanyDetails, T as TemplateContext, E as EmailTemplateResult, a as EmailTemplateName, O as OrderPlacedLineItem, S as StorageService, b as EntityMap$2 } from './index-D2C1O9b4.cjs';
|
|
2
|
+
export { A as AnalyticsHandlerConfig, c as AuthHandlersConfig, B as BlogBySlugConfig, d as ChangePasswordConfig, e as CmsApiHandlerConfig, f as CmsGetter, g as CrudHandlerOptions, D as DashboardStatsConfig, h as EcommerceAnalyticsConfig, F as ForgotPasswordConfig, i as FormBySlugConfig, G as GetPublicSettingsGroupConfig, j as GetPublicSettingsGroupDataSource, I as InviteAcceptConfig, k as SetPasswordConfig, l as SettingsApiConfig, m as SocialLinkItem, n as StorefrontApiConfig, o as StorefrontOtpFlags, U as UploadHandlerConfig, p as UserAuthApiConfig, q as UserAvatarConfig, r as UserProfileConfig, s as UsersApiConfig, t as createAnalyticsHandlers, u as createBlogBySlugHandler, v as createChangePasswordHandler, w as createCmsApiHandler, x as createCrudByIdHandler, y as createCrudHandler, z as createDashboardStatsHandler, H as createEcommerceAnalyticsHandler, J as createForgotPasswordHandler, K as createFormBySlugHandler, L as createInviteAcceptHandler, M as createMediaZipExtractHandler, N as createSetPasswordHandler, P as createSettingsApiHandlers, Q as createStorefrontApiHandler, R as createUploadHandler, V as createUserAuthApiRouter, W as createUserAvatarHandler, X as createUserProfileHandler, Y as createUsersApiHandlers, Z as getCompanyDetailsFromSettings, _ as getPublicSettingsGroup, $ as mergeEmailLayoutCompanyDetails } from './index-D2C1O9b4.cjs';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
import * as typeorm from 'typeorm';
|
|
5
5
|
import { DataSource, EntityTarget, ObjectLiteral } from 'typeorm';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CompanyDetails, T as TemplateContext, E as EmailTemplateResult, a as EmailTemplateName, O as OrderPlacedLineItem, S as StorageService, b as EntityMap$2 } from './index-
|
|
2
|
-
export { A as AnalyticsHandlerConfig, c as AuthHandlersConfig, B as BlogBySlugConfig, d as ChangePasswordConfig, e as CmsApiHandlerConfig, f as CmsGetter, g as CrudHandlerOptions, D as DashboardStatsConfig, h as EcommerceAnalyticsConfig, F as ForgotPasswordConfig, i as FormBySlugConfig, G as GetPublicSettingsGroupConfig, j as GetPublicSettingsGroupDataSource, I as InviteAcceptConfig, k as SetPasswordConfig, l as SettingsApiConfig, m as SocialLinkItem, n as StorefrontApiConfig, o as StorefrontOtpFlags, U as UploadHandlerConfig, p as UserAuthApiConfig, q as UserAvatarConfig, r as UserProfileConfig, s as UsersApiConfig, t as createAnalyticsHandlers, u as createBlogBySlugHandler, v as createChangePasswordHandler, w as createCmsApiHandler, x as createCrudByIdHandler, y as createCrudHandler, z as createDashboardStatsHandler, H as createEcommerceAnalyticsHandler, J as createForgotPasswordHandler, K as createFormBySlugHandler, L as createInviteAcceptHandler, M as createMediaZipExtractHandler, N as createSetPasswordHandler, P as createSettingsApiHandlers, Q as createStorefrontApiHandler, R as createUploadHandler, V as createUserAuthApiRouter, W as createUserAvatarHandler, X as createUserProfileHandler, Y as createUsersApiHandlers, Z as getCompanyDetailsFromSettings, _ as getPublicSettingsGroup, $ as mergeEmailLayoutCompanyDetails } from './index-
|
|
1
|
+
import { C as CompanyDetails, T as TemplateContext, E as EmailTemplateResult, a as EmailTemplateName, O as OrderPlacedLineItem, S as StorageService, b as EntityMap$2 } from './index-GMn7-9PX.js';
|
|
2
|
+
export { A as AnalyticsHandlerConfig, c as AuthHandlersConfig, B as BlogBySlugConfig, d as ChangePasswordConfig, e as CmsApiHandlerConfig, f as CmsGetter, g as CrudHandlerOptions, D as DashboardStatsConfig, h as EcommerceAnalyticsConfig, F as ForgotPasswordConfig, i as FormBySlugConfig, G as GetPublicSettingsGroupConfig, j as GetPublicSettingsGroupDataSource, I as InviteAcceptConfig, k as SetPasswordConfig, l as SettingsApiConfig, m as SocialLinkItem, n as StorefrontApiConfig, o as StorefrontOtpFlags, U as UploadHandlerConfig, p as UserAuthApiConfig, q as UserAvatarConfig, r as UserProfileConfig, s as UsersApiConfig, t as createAnalyticsHandlers, u as createBlogBySlugHandler, v as createChangePasswordHandler, w as createCmsApiHandler, x as createCrudByIdHandler, y as createCrudHandler, z as createDashboardStatsHandler, H as createEcommerceAnalyticsHandler, J as createForgotPasswordHandler, K as createFormBySlugHandler, L as createInviteAcceptHandler, M as createMediaZipExtractHandler, N as createSetPasswordHandler, P as createSettingsApiHandlers, Q as createStorefrontApiHandler, R as createUploadHandler, V as createUserAuthApiRouter, W as createUserAvatarHandler, X as createUserProfileHandler, Y as createUsersApiHandlers, Z as getCompanyDetailsFromSettings, _ as getPublicSettingsGroup, $ as mergeEmailLayoutCompanyDetails } from './index-GMn7-9PX.js';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
import * as typeorm from 'typeorm';
|
|
5
5
|
import { DataSource, EntityTarget, ObjectLiteral } from 'typeorm';
|
package/dist/index.js
CHANGED
|
@@ -4371,7 +4371,7 @@ function createFormSubmissionHandler(config) {
|
|
|
4371
4371
|
};
|
|
4372
4372
|
}
|
|
4373
4373
|
function createUsersApiHandlers(config) {
|
|
4374
|
-
const { dataSource, entityMap, json, requireAuth, requireEntityPermission, baseUrl, getCms, getCompanyDetails } = config;
|
|
4374
|
+
const { dataSource, entityMap, json, requireAuth, requireEntityPermission, baseUrl, getCms, getCompanyDetails, getSessionUser } = config;
|
|
4375
4375
|
async function trySendInviteEmail(toEmail, inviteLink, inviteeName) {
|
|
4376
4376
|
if (!getCms) return;
|
|
4377
4377
|
try {
|
|
@@ -4407,7 +4407,10 @@ function createUsersApiHandlers(config) {
|
|
|
4407
4407
|
const sortField = url.searchParams.get("sortField") || "createdAt";
|
|
4408
4408
|
const sortOrder = url.searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
|
|
4409
4409
|
const search = url.searchParams.get("search");
|
|
4410
|
-
const where = search ? [
|
|
4410
|
+
const where = search ? [
|
|
4411
|
+
{ name: ILike(`%${search}%`), deleted: false },
|
|
4412
|
+
{ email: ILike(`%${search}%`), deleted: false }
|
|
4413
|
+
] : { deleted: false };
|
|
4411
4414
|
const [data, total] = await userRepo().findAndCount({
|
|
4412
4415
|
skip,
|
|
4413
4416
|
take: limit,
|
|
@@ -4472,7 +4475,7 @@ function createUsersApiHandlers(config) {
|
|
|
4472
4475
|
}
|
|
4473
4476
|
try {
|
|
4474
4477
|
const user = await userRepo().findOne({
|
|
4475
|
-
where: { id: parseInt(id, 10) },
|
|
4478
|
+
where: { id: parseInt(id, 10), deleted: false },
|
|
4476
4479
|
relations: ["group"],
|
|
4477
4480
|
select: ["id", "name", "email", "blocked", "createdAt", "updatedAt", "groupId"]
|
|
4478
4481
|
});
|
|
@@ -4490,11 +4493,14 @@ function createUsersApiHandlers(config) {
|
|
|
4490
4493
|
if (pe) return pe;
|
|
4491
4494
|
}
|
|
4492
4495
|
try {
|
|
4496
|
+
const uid = parseInt(id, 10);
|
|
4497
|
+
const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });
|
|
4498
|
+
if (!existing) return json({ error: "Not found" }, { status: 404 });
|
|
4493
4499
|
const body = await req.json();
|
|
4494
4500
|
const { password: _p, ...safe } = body;
|
|
4495
|
-
await userRepo().update(
|
|
4501
|
+
await userRepo().update(uid, safe);
|
|
4496
4502
|
const updated = await userRepo().findOne({
|
|
4497
|
-
where: { id:
|
|
4503
|
+
where: { id: uid, deleted: false },
|
|
4498
4504
|
relations: ["group"],
|
|
4499
4505
|
select: ["id", "name", "email", "blocked", "createdAt", "updatedAt", "groupId"]
|
|
4500
4506
|
});
|
|
@@ -4511,8 +4517,23 @@ function createUsersApiHandlers(config) {
|
|
|
4511
4517
|
if (pe) return pe;
|
|
4512
4518
|
}
|
|
4513
4519
|
try {
|
|
4514
|
-
const
|
|
4515
|
-
|
|
4520
|
+
const uid = parseInt(id, 10);
|
|
4521
|
+
const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });
|
|
4522
|
+
if (!existing) return json({ error: "User not found" }, { status: 404 });
|
|
4523
|
+
let deletedBy = null;
|
|
4524
|
+
if (getSessionUser) {
|
|
4525
|
+
try {
|
|
4526
|
+
const u = await getSessionUser();
|
|
4527
|
+
if (u?.id) {
|
|
4528
|
+
const n = Number(u.id);
|
|
4529
|
+
if (Number.isFinite(n)) deletedBy = n;
|
|
4530
|
+
}
|
|
4531
|
+
} catch {
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
const payload = { deleted: true, deletedAt: /* @__PURE__ */ new Date() };
|
|
4535
|
+
if (deletedBy != null) payload.deletedBy = deletedBy;
|
|
4536
|
+
await userRepo().update(uid, payload);
|
|
4516
4537
|
return json({ message: "User deleted successfully" });
|
|
4517
4538
|
} catch {
|
|
4518
4539
|
return json({ error: "Server Error" }, { status: 500 });
|
|
@@ -4526,7 +4547,10 @@ function createUsersApiHandlers(config) {
|
|
|
4526
4547
|
if (pe) return pe;
|
|
4527
4548
|
}
|
|
4528
4549
|
try {
|
|
4529
|
-
const user = await userRepo().findOne({
|
|
4550
|
+
const user = await userRepo().findOne({
|
|
4551
|
+
where: { id: parseInt(id, 10), deleted: false },
|
|
4552
|
+
select: ["email", "name"]
|
|
4553
|
+
});
|
|
4530
4554
|
if (!user) return json({ error: "User not found" }, { status: 404 });
|
|
4531
4555
|
const emailToken = Buffer.from(user.email).toString("base64");
|
|
4532
4556
|
const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;
|
|
@@ -7781,6 +7805,28 @@ function buildSearchWhereClause(repo, search) {
|
|
|
7781
7805
|
if (ors.length === 0) return {};
|
|
7782
7806
|
return ors.length === 1 ? ors[0] : ors;
|
|
7783
7807
|
}
|
|
7808
|
+
function entityHasSoftDelete(repo) {
|
|
7809
|
+
return repo.metadata.columns.some((c) => c.propertyName === "deleted");
|
|
7810
|
+
}
|
|
7811
|
+
function mergeDeletedFalseWhere(repo, where) {
|
|
7812
|
+
if (!entityHasSoftDelete(repo)) return where;
|
|
7813
|
+
const d = { deleted: false };
|
|
7814
|
+
if (Array.isArray(where)) {
|
|
7815
|
+
if (where.length === 0) return [d];
|
|
7816
|
+
return where.map((w) => ({ ...w, ...d }));
|
|
7817
|
+
}
|
|
7818
|
+
return Object.keys(where).length > 0 ? { ...where, ...d } : d;
|
|
7819
|
+
}
|
|
7820
|
+
function buildSoftDeletePayload(meta, deletedBy) {
|
|
7821
|
+
const payload = { deleted: true };
|
|
7822
|
+
if (meta.columns.some((c) => c.propertyName === "deletedAt")) {
|
|
7823
|
+
payload.deletedAt = /* @__PURE__ */ new Date();
|
|
7824
|
+
}
|
|
7825
|
+
if (deletedBy != null && meta.columns.some((c) => c.propertyName === "deletedBy")) {
|
|
7826
|
+
payload.deletedBy = deletedBy;
|
|
7827
|
+
}
|
|
7828
|
+
return payload;
|
|
7829
|
+
}
|
|
7784
7830
|
function makeContactErpSync(dataSource, entityMap, getCms) {
|
|
7785
7831
|
return async function syncContactRowToErp(row) {
|
|
7786
7832
|
if (!getCms) return;
|
|
@@ -7805,10 +7851,11 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7805
7851
|
async function authz(req, resource, action) {
|
|
7806
7852
|
const authError = await requireAuth(req);
|
|
7807
7853
|
if (authError) return authError;
|
|
7808
|
-
if (reqPerm) {
|
|
7809
|
-
|
|
7810
|
-
if (pe) return pe;
|
|
7854
|
+
if (!reqPerm) {
|
|
7855
|
+
return json({ error: "Forbidden", reason: "entity_rbac_required", entity: resource, action }, { status: 403 });
|
|
7811
7856
|
}
|
|
7857
|
+
const pe = await reqPerm(req, resource, action);
|
|
7858
|
+
if (pe) return pe;
|
|
7812
7859
|
return null;
|
|
7813
7860
|
}
|
|
7814
7861
|
return {
|
|
@@ -7844,7 +7891,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7844
7891
|
return json({ total: 0, page, limit, totalPages: 0, data: [] });
|
|
7845
7892
|
}
|
|
7846
7893
|
}
|
|
7847
|
-
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);
|
|
7894
|
+
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);
|
|
7848
7895
|
if (search && typeof search === "string" && search.trim()) {
|
|
7849
7896
|
const term = `%${search.trim()}%`;
|
|
7850
7897
|
qb.andWhere(
|
|
@@ -7882,7 +7929,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7882
7929
|
const dateTo = searchParams.get("dateTo")?.trim();
|
|
7883
7930
|
const methodFilter = searchParams.get("method")?.trim();
|
|
7884
7931
|
const orderNumberParam = searchParams.get("orderNumber")?.trim();
|
|
7885
|
-
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);
|
|
7932
|
+
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);
|
|
7886
7933
|
if (search && typeof search === "string" && search.trim()) {
|
|
7887
7934
|
const term = `%${search.trim()}%`;
|
|
7888
7935
|
qb.andWhere(
|
|
@@ -7913,7 +7960,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7913
7960
|
const repo2 = dataSource.getRepository(entity);
|
|
7914
7961
|
const statusFilter = searchParams.get("status")?.trim();
|
|
7915
7962
|
const inventory = searchParams.get("inventory")?.trim();
|
|
7916
|
-
const productWhere = {};
|
|
7963
|
+
const productWhere = { deleted: false };
|
|
7917
7964
|
if (statusFilter) productWhere.status = statusFilter;
|
|
7918
7965
|
if (inventory === "in_stock") productWhere.quantity = MoreThan2(0);
|
|
7919
7966
|
if (inventory === "out_of_stock") productWhere.quantity = 0;
|
|
@@ -7936,7 +7983,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7936
7983
|
const typeFilter2 = searchParams.get("type")?.trim();
|
|
7937
7984
|
const orderIdParam = searchParams.get("orderId")?.trim();
|
|
7938
7985
|
const includeSummary = searchParams.get("includeSummary") === "1";
|
|
7939
|
-
const qb = repo2.createQueryBuilder("contact").orderBy(`contact.${sortField2}`, sortOrderContacts).skip(skip).take(limit);
|
|
7986
|
+
const qb = repo2.createQueryBuilder("contact").andWhere("contact.deleted = :contactDel", { contactDel: false }).orderBy(`contact.${sortField2}`, sortOrderContacts).skip(skip).take(limit);
|
|
7940
7987
|
if (search && typeof search === "string" && search.trim()) {
|
|
7941
7988
|
const term = `%${search.trim()}%`;
|
|
7942
7989
|
qb.andWhere("(contact.name ILIKE :term OR contact.email ILIKE :term OR contact.phone ILIKE :term)", { term });
|
|
@@ -7977,9 +8024,9 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
7977
8024
|
if (parentIdParam != null && parentIdParam !== "") {
|
|
7978
8025
|
const n = Number(parentIdParam);
|
|
7979
8026
|
if (!Number.isFinite(n)) return json({ error: "Invalid parentId" }, { status: 400 });
|
|
7980
|
-
qb.where("m.parentId = :pid", { pid: n });
|
|
8027
|
+
qb.where("m.deleted = :mediaDel AND m.parentId = :pid", { mediaDel: false, pid: n });
|
|
7981
8028
|
} else {
|
|
7982
|
-
qb.where("m.parentId IS NULL");
|
|
8029
|
+
qb.where("m.deleted = :mediaDel AND m.parentId IS NULL", { mediaDel: false });
|
|
7983
8030
|
}
|
|
7984
8031
|
if (search && typeof search === "string" && search.trim()) {
|
|
7985
8032
|
qb.andWhere("m.filename ILIKE :search", { search: `%${search.trim()}%` });
|
|
@@ -8023,6 +8070,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8023
8070
|
where = extraWhere;
|
|
8024
8071
|
}
|
|
8025
8072
|
}
|
|
8073
|
+
where = mergeDeletedFalseWhere(repo, where);
|
|
8026
8074
|
const [data, total] = await repo.findAndCount({
|
|
8027
8075
|
skip,
|
|
8028
8076
|
take: limit,
|
|
@@ -8190,15 +8238,16 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
8190
8238
|
};
|
|
8191
8239
|
}
|
|
8192
8240
|
function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
8193
|
-
const { requireAuth, json, requireEntityPermission: reqPerm, getCms } = options;
|
|
8241
|
+
const { requireAuth, json, requireEntityPermission: reqPerm, getCms, getDeletedByUserId } = options;
|
|
8194
8242
|
const syncContactRowToErp = makeContactErpSync(dataSource, entityMap, getCms);
|
|
8195
8243
|
async function authz(req, resource, action) {
|
|
8196
8244
|
const authError = await requireAuth(req);
|
|
8197
8245
|
if (authError) return authError;
|
|
8198
|
-
if (reqPerm) {
|
|
8199
|
-
|
|
8200
|
-
if (pe) return pe;
|
|
8246
|
+
if (!reqPerm) {
|
|
8247
|
+
return json({ error: "Forbidden", reason: "entity_rbac_required", entity: resource, action }, { status: 403 });
|
|
8201
8248
|
}
|
|
8249
|
+
const pe = await reqPerm(req, resource, action);
|
|
8250
|
+
if (pe) return pe;
|
|
8202
8251
|
return null;
|
|
8203
8252
|
}
|
|
8204
8253
|
return {
|
|
@@ -8210,7 +8259,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8210
8259
|
const repo = dataSource.getRepository(entity);
|
|
8211
8260
|
if (resource === "orders") {
|
|
8212
8261
|
const order = await repo.findOne({
|
|
8213
|
-
where: { id: Number(id) },
|
|
8262
|
+
where: { id: Number(id), deleted: false },
|
|
8214
8263
|
relations: ["contact", "billingAddress", "shippingAddress", "items", "items.product", "items.product.collection", "payments"]
|
|
8215
8264
|
});
|
|
8216
8265
|
if (!order) return json({ message: "Not found" }, { status: 404 });
|
|
@@ -8222,7 +8271,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8222
8271
|
}
|
|
8223
8272
|
if (resource === "contacts") {
|
|
8224
8273
|
const contact = await repo.findOne({
|
|
8225
|
-
where: { id: Number(id) },
|
|
8274
|
+
where: { id: Number(id), deleted: false },
|
|
8226
8275
|
relations: ["form_submissions", "form_submissions.form", "orders", "payments", "addresses"]
|
|
8227
8276
|
});
|
|
8228
8277
|
if (!contact) return json({ message: "Not found" }, { status: 404 });
|
|
@@ -8244,7 +8293,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8244
8293
|
}
|
|
8245
8294
|
if (resource === "payments") {
|
|
8246
8295
|
const payment = await repo.findOne({
|
|
8247
|
-
where: { id: Number(id) },
|
|
8296
|
+
where: { id: Number(id), deleted: false },
|
|
8248
8297
|
relations: ["order", "order.contact", "contact"]
|
|
8249
8298
|
});
|
|
8250
8299
|
if (!payment) return json({ message: "Not found" }, { status: 404 });
|
|
@@ -8252,12 +8301,13 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8252
8301
|
}
|
|
8253
8302
|
if (resource === "blogs") {
|
|
8254
8303
|
const blog = await repo.findOne({
|
|
8255
|
-
where: { id: Number(id) },
|
|
8304
|
+
where: { id: Number(id), deleted: false },
|
|
8256
8305
|
relations: ["category", "seo", "tags"]
|
|
8257
8306
|
});
|
|
8258
8307
|
return blog ? json(blog) : json({ message: "Not found" }, { status: 404 });
|
|
8259
8308
|
}
|
|
8260
|
-
const
|
|
8309
|
+
const idWhere = entityHasSoftDelete(repo) ? { id: Number(id), deleted: false } : { id: Number(id) };
|
|
8310
|
+
const item = await repo.findOne({ where: idWhere });
|
|
8261
8311
|
return item ? json(item) : json({ message: "Not found" }, { status: 404 });
|
|
8262
8312
|
},
|
|
8263
8313
|
async PUT(req, resource, id) {
|
|
@@ -8269,7 +8319,9 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8269
8319
|
const repo = dataSource.getRepository(entity);
|
|
8270
8320
|
const numericId = Number(id);
|
|
8271
8321
|
if (resource === "blogs" && rawBody && typeof rawBody === "object" && entityMap.categories && entityMap.seos && entityMap.tags) {
|
|
8272
|
-
const existing = await repo.findOne({
|
|
8322
|
+
const existing = await repo.findOne({
|
|
8323
|
+
where: { id: numericId, deleted: false }
|
|
8324
|
+
});
|
|
8273
8325
|
if (!existing) return json({ message: "Not found" }, { status: 404 });
|
|
8274
8326
|
const updatePayload2 = pickColumnUpdates(repo, rawBody);
|
|
8275
8327
|
if ("category" in rawBody) {
|
|
@@ -8345,6 +8397,12 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8345
8397
|
});
|
|
8346
8398
|
return updated2 ? json(updated2) : json({ message: "Not found" }, { status: 404 });
|
|
8347
8399
|
}
|
|
8400
|
+
if (entityHasSoftDelete(repo)) {
|
|
8401
|
+
const cur = await repo.findOne({
|
|
8402
|
+
where: { id: numericId, deleted: false }
|
|
8403
|
+
});
|
|
8404
|
+
if (!cur) return json({ message: "Not found" }, { status: 404 });
|
|
8405
|
+
}
|
|
8348
8406
|
const updatePayload = rawBody && typeof rawBody === "object" ? pickColumnUpdates(repo, rawBody) : {};
|
|
8349
8407
|
if (resource === "media") {
|
|
8350
8408
|
const u = updatePayload;
|
|
@@ -8371,7 +8429,24 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
8371
8429
|
const entity = entityMap[resource];
|
|
8372
8430
|
if (!entity) return json({ error: "Invalid resource" }, { status: 400 });
|
|
8373
8431
|
const repo = dataSource.getRepository(entity);
|
|
8374
|
-
const
|
|
8432
|
+
const numericId = Number(id);
|
|
8433
|
+
if (entityHasSoftDelete(repo)) {
|
|
8434
|
+
const existing = await repo.findOne({
|
|
8435
|
+
where: { id: numericId, deleted: false }
|
|
8436
|
+
});
|
|
8437
|
+
if (!existing) return json({ message: "Not found" }, { status: 404 });
|
|
8438
|
+
let deletedBy = null;
|
|
8439
|
+
if (getDeletedByUserId) {
|
|
8440
|
+
try {
|
|
8441
|
+
deletedBy = await getDeletedByUserId(req);
|
|
8442
|
+
} catch {
|
|
8443
|
+
deletedBy = null;
|
|
8444
|
+
}
|
|
8445
|
+
}
|
|
8446
|
+
await repo.update(numericId, buildSoftDeletePayload(repo.metadata, deletedBy));
|
|
8447
|
+
return json({ message: "Deleted successfully" }, { status: 200 });
|
|
8448
|
+
}
|
|
8449
|
+
const result = await repo.delete(numericId);
|
|
8375
8450
|
if (result.affected === 0) return json({ message: "Not found" }, { status: 404 });
|
|
8376
8451
|
return json({ message: "Deleted successfully" }, { status: 200 });
|
|
8377
8452
|
}
|
|
@@ -8799,9 +8874,10 @@ function createCmsApiHandler(config) {
|
|
|
8799
8874
|
userProfile,
|
|
8800
8875
|
settings: settingsConfig,
|
|
8801
8876
|
chat: chatConfig,
|
|
8802
|
-
requireEntityPermission:
|
|
8877
|
+
requireEntityPermission: userRequireEntityPermission,
|
|
8803
8878
|
getSessionUser
|
|
8804
8879
|
} = config;
|
|
8880
|
+
const requireEntityPermissionEffective = userRequireEntityPermission ?? (async (_req, entity, action) => config.json({ error: "Forbidden", reason: "entity_rbac_required", entity, action }, { status: 403 }));
|
|
8805
8881
|
const analytics = analyticsConfig ?? (getCms ? {
|
|
8806
8882
|
json: config.json,
|
|
8807
8883
|
requireAuth: async () => null,
|
|
@@ -8839,12 +8915,20 @@ function createCmsApiHandler(config) {
|
|
|
8839
8915
|
const crudOpts = {
|
|
8840
8916
|
requireAuth: config.requireAuth,
|
|
8841
8917
|
json: config.json,
|
|
8842
|
-
requireEntityPermission:
|
|
8843
|
-
getCms
|
|
8918
|
+
requireEntityPermission: requireEntityPermissionEffective,
|
|
8919
|
+
getCms,
|
|
8920
|
+
...getSessionUser ? {
|
|
8921
|
+
getDeletedByUserId: async () => {
|
|
8922
|
+
const u = await getSessionUser();
|
|
8923
|
+
if (!u?.id) return null;
|
|
8924
|
+
const n = Number(u.id);
|
|
8925
|
+
return Number.isFinite(n) ? n : null;
|
|
8926
|
+
}
|
|
8927
|
+
} : {}
|
|
8844
8928
|
};
|
|
8845
8929
|
const crud = createCrudHandler(dataSource, entityMap, crudOpts);
|
|
8846
8930
|
const crudById = createCrudByIdHandler(dataSource, entityMap, crudOpts);
|
|
8847
|
-
const mergePerm = (c) => !c ? void 0 :
|
|
8931
|
+
const mergePerm = (c) => !c ? void 0 : { ...c, requireEntityPermission: requireEntityPermissionEffective };
|
|
8848
8932
|
const adminRoles = getSessionUser && createAdminRolesHandlers({
|
|
8849
8933
|
dataSource,
|
|
8850
8934
|
entityMap,
|
|
@@ -8860,12 +8944,7 @@ function createCmsApiHandler(config) {
|
|
|
8860
8944
|
json: config.json,
|
|
8861
8945
|
requireAuth: config.requireAuth
|
|
8862
8946
|
}
|
|
8863
|
-
)
|
|
8864
|
-
dataSource,
|
|
8865
|
-
entityMap,
|
|
8866
|
-
json: config.json,
|
|
8867
|
-
requireAuth: config.requireAuth
|
|
8868
|
-
};
|
|
8947
|
+
);
|
|
8869
8948
|
const ecommerceAnalyticsGet = createEcommerceAnalyticsHandler(ecommerceAnalyticsResolved);
|
|
8870
8949
|
const analyticsHandlers = analytics ? createAnalyticsHandlers(analytics) : null;
|
|
8871
8950
|
const uploadMerged = upload ? {
|
|
@@ -8884,7 +8963,11 @@ function createCmsApiHandler(config) {
|
|
|
8884
8963
|
const usersApiMerged = usersApi && getCms ? {
|
|
8885
8964
|
...usersApi,
|
|
8886
8965
|
getCms: usersApi.getCms ?? getCms,
|
|
8887
|
-
getCompanyDetails: usersApi.getCompanyDetails ?? config.getCompanyDetails
|
|
8966
|
+
getCompanyDetails: usersApi.getCompanyDetails ?? config.getCompanyDetails,
|
|
8967
|
+
...getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}
|
|
8968
|
+
} : usersApi ? {
|
|
8969
|
+
...usersApi,
|
|
8970
|
+
...getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}
|
|
8888
8971
|
} : usersApi;
|
|
8889
8972
|
const usersHandlers = usersApiMerged ? createUsersApiHandlers(mergePerm(usersApiMerged) ?? usersApiMerged) : null;
|
|
8890
8973
|
const avatarPost = userAvatar ? createUserAvatarHandler(userAvatar) : null;
|
|
@@ -8895,7 +8978,7 @@ function createCmsApiHandler(config) {
|
|
|
8895
8978
|
entityMap,
|
|
8896
8979
|
json: config.json,
|
|
8897
8980
|
requireAuth: config.requireAuth,
|
|
8898
|
-
requireEntityPermission:
|
|
8981
|
+
requireEntityPermission: requireEntityPermissionEffective
|
|
8899
8982
|
});
|
|
8900
8983
|
const chatHandlers = chatConfig ? createChatHandlers(chatConfig) : null;
|
|
8901
8984
|
function resolveResource(segment) {
|
|
@@ -8904,12 +8987,10 @@ function createCmsApiHandler(config) {
|
|
|
8904
8987
|
}
|
|
8905
8988
|
return {
|
|
8906
8989
|
async handle(method, path, req) {
|
|
8907
|
-
const perm = reqEntityPerm;
|
|
8908
8990
|
async function analyticsGate() {
|
|
8909
8991
|
const a = await config.requireAuth(req);
|
|
8910
8992
|
if (a) return a;
|
|
8911
|
-
|
|
8912
|
-
return null;
|
|
8993
|
+
return requireEntityPermissionEffective(req, "analytics", "read");
|
|
8913
8994
|
}
|
|
8914
8995
|
if (path[0] === "admin" && path[1] === "roles") {
|
|
8915
8996
|
if (!adminRoles) return config.json({ error: "Not found" }, { status: 404 });
|
|
@@ -8993,19 +9074,17 @@ function createCmsApiHandler(config) {
|
|
|
8993
9074
|
const group = path[1];
|
|
8994
9075
|
const isPublic = settingsConfig?.publicGetGroups?.includes(group);
|
|
8995
9076
|
if (method === "GET") {
|
|
8996
|
-
if (!isPublic
|
|
9077
|
+
if (!isPublic) {
|
|
8997
9078
|
const a = await config.requireAuth(req);
|
|
8998
9079
|
if (a) return a;
|
|
8999
|
-
const pe = await
|
|
9080
|
+
const pe = await requireEntityPermissionEffective(req, "settings", "read");
|
|
9000
9081
|
if (pe) return pe;
|
|
9001
9082
|
}
|
|
9002
9083
|
return settingsHandlers.GET(req, group);
|
|
9003
9084
|
}
|
|
9004
9085
|
if (method === "PUT") {
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
if (pe) return pe;
|
|
9008
|
-
}
|
|
9086
|
+
const pe = await requireEntityPermissionEffective(req, "settings", "update");
|
|
9087
|
+
if (pe) return pe;
|
|
9009
9088
|
return settingsHandlers.PUT(req, group);
|
|
9010
9089
|
}
|
|
9011
9090
|
}
|
|
@@ -9021,10 +9100,8 @@ function createCmsApiHandler(config) {
|
|
|
9021
9100
|
if (path[0] === "orders" && path.length === 3 && path[2] === "invoice" && method === "GET" && getCms) {
|
|
9022
9101
|
const a = await config.requireAuth(req);
|
|
9023
9102
|
if (a) return a;
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
if (pe) return pe;
|
|
9027
|
-
}
|
|
9103
|
+
const pe = await requireEntityPermissionEffective(req, "orders", "read");
|
|
9104
|
+
if (pe) return pe;
|
|
9028
9105
|
const cms = await getCms();
|
|
9029
9106
|
const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await Promise.resolve().then(() => (init_erp_order_invoice(), erp_order_invoice_exports));
|
|
9030
9107
|
const oid = Number(path[1]);
|
|
@@ -9034,10 +9111,8 @@ function createCmsApiHandler(config) {
|
|
|
9034
9111
|
if (path[0] === "orders" && path.length === 3 && path[2] === "repost-erp" && getCms) {
|
|
9035
9112
|
const a = await config.requireAuth(req);
|
|
9036
9113
|
if (a) return a;
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
if (pe) return pe;
|
|
9040
|
-
}
|
|
9114
|
+
const pe = await requireEntityPermissionEffective(req, "orders", method === "GET" ? "read" : "update");
|
|
9115
|
+
if (pe) return pe;
|
|
9041
9116
|
const oid = Number(path[1]);
|
|
9042
9117
|
if (!Number.isFinite(oid)) return config.json({ error: "Invalid id" }, { status: 400 });
|
|
9043
9118
|
const cms = await getCms();
|
|
@@ -10494,6 +10569,9 @@ var DEFAULT_ADMIN_NAV = [
|
|
|
10494
10569
|
{ href: "/admin/submissions", label: "Submissions" },
|
|
10495
10570
|
{ href: "/admin/pages", label: "Pages" }
|
|
10496
10571
|
];
|
|
10572
|
+
|
|
10573
|
+
// src/index.ts
|
|
10574
|
+
console.log("\u{1F525} USING LOCAL CMS CORE (index.ts loaded) \u{1F525}");
|
|
10497
10575
|
export {
|
|
10498
10576
|
ADMIN_GROUP_NAME,
|
|
10499
10577
|
Address,
|