@infuro/cms-core 1.0.61 → 1.0.62
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 +3621 -2639
- package/dist/admin.js +2412 -1430
- package/dist/api.cjs +41 -37
- package/dist/api.js +9 -5
- package/dist/{chunk-URN7GS23.js → chunk-6LV36PCL.js} +199 -1059
- package/dist/{chunk-O2642WVS.js → chunk-6XAVZE4I.js} +17 -3
- package/dist/{chunk-BXYZDMTZ.cjs → chunk-AXMP2U43.cjs} +3 -94
- package/dist/{chunk-T3HPSF7K.js → chunk-AYWDQFJZ.js} +3 -0
- package/dist/chunk-CTIEAHQL.cjs +96 -0
- package/dist/chunk-GWDI752Q.js +83 -0
- package/dist/chunk-GZGFNVTK.js +886 -0
- package/dist/chunk-H3IVLIPR.cjs +86 -0
- package/dist/{chunk-2KUCQVAQ.js → chunk-HMLVPIJR.js} +2 -91
- package/dist/{chunk-V25RDUOU.cjs → chunk-LRD4CGOG.cjs} +38 -4
- package/dist/{chunk-73WVHINE.cjs → chunk-LVQSG25Y.cjs} +18 -4
- package/dist/chunk-NMYGQWHV.js +93 -0
- package/dist/chunk-OVTOP42W.js +199 -0
- package/dist/{chunk-CNAHVRRU.cjs → chunk-QA5C477U.cjs} +676 -312
- package/dist/{chunk-UHT4INVW.js → chunk-R6Q67HAS.js} +625 -252
- package/dist/{chunk-YSYX4GUD.cjs → chunk-TWTISTZB.cjs} +210 -1080
- package/dist/{chunk-77I3KS7V.cjs → chunk-UEE4PTTB.cjs} +3 -0
- package/dist/chunk-WFMVD567.cjs +209 -0
- package/dist/{chunk-L3525VXI.js → chunk-YW7EF7K7.js} +36 -2
- package/dist/chunk-ZPAPCGCR.cjs +899 -0
- package/dist/{email-queue-OI2HSCGE.js → email-queue-65PQAG4C.js} +3 -2
- package/dist/{email-queue-6NJY6HNM.cjs → email-queue-J7DXYNCE.cjs} +7 -6
- package/dist/email-service-F7HA4X63.js +3 -0
- package/dist/email-service-RDOTY3CO.cjs +28 -0
- package/dist/{emit-order-notification-trigger-TNEZOYEE.cjs → emit-order-notification-trigger-K7URAZHJ.cjs} +4 -4
- package/dist/{emit-order-notification-trigger-CZU3V2WE.js → emit-order-notification-trigger-MD7EBODC.js} +2 -2
- package/dist/{erp-order-invoice-EYYNR526.cjs → erp-order-invoice-C5GZCOBM.cjs} +6 -5
- package/dist/{erp-order-invoice-3GXDE443.js → erp-order-invoice-MYFCXOCY.js} +2 -1
- package/dist/index.cjs +363 -314
- package/dist/index.d.cts +53 -19
- package/dist/index.d.ts +53 -19
- package/dist/index.js +75 -26
- package/dist/migrations/1783000000000-AddOrderPendingProcessingCompletedTriggers.ts +56 -0
- package/dist/migrations/1783100000000-AddSmsToOrderNotificationBindingsChannelEnum.ts +17 -0
- package/dist/migrations/1783200000000-AddOrderAssigneeColumns.ts +30 -0
- package/dist/order-assignees-handlers-LKMAGLG6.js +150 -0
- package/dist/order-assignees-handlers-NPKD64P6.cjs +152 -0
- package/dist/order-completion-otp-handlers-3NTOGEA5.js +361 -0
- package/dist/order-completion-otp-handlers-4EOLYLAP.cjs +363 -0
- package/dist/order-notification-dispatcher-IYMOS4VY.js +10 -0
- package/dist/order-notification-dispatcher-X2XM5VUY.cjs +35 -0
- package/dist/sms-notification-templates-handlers-SJLO7JGZ.js +47 -0
- package/dist/sms-notification-templates-handlers-YSB3L2PK.cjs +49 -0
- package/package.json +1 -1
- package/dist/order-notification-dispatcher-KJVGLK5E.cjs +0 -24
- package/dist/order-notification-dispatcher-ZSFKEYMP.js +0 -7
|
@@ -4,6 +4,9 @@ var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
|
4
4
|
var events = require('events');
|
|
5
5
|
|
|
6
6
|
var KNOWN_NOTIFICATION_TRIGGERS = {
|
|
7
|
+
ORDER_PENDING: "order_pending",
|
|
8
|
+
ORDER_PROCESSING: "order_processing",
|
|
9
|
+
ORDER_COMPLETED: "order_completed",
|
|
7
10
|
ORDER_PLACED: "order_placed",
|
|
8
11
|
ORDER_CANCELLED: "order_cancelled",
|
|
9
12
|
PAYMENT_SUCCESS: "payment_success",
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
|
|
4
|
+
var crypto = require('crypto');
|
|
5
|
+
var typeorm = require('typeorm');
|
|
6
|
+
|
|
7
|
+
// src/plugins/sms/sms-queue.ts
|
|
8
|
+
var SMS_QUEUE_NAME = "sms";
|
|
9
|
+
function registerSmsQueueProcessor(cms) {
|
|
10
|
+
const queue = cms.getPlugin("queue");
|
|
11
|
+
const sms = cms.getPlugin("sms");
|
|
12
|
+
if (!queue || !sms || typeof sms.send !== "function") return;
|
|
13
|
+
queue.registerProcessor(SMS_QUEUE_NAME, async (data) => {
|
|
14
|
+
const payload = data;
|
|
15
|
+
if (!payload.to) return;
|
|
16
|
+
if (payload.templateKey?.trim()) {
|
|
17
|
+
await sms.send({
|
|
18
|
+
to: payload.to,
|
|
19
|
+
templateKey: payload.templateKey.trim(),
|
|
20
|
+
variables: payload.variables,
|
|
21
|
+
otpCode: payload.otpCode
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!payload.body?.trim()) return;
|
|
26
|
+
await sms.send({
|
|
27
|
+
to: payload.to,
|
|
28
|
+
body: payload.body,
|
|
29
|
+
otpCode: payload.otpCode,
|
|
30
|
+
variables: payload.variables
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
chunkUSNT2KNT_cjs.__name(registerSmsQueueProcessor, "registerSmsQueueProcessor");
|
|
35
|
+
async function queueSms(cms, payload) {
|
|
36
|
+
const queue = cms.getPlugin("queue");
|
|
37
|
+
const sms = cms.getPlugin("sms");
|
|
38
|
+
if (queue) {
|
|
39
|
+
await queue.add(SMS_QUEUE_NAME, payload);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (sms && typeof sms.send === "function") {
|
|
43
|
+
if (payload.templateKey?.trim()) {
|
|
44
|
+
await sms.send({
|
|
45
|
+
to: payload.to,
|
|
46
|
+
templateKey: payload.templateKey.trim(),
|
|
47
|
+
variables: payload.variables,
|
|
48
|
+
otpCode: payload.otpCode
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (payload.body?.trim()) {
|
|
53
|
+
await sms.send({
|
|
54
|
+
to: payload.to,
|
|
55
|
+
body: payload.body,
|
|
56
|
+
otpCode: payload.otpCode,
|
|
57
|
+
variables: payload.variables
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
chunkUSNT2KNT_cjs.__name(queueSms, "queueSms");
|
|
63
|
+
var OTP_TTL_MS = 10 * 60 * 1e3;
|
|
64
|
+
var MAX_SENDS_PER_HOUR = 5;
|
|
65
|
+
var MAX_VERIFY_ATTEMPTS = 8;
|
|
66
|
+
function getPepper(explicit) {
|
|
67
|
+
return (explicit || process.env.OTP_PEPPER || process.env.NEXTAUTH_SECRET || "dev-otp-pepper").trim();
|
|
68
|
+
}
|
|
69
|
+
chunkUSNT2KNT_cjs.__name(getPepper, "getPepper");
|
|
70
|
+
function hashOtpCode(code, purpose, identifier, pepper) {
|
|
71
|
+
return crypto.createHmac("sha256", getPepper(pepper)).update(`${purpose}|${identifier}|${code}`).digest("hex");
|
|
72
|
+
}
|
|
73
|
+
chunkUSNT2KNT_cjs.__name(hashOtpCode, "hashOtpCode");
|
|
74
|
+
function verifyOtpCodeHash(code, storedHash, purpose, identifier, pepper) {
|
|
75
|
+
const h = hashOtpCode(code, purpose, identifier, pepper);
|
|
76
|
+
try {
|
|
77
|
+
return crypto.timingSafeEqual(Buffer.from(h, "utf8"), Buffer.from(storedHash, "utf8"));
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
chunkUSNT2KNT_cjs.__name(verifyOtpCodeHash, "verifyOtpCodeHash");
|
|
83
|
+
function generateNumericOtp(length = 6) {
|
|
84
|
+
const max = 10 ** length;
|
|
85
|
+
return crypto.randomInt(0, max).toString().padStart(length, "0");
|
|
86
|
+
}
|
|
87
|
+
chunkUSNT2KNT_cjs.__name(generateNumericOtp, "generateNumericOtp");
|
|
88
|
+
function normalizePhoneE164(raw, defaultCountryCode) {
|
|
89
|
+
const t = raw.trim();
|
|
90
|
+
const digitsOnly = t.replace(/\D/g, "");
|
|
91
|
+
if (digitsOnly.length < 10) return null;
|
|
92
|
+
if (t.startsWith("+")) return `+${digitsOnly}`;
|
|
93
|
+
const cc = (defaultCountryCode || process.env.DEFAULT_PHONE_COUNTRY_CODE || "91").replace(/\D/g, "");
|
|
94
|
+
if (digitsOnly.length > 10) return `+${digitsOnly}`;
|
|
95
|
+
return `+${cc}${digitsOnly}`;
|
|
96
|
+
}
|
|
97
|
+
chunkUSNT2KNT_cjs.__name(normalizePhoneE164, "normalizePhoneE164");
|
|
98
|
+
async function countRecentOtpSends(dataSource, entityMap, purpose, identifier, since) {
|
|
99
|
+
const repo = dataSource.getRepository(entityMap.otp_challenges);
|
|
100
|
+
return repo.count({
|
|
101
|
+
where: {
|
|
102
|
+
purpose,
|
|
103
|
+
identifier,
|
|
104
|
+
createdAt: typeorm.MoreThan(since)
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
chunkUSNT2KNT_cjs.__name(countRecentOtpSends, "countRecentOtpSends");
|
|
109
|
+
async function createOtpChallenge(dataSource, entityMap, input) {
|
|
110
|
+
const { purpose, channel, identifier, code, pepper } = input;
|
|
111
|
+
const since = new Date(Date.now() - 60 * 60 * 1e3);
|
|
112
|
+
const recent = await countRecentOtpSends(dataSource, entityMap, purpose, identifier, since);
|
|
113
|
+
if (recent >= MAX_SENDS_PER_HOUR) {
|
|
114
|
+
return {
|
|
115
|
+
ok: false,
|
|
116
|
+
error: "Too many codes sent. Try again later.",
|
|
117
|
+
status: 429
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const repo = dataSource.getRepository(entityMap.otp_challenges);
|
|
121
|
+
await repo.delete({
|
|
122
|
+
purpose,
|
|
123
|
+
identifier,
|
|
124
|
+
consumedAt: typeorm.IsNull()
|
|
125
|
+
});
|
|
126
|
+
const expiresAt = new Date(Date.now() + OTP_TTL_MS);
|
|
127
|
+
const codeHash = hashOtpCode(code, purpose, identifier, pepper);
|
|
128
|
+
await repo.save(repo.create({
|
|
129
|
+
purpose,
|
|
130
|
+
channel,
|
|
131
|
+
identifier,
|
|
132
|
+
codeHash,
|
|
133
|
+
expiresAt,
|
|
134
|
+
attempts: 0,
|
|
135
|
+
consumedAt: null
|
|
136
|
+
}));
|
|
137
|
+
return {
|
|
138
|
+
ok: true
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
chunkUSNT2KNT_cjs.__name(createOtpChallenge, "createOtpChallenge");
|
|
142
|
+
async function verifyAndConsumeOtpChallenge(dataSource, entityMap, input) {
|
|
143
|
+
const { purpose, identifier, code, pepper } = input;
|
|
144
|
+
const repo = dataSource.getRepository(entityMap.otp_challenges);
|
|
145
|
+
const row = await repo.findOne({
|
|
146
|
+
where: {
|
|
147
|
+
purpose,
|
|
148
|
+
identifier,
|
|
149
|
+
consumedAt: typeorm.IsNull()
|
|
150
|
+
},
|
|
151
|
+
order: {
|
|
152
|
+
id: "DESC"
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
if (!row) {
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
error: "Invalid or expired code",
|
|
159
|
+
status: 400
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const r = row;
|
|
163
|
+
if (new Date(r.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
164
|
+
await repo.delete(row.id);
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
error: "Invalid or expired code",
|
|
168
|
+
status: 400
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
const attempts = r.attempts || 0;
|
|
172
|
+
if (attempts >= MAX_VERIFY_ATTEMPTS) {
|
|
173
|
+
await repo.delete(row.id);
|
|
174
|
+
return {
|
|
175
|
+
ok: false,
|
|
176
|
+
error: "Too many attempts",
|
|
177
|
+
status: 400
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const valid = verifyOtpCodeHash(code, r.codeHash, purpose, identifier, pepper);
|
|
181
|
+
if (!valid) {
|
|
182
|
+
await repo.update(row.id, {
|
|
183
|
+
attempts: attempts + 1
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
error: "Invalid or expired code",
|
|
188
|
+
status: 400
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
await repo.update(row.id, {
|
|
192
|
+
consumedAt: /* @__PURE__ */ new Date(),
|
|
193
|
+
attempts: attempts + 1
|
|
194
|
+
});
|
|
195
|
+
return {
|
|
196
|
+
ok: true
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
chunkUSNT2KNT_cjs.__name(verifyAndConsumeOtpChallenge, "verifyAndConsumeOtpChallenge");
|
|
200
|
+
|
|
201
|
+
exports.countRecentOtpSends = countRecentOtpSends;
|
|
202
|
+
exports.createOtpChallenge = createOtpChallenge;
|
|
203
|
+
exports.generateNumericOtp = generateNumericOtp;
|
|
204
|
+
exports.hashOtpCode = hashOtpCode;
|
|
205
|
+
exports.normalizePhoneE164 = normalizePhoneE164;
|
|
206
|
+
exports.queueSms = queueSms;
|
|
207
|
+
exports.registerSmsQueueProcessor = registerSmsQueueProcessor;
|
|
208
|
+
exports.verifyAndConsumeOtpChallenge = verifyAndConsumeOtpChallenge;
|
|
209
|
+
exports.verifyOtpCodeHash = verifyOtpCodeHash;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isOrderEligibleForInvoiceEmail, resolveOrderInvoicePdfBytes } from './chunk-
|
|
1
|
+
import { isOrderEligibleForInvoiceEmail, resolveOrderInvoicePdfBytes } from './chunk-HMLVPIJR.js';
|
|
2
2
|
import { __name } from './chunk-SHUYVCID.js';
|
|
3
3
|
|
|
4
4
|
// src/plugins/email/email-queue.ts
|
|
@@ -128,7 +128,41 @@ async function queueEmail(cms, payload) {
|
|
|
128
128
|
await queue.add(EMAIL_QUEUE_NAME, payload);
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
let email = cms && typeof cms.getPlugin === "function" ? cms.getPlugin("email") : void 0;
|
|
132
|
+
if (!email) {
|
|
133
|
+
try {
|
|
134
|
+
const { EmailService } = await import('./email-service-F7HA4X63.js');
|
|
135
|
+
const env = typeof process !== "undefined" && process.env ? process.env : {};
|
|
136
|
+
const type = String(env.SMTP_TYPE || "SMTP").toUpperCase();
|
|
137
|
+
const port = env.SMTP_PORT ? parseInt(env.SMTP_PORT, 10) : void 0;
|
|
138
|
+
const fallbackService = new EmailService({
|
|
139
|
+
type: type === "AWS" || type === "GMAIL" || type === "SENDGRID" ? type : "SMTP",
|
|
140
|
+
from: env.SMTP_FROM || "no-reply@example.com",
|
|
141
|
+
to: env.SMTP_TO || "info@example.com",
|
|
142
|
+
user: env.SMTP_USER,
|
|
143
|
+
password: env.SMTP_PASSWORD || env.SMTP_PASS,
|
|
144
|
+
host: env.SMTP_HOST,
|
|
145
|
+
port,
|
|
146
|
+
secure: env.SMTP_SECURE === "true",
|
|
147
|
+
region: env.AWS_SES_REGION || env.AWS_REGION,
|
|
148
|
+
accessKeyId: env.AWS_ACCESS_KEY_ID,
|
|
149
|
+
secretAccessKey: env.AWS_SECRET_ACCESS_KEY
|
|
150
|
+
});
|
|
151
|
+
if (payload.subject != null && payload.html != null) {
|
|
152
|
+
await fallbackService.send({
|
|
153
|
+
to: payload.to,
|
|
154
|
+
subject: payload.subject,
|
|
155
|
+
html: payload.html,
|
|
156
|
+
text: payload.text,
|
|
157
|
+
attachments: payload.attachments
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
} catch (e) {
|
|
162
|
+
console.error("[email-queue] fallback email send error", e);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
132
166
|
if (!email) return;
|
|
133
167
|
const attachmentsResult = await resolveInvoiceAttachmentForJob(cms, payload, registeredInvoiceOptions);
|
|
134
168
|
if (payload.templateName && payload.ctx) {
|