@infuro/cms-core 1.0.50 → 1.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs +843 -402
- package/dist/admin.d.cts +13 -1
- package/dist/admin.d.ts +13 -1
- package/dist/admin.js +843 -402
- package/dist/api.cjs +35 -35
- package/dist/api.js +4 -4
- package/dist/auth.cjs +44 -43
- package/dist/auth.d.cts +2 -3
- package/dist/auth.d.ts +2 -3
- package/dist/auth.js +2 -1
- package/dist/{chunk-JCMOOPNX.cjs → chunk-3BPD5NGU.cjs} +210 -90
- package/dist/chunk-7L6KWI7S.cjs +212 -0
- package/dist/{chunk-YV5PK4JW.cjs → chunk-BC22I7C7.cjs} +45 -247
- package/dist/{chunk-WRKV6MHB.js → chunk-BNKZNLEX.js} +2 -196
- package/dist/{chunk-IPDHT2UV.js → chunk-CTXBYO2J.js} +94 -104
- package/dist/{chunk-UUWAUHUW.cjs → chunk-JN4AFHZ4.cjs} +94 -105
- package/dist/{chunk-JE22VP6S.js → chunk-MXIWUFBP.js} +1 -1
- package/dist/{chunk-LT2WOPKA.js → chunk-UO5Q5RXB.js} +181 -61
- package/dist/{chunk-KOTXDSQB.cjs → chunk-UQWZUZ5X.cjs} +1 -1
- package/dist/chunk-WUQAOTHA.js +203 -0
- package/dist/{emit-order-notification-trigger-6XX7LSC4.js → emit-order-notification-trigger-HZQPPSFB.js} +1 -1
- package/dist/{emit-order-notification-trigger-NASG7ZEO.cjs → emit-order-notification-trigger-NR3VN6C6.cjs} +3 -3
- package/dist/index.cjs +334 -299
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +59 -24
- package/dist/middleware.cjs +15 -0
- package/dist/middleware.js +2 -0
- package/dist/{order-notification-dispatcher-3TA4ETYJ.js → order-notification-dispatcher-AT4IFAGL.js} +2 -2
- package/dist/{order-notification-dispatcher-ZEAZ5SHV.cjs → order-notification-dispatcher-YBAWDOIO.cjs} +5 -5
- package/package.json +6 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { linkUnclaimedContactToUser, ensureCustomerForUser } from './chunk-RK5ETF2I.js';
|
|
2
2
|
import { retireSoftDeletedUniqueValue } from './chunk-DBPSJYLZ.js';
|
|
3
3
|
import { getPermissionableEntityKeys, ADMIN_GROUP_NAME, isSuperAdmin, permissionRowsToRecord, vendorPortalFlagsFromUser } from './chunk-JIWUVQ6B.js';
|
|
4
|
+
import { logAuth, nextAuthCookieDebugInfo, summarizeSessionUserForLog } from './chunk-WUQAOTHA.js';
|
|
4
5
|
import { __name } from './chunk-SHUYVCID.js';
|
|
5
|
-
import { getToken } from 'next-auth/jwt';
|
|
6
6
|
import _CredentialsProvider from 'next-auth/providers/credentials';
|
|
7
7
|
import _GoogleProvider from 'next-auth/providers/google';
|
|
8
8
|
|
|
@@ -48,200 +48,6 @@ async function seedAdministratorPermissions(dataSource, entityMap) {
|
|
|
48
48
|
}
|
|
49
49
|
__name(seedAdministratorPermissions, "seedAdministratorPermissions");
|
|
50
50
|
|
|
51
|
-
// src/auth/auth-debug.ts
|
|
52
|
-
var LOG_PREFIX = "[cms-auth]";
|
|
53
|
-
function isAuthDebugEnabled() {
|
|
54
|
-
const v = process.env.CMS_AUTH_DEBUG?.trim().toLowerCase();
|
|
55
|
-
return v === "1" || v === "true" || v === "yes";
|
|
56
|
-
}
|
|
57
|
-
__name(isAuthDebugEnabled, "isAuthDebugEnabled");
|
|
58
|
-
function isAuthDebugClientEnabled() {
|
|
59
|
-
if (typeof window === "undefined") return false;
|
|
60
|
-
const v = process.env.NEXT_PUBLIC_CMS_AUTH_DEBUG?.trim().toLowerCase();
|
|
61
|
-
return v === "1" || v === "true" || v === "yes";
|
|
62
|
-
}
|
|
63
|
-
__name(isAuthDebugClientEnabled, "isAuthDebugClientEnabled");
|
|
64
|
-
function logAuth(message, data) {
|
|
65
|
-
if (!isAuthDebugEnabled()) return;
|
|
66
|
-
if (data) console.info(LOG_PREFIX, message, data);
|
|
67
|
-
else console.info(LOG_PREFIX, message);
|
|
68
|
-
}
|
|
69
|
-
__name(logAuth, "logAuth");
|
|
70
|
-
function logAuthClient(message, data) {
|
|
71
|
-
if (!isAuthDebugClientEnabled()) return;
|
|
72
|
-
if (data) console.info(LOG_PREFIX, message, data);
|
|
73
|
-
else console.info(LOG_PREFIX, message);
|
|
74
|
-
}
|
|
75
|
-
__name(logAuthClient, "logAuthClient");
|
|
76
|
-
function summarizeSessionUserForLog(user) {
|
|
77
|
-
if (!user || typeof user !== "object") return {
|
|
78
|
-
present: false
|
|
79
|
-
};
|
|
80
|
-
const u = user;
|
|
81
|
-
return {
|
|
82
|
-
present: true,
|
|
83
|
-
email: u.email ?? null,
|
|
84
|
-
id: u.id ?? null,
|
|
85
|
-
adminAccess: u.adminAccess ?? null,
|
|
86
|
-
isRBACAdmin: u.isRBACAdmin ?? null,
|
|
87
|
-
isVendorPortal: u.isVendorPortal ?? null,
|
|
88
|
-
groupName: u.groupName ?? null
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
__name(summarizeSessionUserForLog, "summarizeSessionUserForLog");
|
|
92
|
-
function nextAuthCookieDebugInfo() {
|
|
93
|
-
const nextAuthUrl = process.env.NEXTAUTH_URL ?? "(unset)";
|
|
94
|
-
const isHttps = nextAuthUrl.startsWith("https");
|
|
95
|
-
return {
|
|
96
|
-
nextAuthUrl,
|
|
97
|
-
hasSecret: Boolean(process.env.NEXTAUTH_SECRET),
|
|
98
|
-
cookieName: isHttps ? "__Secure-next-auth.session-token" : "next-auth.session-token",
|
|
99
|
-
cookieSecure: isHttps,
|
|
100
|
-
nodeEnv: process.env.NODE_ENV ?? "(unset)"
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
__name(nextAuthCookieDebugInfo, "nextAuthCookieDebugInfo");
|
|
104
|
-
|
|
105
|
-
// src/auth/middleware.ts
|
|
106
|
-
var defaultPublicApiMethods = {
|
|
107
|
-
"/api/contacts": [
|
|
108
|
-
"POST"
|
|
109
|
-
],
|
|
110
|
-
"/api/form-submissions": [
|
|
111
|
-
"POST"
|
|
112
|
-
],
|
|
113
|
-
"/api/blogs": [
|
|
114
|
-
"GET"
|
|
115
|
-
],
|
|
116
|
-
"/api/forms": [
|
|
117
|
-
"GET"
|
|
118
|
-
],
|
|
119
|
-
"/api/auth": [
|
|
120
|
-
"GET",
|
|
121
|
-
"POST"
|
|
122
|
-
],
|
|
123
|
-
"/api/health": [
|
|
124
|
-
"GET"
|
|
125
|
-
],
|
|
126
|
-
"/api/users/forgot-password": [
|
|
127
|
-
"POST"
|
|
128
|
-
],
|
|
129
|
-
"/api/users/set-password": [
|
|
130
|
-
"POST"
|
|
131
|
-
],
|
|
132
|
-
"/api/users/invite": [
|
|
133
|
-
"GET",
|
|
134
|
-
"POST"
|
|
135
|
-
],
|
|
136
|
-
/** Public keys only (e.g. googleEnabled); secrets stay private in the settings handler. */
|
|
137
|
-
"/api/settings/auth_providers": [
|
|
138
|
-
"GET"
|
|
139
|
-
]
|
|
140
|
-
};
|
|
141
|
-
function legacyGetSessionToken(request) {
|
|
142
|
-
const secure = request.cookies.get("__Secure-next-auth.session-token")?.value;
|
|
143
|
-
const regular = request.cookies.get("next-auth.session-token")?.value;
|
|
144
|
-
return secure ?? regular;
|
|
145
|
-
}
|
|
146
|
-
__name(legacyGetSessionToken, "legacyGetSessionToken");
|
|
147
|
-
function sessionCookiePresence(request) {
|
|
148
|
-
const secure = request.cookies.get("__Secure-next-auth.session-token")?.value;
|
|
149
|
-
const regular = request.cookies.get("next-auth.session-token")?.value;
|
|
150
|
-
const hasChunked = Boolean(request.cookies.get("next-auth.session-token.0")?.value) || Boolean(request.cookies.get("__Secure-next-auth.session-token.0")?.value);
|
|
151
|
-
return {
|
|
152
|
-
hasSecureToken: Boolean(secure),
|
|
153
|
-
hasRegularToken: Boolean(regular),
|
|
154
|
-
hasChunkedToken: hasChunked,
|
|
155
|
-
resolved: Boolean(secure ?? regular)
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
__name(sessionCookiePresence, "sessionCookiePresence");
|
|
159
|
-
function isPublicMethod(pathname, method, publicApiMethods) {
|
|
160
|
-
for (const [endpoint, methods] of Object.entries(publicApiMethods)) {
|
|
161
|
-
if (pathname.startsWith(endpoint) && methods.includes(method)) return true;
|
|
162
|
-
}
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
__name(isPublicMethod, "isPublicMethod");
|
|
166
|
-
async function hasValidSession(request, secret, legacyGetToken) {
|
|
167
|
-
if (request.req) {
|
|
168
|
-
const token = await getToken({
|
|
169
|
-
req: request.req,
|
|
170
|
-
secret
|
|
171
|
-
});
|
|
172
|
-
return token != null;
|
|
173
|
-
}
|
|
174
|
-
return Boolean(legacyGetToken(request));
|
|
175
|
-
}
|
|
176
|
-
__name(hasValidSession, "hasValidSession");
|
|
177
|
-
function createCmsMiddleware(config = {}) {
|
|
178
|
-
const { publicAdminPaths = [
|
|
179
|
-
"/admin/signin",
|
|
180
|
-
"/admin/forgot-password",
|
|
181
|
-
"/admin/reset-password",
|
|
182
|
-
"/admin/invite"
|
|
183
|
-
], publicApiMethods = defaultPublicApiMethods, signInPath = "/admin/signin", getSessionToken = legacyGetSessionToken, secret = process.env.NEXTAUTH_SECRET } = config;
|
|
184
|
-
return /* @__PURE__ */ __name(async function cmsMiddleware(request) {
|
|
185
|
-
const pathname = request.nextUrl.pathname;
|
|
186
|
-
const method = request.method;
|
|
187
|
-
if (publicAdminPaths.some((p) => pathname === p || pathname.startsWith(p + "/"))) {
|
|
188
|
-
return {
|
|
189
|
-
type: "next"
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
if (pathname.startsWith("/admin")) {
|
|
193
|
-
const authenticated = await hasValidSession(request, secret, getSessionToken);
|
|
194
|
-
const cookies = sessionCookiePresence(request);
|
|
195
|
-
if (!authenticated) {
|
|
196
|
-
logAuth("middleware: admin redirect to signin (no session)", {
|
|
197
|
-
pathname,
|
|
198
|
-
method,
|
|
199
|
-
usesGetToken: Boolean(request.req),
|
|
200
|
-
...cookies,
|
|
201
|
-
expectedCookieName: process.env.NEXTAUTH_URL?.startsWith("https") ? "__Secure-next-auth.session-token" : "next-auth.session-token"
|
|
202
|
-
});
|
|
203
|
-
return {
|
|
204
|
-
type: "redirect",
|
|
205
|
-
url: new URL(signInPath, request.url).toString()
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
logAuth("middleware: admin allowed", {
|
|
209
|
-
pathname,
|
|
210
|
-
method,
|
|
211
|
-
usesGetToken: Boolean(request.req),
|
|
212
|
-
...cookies
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
if (pathname.startsWith("/api")) {
|
|
216
|
-
if (isPublicMethod(pathname, method, publicApiMethods)) {
|
|
217
|
-
return {
|
|
218
|
-
type: "next"
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
const authenticated = await hasValidSession(request, secret, getSessionToken);
|
|
222
|
-
if (!authenticated) {
|
|
223
|
-
logAuth("middleware: api 401 (no session)", {
|
|
224
|
-
pathname,
|
|
225
|
-
method,
|
|
226
|
-
usesGetToken: Boolean(request.req),
|
|
227
|
-
...sessionCookiePresence(request)
|
|
228
|
-
});
|
|
229
|
-
return {
|
|
230
|
-
type: "json",
|
|
231
|
-
status: 401,
|
|
232
|
-
body: {
|
|
233
|
-
error: "Unauthorized"
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return {
|
|
239
|
-
type: "next"
|
|
240
|
-
};
|
|
241
|
-
}, "cmsMiddleware");
|
|
242
|
-
}
|
|
243
|
-
__name(createCmsMiddleware, "createCmsMiddleware");
|
|
244
|
-
|
|
245
51
|
// src/auth/auth-providers-settings.ts
|
|
246
52
|
var AUTH_PROVIDERS_SETTINGS_GROUP = "auth_providers";
|
|
247
53
|
function parseEnabled(raw) {
|
|
@@ -1022,4 +828,4 @@ async function buildStorefrontNextAuthOptions(config) {
|
|
|
1022
828
|
}
|
|
1023
829
|
__name(buildStorefrontNextAuthOptions, "buildStorefrontNextAuthOptions");
|
|
1024
830
|
|
|
1025
|
-
export { AUTH_PROVIDERS_SETTINGS_GROUP, buildNextAuthOptions, buildStorefrontNextAuthOptions,
|
|
831
|
+
export { AUTH_PROVIDERS_SETTINGS_GROUP, buildNextAuthOptions, buildStorefrontNextAuthOptions, createCustomerUserFromGoogleOAuth, getNextAuthOptions, getStorefrontNextAuthOptions, googleOAuthRedirectUri, isGoogleAuthPubliclyEnabled, resolveGoogleAuthConfig, seedAdministratorPermissions };
|
|
@@ -57,6 +57,9 @@ function buildEventOrderTemplateVariables(input) {
|
|
|
57
57
|
currency: String(order.currency ?? "INR"),
|
|
58
58
|
lines: orderLines
|
|
59
59
|
};
|
|
60
|
+
const qrToken = order.qrToken?.trim() || order.orderNumber?.trim() || "";
|
|
61
|
+
const fallbackQrUrl = qrToken ? `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(qrToken)}` : "";
|
|
62
|
+
const fallbackTicketQr = fallbackQrUrl ? `<img src="${fallbackQrUrl}" alt="Ticket QR Code" width="200" height="200" style="display:block;margin:12px 0;border:1px solid #e5e7eb;border-radius:8px;" />` : "";
|
|
60
63
|
return {
|
|
61
64
|
eventName: event.name ?? productNames ?? "",
|
|
62
65
|
vendorName: vendorName.trim(),
|
|
@@ -73,6 +76,8 @@ function buildEventOrderTemplateVariables(input) {
|
|
|
73
76
|
trackUrl,
|
|
74
77
|
invoiceNumber,
|
|
75
78
|
invoiceUrl,
|
|
79
|
+
ticketQr: fallbackTicketQr,
|
|
80
|
+
qrImageUrl: fallbackQrUrl,
|
|
76
81
|
orderDetails: formatOrderDetailsText(orderDetailsPayload),
|
|
77
82
|
orderDetailsHtml: formatOrderDetailsHtml(orderDetailsPayload)
|
|
78
83
|
};
|
|
@@ -2099,72 +2104,27 @@ async function getGoogleAccessToken(clientEmail, privateKey) {
|
|
|
2099
2104
|
return tokenData.access_token;
|
|
2100
2105
|
}
|
|
2101
2106
|
__name(getGoogleAccessToken, "getGoogleAccessToken");
|
|
2102
|
-
async function resolveFcmServiceAccount(dataSource, entityMap) {
|
|
2103
|
-
const pushSettings = await getSettingsGroup(dataSource, entityMap, "push");
|
|
2104
|
-
let projectId = pushSettings.firebase_project_id?.trim();
|
|
2105
|
-
let clientEmail = pushSettings.firebase_client_email?.trim();
|
|
2106
|
-
let privateKey = pushSettings.firebase_private_key?.trim();
|
|
2107
|
-
if (pushSettings.firebase_service_account_json?.trim()) {
|
|
2108
|
-
try {
|
|
2109
|
-
const parsed = JSON.parse(pushSettings.firebase_service_account_json.trim());
|
|
2110
|
-
if (parsed.project_id) projectId = parsed.project_id;
|
|
2111
|
-
if (parsed.client_email) clientEmail = parsed.client_email;
|
|
2112
|
-
if (parsed.private_key) privateKey = parsed.private_key;
|
|
2113
|
-
} catch {
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
if (!projectId || !clientEmail || !privateKey) {
|
|
2117
|
-
return {
|
|
2118
|
-
ok: false,
|
|
2119
|
-
error: "Firebase Service Account JSON / credentials are not configured"
|
|
2120
|
-
};
|
|
2121
|
-
}
|
|
2122
|
-
return {
|
|
2123
|
-
ok: true,
|
|
2124
|
-
account: {
|
|
2125
|
-
projectId,
|
|
2126
|
-
clientEmail,
|
|
2127
|
-
privateKey
|
|
2128
|
-
}
|
|
2129
|
-
};
|
|
2130
|
-
}
|
|
2131
|
-
__name(resolveFcmServiceAccount, "resolveFcmServiceAccount");
|
|
2132
|
-
async function validateFcmCredentials(dataSource, entityMap) {
|
|
2133
|
-
try {
|
|
2134
|
-
const resolved = await resolveFcmServiceAccount(dataSource, entityMap);
|
|
2135
|
-
if (!resolved.ok) {
|
|
2136
|
-
return {
|
|
2137
|
-
success: false,
|
|
2138
|
-
error: resolved.error
|
|
2139
|
-
};
|
|
2140
|
-
}
|
|
2141
|
-
const { projectId, clientEmail, privateKey } = resolved.account;
|
|
2142
|
-
await getGoogleAccessToken(clientEmail, privateKey);
|
|
2143
|
-
return {
|
|
2144
|
-
success: true,
|
|
2145
|
-
projectId,
|
|
2146
|
-
clientEmail
|
|
2147
|
-
};
|
|
2148
|
-
} catch (err) {
|
|
2149
|
-
const errorMsg = err instanceof Error ? err.message : "Unknown credential validation error";
|
|
2150
|
-
console.error("[fcm-push] Exception in validateFcmCredentials", errorMsg);
|
|
2151
|
-
return {
|
|
2152
|
-
success: false,
|
|
2153
|
-
error: errorMsg
|
|
2154
|
-
};
|
|
2155
|
-
}
|
|
2156
|
-
}
|
|
2157
|
-
__name(validateFcmCredentials, "validateFcmCredentials");
|
|
2158
2107
|
async function sendFcmPushNotification(dataSource, entityMap, msg) {
|
|
2159
2108
|
try {
|
|
2160
|
-
const
|
|
2161
|
-
|
|
2109
|
+
const pushSettings = await getSettingsGroup(dataSource, entityMap, "push");
|
|
2110
|
+
let projectId = pushSettings.firebase_project_id?.trim();
|
|
2111
|
+
let clientEmail = pushSettings.firebase_client_email?.trim();
|
|
2112
|
+
let privateKey = pushSettings.firebase_private_key?.trim();
|
|
2113
|
+
if (pushSettings.firebase_service_account_json?.trim()) {
|
|
2114
|
+
try {
|
|
2115
|
+
const parsed = JSON.parse(pushSettings.firebase_service_account_json.trim());
|
|
2116
|
+
if (parsed.project_id) projectId = parsed.project_id;
|
|
2117
|
+
if (parsed.client_email) clientEmail = parsed.client_email;
|
|
2118
|
+
if (parsed.private_key) privateKey = parsed.private_key;
|
|
2119
|
+
} catch {
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
if (!projectId || !clientEmail || !privateKey) {
|
|
2162
2123
|
return {
|
|
2163
2124
|
success: false,
|
|
2164
|
-
error:
|
|
2125
|
+
error: "Firebase Service Account JSON / credentials are not configured"
|
|
2165
2126
|
};
|
|
2166
2127
|
}
|
|
2167
|
-
const { projectId, clientEmail, privateKey } = resolved.account;
|
|
2168
2128
|
const accessToken = await getGoogleAccessToken(clientEmail, privateKey);
|
|
2169
2129
|
const fcmEndpoint = `https://fcm.googleapis.com/v1/projects/${projectId}/messages:send`;
|
|
2170
2130
|
const fcmPayload = {
|
|
@@ -2275,59 +2235,69 @@ async function loadBoundTemplate(triggerKey, channel, audienceType = "customers"
|
|
|
2275
2235
|
console.warn("[order-notifications] order_notification_bindings or message_templates missing from entityMap");
|
|
2276
2236
|
return null;
|
|
2277
2237
|
}
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
triggerKey,
|
|
2282
|
-
channel,
|
|
2283
|
-
type: audienceType,
|
|
2284
|
-
enabled: true
|
|
2285
|
-
}
|
|
2286
|
-
});
|
|
2287
|
-
if (!binding && audienceType === "customers") {
|
|
2288
|
-
binding = await bindingRepo.findOne({
|
|
2238
|
+
try {
|
|
2239
|
+
const bindingRepo = dataSource.getRepository(entityMap.order_notification_bindings);
|
|
2240
|
+
let binding = await bindingRepo.findOne({
|
|
2289
2241
|
where: {
|
|
2290
2242
|
triggerKey,
|
|
2291
2243
|
channel,
|
|
2244
|
+
type: audienceType,
|
|
2292
2245
|
enabled: true
|
|
2293
2246
|
}
|
|
2294
|
-
});
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
}
|
|
2304
|
-
const templateId = binding.messageTemplateId;
|
|
2305
|
-
if (templateId == null) {
|
|
2306
|
-
console.warn("[order-notifications] binding exists but no template selected", {
|
|
2307
|
-
triggerKey,
|
|
2308
|
-
channel,
|
|
2309
|
-
audienceType
|
|
2310
|
-
});
|
|
2311
|
-
return null;
|
|
2312
|
-
}
|
|
2313
|
-
const template = await dataSource.getRepository(entityMap.message_templates).findOne({
|
|
2314
|
-
where: {
|
|
2315
|
-
id: templateId,
|
|
2316
|
-
channel,
|
|
2317
|
-
deleted: false,
|
|
2318
|
-
enabled: true
|
|
2247
|
+
}).catch(() => null);
|
|
2248
|
+
if (!binding && audienceType === "customers") {
|
|
2249
|
+
binding = await bindingRepo.findOne({
|
|
2250
|
+
where: {
|
|
2251
|
+
triggerKey,
|
|
2252
|
+
channel,
|
|
2253
|
+
enabled: true
|
|
2254
|
+
}
|
|
2255
|
+
}).catch(() => null);
|
|
2319
2256
|
}
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2257
|
+
if (!binding) {
|
|
2258
|
+
console.warn("[order-notifications] no order_notification_bindings row", {
|
|
2259
|
+
triggerKey,
|
|
2260
|
+
channel,
|
|
2261
|
+
audienceType
|
|
2262
|
+
});
|
|
2263
|
+
return null;
|
|
2264
|
+
}
|
|
2265
|
+
const templateId = binding.messageTemplateId;
|
|
2266
|
+
if (templateId == null) {
|
|
2267
|
+
console.warn("[order-notifications] binding exists but no template selected", {
|
|
2268
|
+
triggerKey,
|
|
2269
|
+
channel,
|
|
2270
|
+
audienceType
|
|
2271
|
+
});
|
|
2272
|
+
return null;
|
|
2273
|
+
}
|
|
2274
|
+
const template = await dataSource.getRepository(entityMap.message_templates).findOne({
|
|
2275
|
+
where: {
|
|
2276
|
+
id: templateId,
|
|
2277
|
+
channel,
|
|
2278
|
+
deleted: false,
|
|
2279
|
+
enabled: true
|
|
2280
|
+
}
|
|
2281
|
+
}).catch(() => null);
|
|
2282
|
+
if (!template) {
|
|
2283
|
+
console.warn("[order-notifications] bound template not found or disabled", {
|
|
2284
|
+
triggerKey,
|
|
2285
|
+
channel,
|
|
2286
|
+
audienceType,
|
|
2287
|
+
templateId
|
|
2288
|
+
});
|
|
2289
|
+
return null;
|
|
2290
|
+
}
|
|
2291
|
+
return template;
|
|
2292
|
+
} catch (err) {
|
|
2293
|
+
console.warn("[order-notifications] loadBoundTemplate query failed", {
|
|
2323
2294
|
triggerKey,
|
|
2324
2295
|
channel,
|
|
2325
2296
|
audienceType,
|
|
2326
|
-
|
|
2297
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2327
2298
|
});
|
|
2328
2299
|
return null;
|
|
2329
2300
|
}
|
|
2330
|
-
return template;
|
|
2331
2301
|
}
|
|
2332
2302
|
__name(loadBoundTemplate, "loadBoundTemplate");
|
|
2333
2303
|
function mergeTriggerVariables(payload, rich) {
|
|
@@ -2344,9 +2314,11 @@ function mergeTriggerVariables(payload, rich) {
|
|
|
2344
2314
|
refundAmount: String(payload.refundAmount)
|
|
2345
2315
|
} : {}
|
|
2346
2316
|
};
|
|
2317
|
+
const extraVars = payload.extraVariables ?? {};
|
|
2347
2318
|
return {
|
|
2348
2319
|
...basic,
|
|
2349
|
-
...rich ?? {}
|
|
2320
|
+
...rich ?? {},
|
|
2321
|
+
...extraVars
|
|
2350
2322
|
};
|
|
2351
2323
|
}
|
|
2352
2324
|
__name(mergeTriggerVariables, "mergeTriggerVariables");
|
|
@@ -2542,7 +2514,23 @@ async function getAdminRecipientEmails(dataSource, entityMap) {
|
|
|
2542
2514
|
}
|
|
2543
2515
|
} catch {
|
|
2544
2516
|
}
|
|
2545
|
-
|
|
2517
|
+
const vendorEmails = /* @__PURE__ */ new Set();
|
|
2518
|
+
try {
|
|
2519
|
+
const vRows = await dataSource.query(`SELECT DISTINCT LOWER(TRIM(email)) AS email FROM vendors WHERE COALESCE(deleted, false) = false AND email IS NOT NULL AND TRIM(email) != ''`).catch(() => []);
|
|
2520
|
+
for (const r of vRows) {
|
|
2521
|
+
if (r.email) vendorEmails.add(r.email.toLowerCase());
|
|
2522
|
+
}
|
|
2523
|
+
const vuRows = await dataSource.query(`SELECT DISTINCT LOWER(TRIM(u.email)) AS email
|
|
2524
|
+
FROM users u
|
|
2525
|
+
LEFT JOIN user_groups g ON g.id = u."groupId"
|
|
2526
|
+
WHERE COALESCE(u.deleted, false) = false
|
|
2527
|
+
AND (LOWER(g.name) LIKE '%vendor%' OR u."groupId" = 5)`).catch(() => []);
|
|
2528
|
+
for (const r of vuRows) {
|
|
2529
|
+
if (r.email) vendorEmails.add(r.email.toLowerCase());
|
|
2530
|
+
}
|
|
2531
|
+
} catch {
|
|
2532
|
+
}
|
|
2533
|
+
return Array.from(emails).filter((e) => !vendorEmails.has(e.toLowerCase()));
|
|
2546
2534
|
}
|
|
2547
2535
|
__name(getAdminRecipientEmails, "getAdminRecipientEmails");
|
|
2548
2536
|
function formatBodyForEmailHtml(body) {
|
|
@@ -2776,6 +2764,8 @@ function initWhatsappTriggerDispatcher(deps) {
|
|
|
2776
2764
|
if (initialized) return;
|
|
2777
2765
|
initialized = true;
|
|
2778
2766
|
const { dataSource, entityMap, getCms } = deps;
|
|
2767
|
+
void dataSource.query(`ALTER TYPE "order_notification_bindings_channel_enum" ADD VALUE IF NOT EXISTS 'mobile'`).catch(() => {
|
|
2768
|
+
});
|
|
2779
2769
|
notificationTriggerEmitter.onAnyTrigger((triggerKey, payload) => {
|
|
2780
2770
|
void handleTrigger(triggerKey, payload, dataSource, entityMap, getCms).catch((err) => {
|
|
2781
2771
|
console.error("[order-notifications]", triggerKey, err);
|
|
@@ -2835,4 +2825,4 @@ async function resendOrderNotification(triggerKey, orderId, deps) {
|
|
|
2835
2825
|
}
|
|
2836
2826
|
__name(resendOrderNotification, "resendOrderNotification");
|
|
2837
2827
|
|
|
2838
|
-
export { CHAT_EMAIL_LOG, EmailService, WhatsAppService, buildChatbotSystemPromptWithEmailTool, buildEventOrderTemplateVariables, buildTranscriptForLeadEmail, detectChatLeadIntent, emailPlugin, emailTemplates, getSettingsGroup, initWhatsappTriggerDispatcher, isWhatsAppPluginEnabled, joinRecipientsForSend, mergeWhatsAppConfigLayers, parseEmailRecipientsFromConfig, parseIntentRecipientEmails, queueWhatsApp, registerWhatsAppQueueProcessor, renderEmail, renderLayout, resendOrderNotification, resolveChatEmailToolSettings, sendChatLeadEmail, sendFcmPushNotification, serializeEmailRecipients,
|
|
2828
|
+
export { CHAT_EMAIL_LOG, EmailService, WhatsAppService, buildChatbotSystemPromptWithEmailTool, buildEventOrderTemplateVariables, buildTranscriptForLeadEmail, detectChatLeadIntent, emailPlugin, emailTemplates, getSettingsGroup, initWhatsappTriggerDispatcher, isWhatsAppPluginEnabled, joinRecipientsForSend, mergeWhatsAppConfigLayers, parseEmailRecipientsFromConfig, parseIntentRecipientEmails, queueWhatsApp, registerWhatsAppQueueProcessor, renderEmail, renderLayout, resendOrderNotification, resolveChatEmailToolSettings, sendChatLeadEmail, sendFcmPushNotification, serializeEmailRecipients, whatsAppConfigured };
|