order-management 0.0.13 → 0.0.15
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/.medusa/server/src/api/store/guest-orders/[id]/invoice/route.js +71 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/returns/route.js +65 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/route.js +64 -0
- package/.medusa/server/src/api/store/guest-orders/route.js +79 -0
- package/.medusa/server/src/api/store/otp/request/route.js +141 -0
- package/.medusa/server/src/api/store/otp/verify/route.js +47 -0
- package/.medusa/server/src/services/otp-service.js +59 -0
- package/.medusa/server/src/subscribers/send-order-email.js +105 -5
- package/README.md +28 -1
- package/package.json +7 -5
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GET = GET;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
// import { INVOICE_MODULE } from "../../../../../medusa-invoice-sbl/src/modules/invoice"
|
|
9
|
+
// import InvoiceModuleService from "../../../../../medusa-invoice-sbl/src/modules/invoice/service"
|
|
10
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
11
|
+
async function GET(req, res) {
|
|
12
|
+
const authHeader = req.headers.authorization;
|
|
13
|
+
const { id } = req.params;
|
|
14
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
15
|
+
res.status(401).json({ message: "Missing or invalid Authorization header" });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const token = authHeader.split(" ")[1];
|
|
19
|
+
const secret = process.env.JWT_SECRET || "medusa-secret-guest-access";
|
|
20
|
+
try {
|
|
21
|
+
const decoded = jsonwebtoken_1.default.verify(token, secret);
|
|
22
|
+
if (!decoded || !decoded.guest_identifier) {
|
|
23
|
+
res.status(401).json({ message: "Invalid token payload" });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const { guest_identifier } = decoded;
|
|
27
|
+
// Resolve Query to fetch order and verify ownership
|
|
28
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
29
|
+
// Fetch the specific order and include customer info
|
|
30
|
+
const { data: orders } = await query.graph({
|
|
31
|
+
entity: "order",
|
|
32
|
+
fields: ["id", "customer.has_account"],
|
|
33
|
+
filters: {
|
|
34
|
+
id: id,
|
|
35
|
+
email: guest_identifier
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
const order = orders[0];
|
|
39
|
+
// Ensure the order exists and either has no customer record or the customer does NOT have an account
|
|
40
|
+
if (!order || (order.customer && order.customer.has_account === true)) {
|
|
41
|
+
res.status(404).json({ message: "Order not found or access denied" });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// 3. Generate Invoice PDF
|
|
45
|
+
// Try to resolve the invoice service if it exists
|
|
46
|
+
try {
|
|
47
|
+
// Note: INVOICE_MODULE and InvoiceModuleService would be imported from the invoice plugin
|
|
48
|
+
// For now, we use a placeholder or check if the service is registered
|
|
49
|
+
const invoiceService = req.scope.resolve("invoiceModuleService");
|
|
50
|
+
if (invoiceService) {
|
|
51
|
+
const pdfBuffer = await invoiceService.generateInvoice(id, req.scope);
|
|
52
|
+
res.setHeader("Content-Type", "application/pdf");
|
|
53
|
+
res.setHeader("Content-Disposition", `attachment; filename=invoice-${id}.pdf`);
|
|
54
|
+
res.status(200).send(pdfBuffer);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (invoiceError) {
|
|
59
|
+
console.error(`[Invoice Download] Invoice service not available: ${invoiceError}`);
|
|
60
|
+
}
|
|
61
|
+
res.status(200).json({
|
|
62
|
+
message: "Invoice generation is not available in this environment, but the endpoint is correctly verifying permissions.",
|
|
63
|
+
order_id: id
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
68
|
+
res.status(401).json({ message: "Unauthorized or invalid token", error: errorMessage });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2d1ZXN0LW9yZGVycy9baWRdL2ludm9pY2Uvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFNQSxrQkEwRUM7QUEvRUQscURBQXFFO0FBQ3JFLHlGQUF5RjtBQUN6RixtR0FBbUc7QUFDbkcsZ0VBQThDO0FBRXZDLEtBQUssVUFBVSxHQUFHLENBQ3JCLEdBQWtCLEVBQ2xCLEdBQW1CO0lBRW5CLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFBO0lBQzVDLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFBO0lBRXpCLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDbkQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUseUNBQXlDLEVBQUUsQ0FBQyxDQUFBO1FBQzVFLE9BQU07SUFDVixDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN0QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSw0QkFBNEIsQ0FBQTtJQUVyRSxJQUFJLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxzQkFBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFlLENBQUE7UUFFdkQsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixF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
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.POST = POST;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
// import { IOrderModuleService } from "@medusajs/framework/types"
|
|
9
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
10
|
+
async function POST(req, res) {
|
|
11
|
+
const authHeader = req.headers.authorization;
|
|
12
|
+
const { id } = req.params;
|
|
13
|
+
const { items, reason_id, note } = req.body;
|
|
14
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
15
|
+
res.status(401).json({ message: "Missing or invalid Authorization header" });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!items || !items.length) {
|
|
19
|
+
res.status(400).json({ message: "Items are required for return" });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const token = authHeader.split(" ")[1];
|
|
23
|
+
const secret = process.env.JWT_SECRET || "medusa-secret-guest-access";
|
|
24
|
+
try {
|
|
25
|
+
const decoded = jsonwebtoken_1.default.verify(token, secret);
|
|
26
|
+
if (!decoded || !decoded.guest_identifier) {
|
|
27
|
+
res.status(401).json({ message: "Invalid token payload" });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const { guest_identifier } = decoded;
|
|
31
|
+
// Resolve Query to fetch order and verify ownership
|
|
32
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
33
|
+
// Fetch the specific order and include customer info
|
|
34
|
+
const { data: orders } = await query.graph({
|
|
35
|
+
entity: "order",
|
|
36
|
+
fields: ["id", "customer.has_account"],
|
|
37
|
+
filters: {
|
|
38
|
+
id: id,
|
|
39
|
+
email: guest_identifier
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const order = orders[0];
|
|
43
|
+
// Ensure the order exists and either has no customer record or the customer does NOT have an account
|
|
44
|
+
if (!order || (order.customer && order.customer.has_account === true)) {
|
|
45
|
+
res.status(404).json({ message: "Order not found or access denied" });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// 3. Create Return Request
|
|
49
|
+
// In Medusa v2, we use order workflows or direct module calls.
|
|
50
|
+
// For simplicity and to fit the current architecture, we'll suggest using a workflow if available or direct module interaction.
|
|
51
|
+
// Since we are building a plugin, we'll use the available services.
|
|
52
|
+
// This is a placeholder for the actual return workflow/module call in Medusa v2
|
|
53
|
+
// Typically: createReturnWorkflow(req.scope).run({ input: { order_id: id, items, ... } })
|
|
54
|
+
res.status(200).json({
|
|
55
|
+
message: "Return request initiated successfully. This is a mock implementation of the return creation logic.",
|
|
56
|
+
order_id: id,
|
|
57
|
+
items
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
62
|
+
res.status(401).json({ message: "Unauthorized or invalid token", error: errorMessage });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2d1ZXN0LW9yZGVycy9baWRdL3JldHVybnMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFLQSxvQkEwRUM7QUE5RUQscURBQThFO0FBQzlFLGtFQUFrRTtBQUNsRSxnRUFBOEM7QUFFdkMsS0FBSyxVQUFVLElBQUksQ0FDdEIsR0FBa0IsRUFDbEIsR0FBbUI7SUFFbkIsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUE7SUFDNUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFDekIsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDLElBSXRDLENBQUE7SUFFRCxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ25ELEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHlDQUF5QyxFQUFFLENBQUMsQ0FBQTtRQUM1RSxPQUFNO0lBQ1YsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDMUIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsQ0FBQyxDQUFBO1FBQ2xFLE9BQU07SUFDVixDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN0QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSw0QkFBNEIsQ0FBQTtJQUVyRSxJQUFJLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxzQkFBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFlLENBQUE7UUFFdkQsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQTtZQUMxRCxPQUFNO1FBQ1YsQ0FBQztRQUVELE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLE9BQU8sQ0FBQTtRQUVwQyxvREFBb0Q7UUFDcEQsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFaEUscURBQXFEO1FBQ3JELE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQ3ZDLE1BQU0sRUFBRSxPQUFPO1lBQ2YsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLHNCQUFzQixDQUFDO1lBQ3RDLE9BQU8sRUFBRTtnQkFDTCxFQUFFLEVBQUUsRUFBRTtnQkFDTixLQUFLLEVBQUUsZ0JBQWdCO2FBQzFCO1NBQ0osQ0FBQyxDQUFBO1FBRUYsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRXZCLHFHQUFxRztRQUNyRyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3BFLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLGtDQUFrQyxFQUFFLENBQUMsQ0FBQTtZQUNyRSxPQUFNO1FBQ1YsQ0FBQztRQUVELDJCQUEyQjtRQUMzQiwrREFBK0Q7UUFDL0QsZ0lBQWdJO1FBQ2hJLG9FQUFvRTtRQUVwRSxnRkFBZ0Y7UUFDaEYsMEZBQTBGO1FBRTFGLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ2pCLE9BQU8sRUFBRSxvR0FBb0c7WUFDN0csUUFBUSxFQUFFLEVBQUU7WUFDWixLQUFLO1NBQ1IsQ0FBQyxDQUFBO0lBRU4sQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDYixNQUFNLFlBQVksR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUE7UUFDN0UsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUE7SUFDM0YsQ0FBQztBQUNMLENBQUMifQ==
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GET = GET;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
9
|
+
async function GET(req, res) {
|
|
10
|
+
const authHeader = req.headers.authorization;
|
|
11
|
+
const { id } = req.params;
|
|
12
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
13
|
+
res.status(401).json({ message: "Missing or invalid Authorization header" });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const token = authHeader.split(" ")[1];
|
|
17
|
+
const secret = process.env.JWT_SECRET || "medusa-secret-guest-access";
|
|
18
|
+
try {
|
|
19
|
+
const decoded = jsonwebtoken_1.default.verify(token, secret);
|
|
20
|
+
if (!decoded || !decoded.guest_identifier) {
|
|
21
|
+
res.status(401).json({ message: "Invalid token payload" });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const { guest_identifier, customer_id } = decoded;
|
|
25
|
+
// Resolve Query to fetch order
|
|
26
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
27
|
+
// Fetch the specific order and include customer info
|
|
28
|
+
const { data: orders } = await query.graph({
|
|
29
|
+
entity: "order",
|
|
30
|
+
fields: [
|
|
31
|
+
"*",
|
|
32
|
+
"items.*",
|
|
33
|
+
"shipping_address.*",
|
|
34
|
+
"billing_address.*",
|
|
35
|
+
"shipping_methods.*",
|
|
36
|
+
"fulfillments.*",
|
|
37
|
+
"fulfillments.items.*",
|
|
38
|
+
"payments.*",
|
|
39
|
+
"total",
|
|
40
|
+
"customer.id",
|
|
41
|
+
"customer.has_account"
|
|
42
|
+
],
|
|
43
|
+
filters: {
|
|
44
|
+
id: id,
|
|
45
|
+
customer_id: customer_id ? [customer_id] : undefined,
|
|
46
|
+
email: !customer_id ? guest_identifier : undefined
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const order = orders[0];
|
|
50
|
+
// Ensure the order exists and either has no customer record or the customer does NOT have an account
|
|
51
|
+
if (!order || (order.customer && order.customer.has_account === true)) {
|
|
52
|
+
res.status(404).json({ message: "Order not found or access denied" });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
res.status(200).json({
|
|
56
|
+
order
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
61
|
+
res.status(401).json({ message: "Unauthorized or invalid token", error: errorMessage });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2d1ZXN0LW9yZGVycy9baWRdL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBSUEsa0JBbUVDO0FBdEVELHFEQUFxRTtBQUNyRSxnRUFBOEM7QUFFdkMsS0FBSyxVQUFVLEdBQUcsQ0FDckIsR0FBa0IsRUFDbEIsR0FBbUI7SUFFbkIsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUE7SUFDNUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFFekIsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUNuRCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSx5Q0FBeUMsRUFBRSxDQUFDLENBQUE7UUFDNUUsT0FBTTtJQUNWLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3RDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLDRCQUE0QixDQUFBO0lBRXJFLElBQUksQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLHNCQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQWUsQ0FBQTtRQUV2RCxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDeEMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFBO1lBQzFELE9BQU07UUFDVixDQUFDO1FBRUQsTUFBTSxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxHQUFHLE9BQU8sQ0FBQTtRQUVqRCwrQkFBK0I7UUFDL0IsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFaEUscURBQXFEO1FBQ3JELE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQ3ZDLE1BQU0sRUFBRSxPQUFPO1lBQ2YsTUFBTSxFQUFFO2dCQUNKLEdBQUc7Z0JBQ0gsU0FBUztnQkFDVCxvQkFBb0I7Z0JBQ3BCLG1CQUFtQjtnQkFDbkIsb0JBQW9CO2dCQUNwQixnQkFBZ0I7Z0JBQ2hCLHNCQUFzQjtnQkFDdEIsWUFBWTtnQkFDWixPQUFPO2dCQUNQLGFBQWE7Z0JBQ2Isc0JBQXNCO2FBQ3pCO1lBQ0QsT0FBTyxFQUFFO2dCQUNMLEVBQUUsRUFBRSxFQUFFO2dCQUNOLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ3BELEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDckQ7U0FDSixDQUFDLENBQUE7UUFFRixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFdkIscUdBQXFHO1FBQ3JHLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDcEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsQ0FBQyxDQUFBO1lBQ3JFLE9BQU07UUFDVixDQUFDO1FBRUQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDakIsS0FBSztTQUNSLENBQUMsQ0FBQTtJQUVOLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxZQUFZLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFBO1FBQzdFLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLCtCQUErQixFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFBO0lBQzNGLENBQUM7QUFDTCxDQUFDIn0=
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GET = GET;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
9
|
+
async function GET(req, res) {
|
|
10
|
+
const authHeader = req.headers.authorization;
|
|
11
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
12
|
+
res.status(401).json({ message: "Missing or invalid Authorization header" });
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const token = authHeader.split(" ")[1];
|
|
16
|
+
const secret = process.env.JWT_SECRET || "medusa-secret-guest-access";
|
|
17
|
+
try {
|
|
18
|
+
const decoded = jsonwebtoken_1.default.verify(token, secret);
|
|
19
|
+
if (!decoded || !decoded.guest_identifier) {
|
|
20
|
+
res.status(401).json({ message: "Invalid token payload" });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const { guest_identifier, customer_id } = decoded;
|
|
24
|
+
// Resolve Query to fetch orders
|
|
25
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
26
|
+
console.log(`[Guest Orders Debug] Fetching orders for: ${guest_identifier} (CID: ${customer_id || 'N/A'})`);
|
|
27
|
+
let guestIds = customer_id ? [customer_id] : [];
|
|
28
|
+
// 1. Fallback: Fetch guest customers for this email if ID is missing from token
|
|
29
|
+
if (guestIds.length === 0) {
|
|
30
|
+
const { data: guestCustomers } = await query.graph({
|
|
31
|
+
entity: "customer",
|
|
32
|
+
fields: ["id"],
|
|
33
|
+
filters: {
|
|
34
|
+
email: guest_identifier,
|
|
35
|
+
has_account: false
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
guestIds = guestCustomers.map(c => c.id);
|
|
39
|
+
console.log(`[Guest Orders Debug] Fallback lookup found IDs: ${guestIds.join(", ")}`);
|
|
40
|
+
}
|
|
41
|
+
if (guestIds.length === 0) {
|
|
42
|
+
res.status(200).json({ orders: [], count: 0, guest_identifier });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// 2. Fetch orders tied to these specific guest customer IDs
|
|
46
|
+
const { data: orders } = await query.graph({
|
|
47
|
+
entity: "order",
|
|
48
|
+
fields: [
|
|
49
|
+
"id",
|
|
50
|
+
"display_id",
|
|
51
|
+
"email",
|
|
52
|
+
"customer_id",
|
|
53
|
+
"status",
|
|
54
|
+
"total",
|
|
55
|
+
"currency_code",
|
|
56
|
+
"created_at",
|
|
57
|
+
"items.*"
|
|
58
|
+
],
|
|
59
|
+
filters: {
|
|
60
|
+
customer_id: guestIds,
|
|
61
|
+
},
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
sort: ["-created_at"]
|
|
64
|
+
});
|
|
65
|
+
// 3. Simple filter for canceled orders
|
|
66
|
+
const guestOrders = orders.filter(o => o.status !== "canceled");
|
|
67
|
+
console.log(`[Guest Orders Debug] Found ${guestOrders.length} valid guest orders`);
|
|
68
|
+
res.status(200).json({
|
|
69
|
+
orders: guestOrders.slice(0, 10), // Limit to recent 10
|
|
70
|
+
count: guestOrders.length,
|
|
71
|
+
guest_identifier
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
76
|
+
res.status(401).json({ message: "Unauthorized or invalid token", error: errorMessage });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2d1ZXN0LW9yZGVycy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUlBLGtCQXNGQztBQXpGRCxxREFBcUU7QUFDckUsZ0VBQThDO0FBRXZDLEtBQUssVUFBVSxHQUFHLENBQ3JCLEdBQWtCLEVBQ2xCLEdBQW1CO0lBRW5CLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFBO0lBRTVDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDbkQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUseUNBQXlDLEVBQUUsQ0FBQyxDQUFBO1FBQzVFLE9BQU07SUFDVixDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN0QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSw0QkFBNEIsQ0FBQTtJQUVyRSxJQUFJLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxzQkFBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFlLENBQUE7UUFFdkQsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQTtZQUMxRCxPQUFNO1FBQ1YsQ0FBQztRQUVELE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsR0FBRyxPQUFPLENBQUE7UUFFakQsZ0NB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
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.POST = POST;
|
|
7
|
+
const otp_service_1 = require("../../../../services/otp-service");
|
|
8
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
9
|
+
const template_1 = require("../../../../utils/template");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const otpService = new otp_service_1.OtpService();
|
|
12
|
+
async function POST(req, res) {
|
|
13
|
+
const { email, phone } = req.body;
|
|
14
|
+
if (!email && !phone) {
|
|
15
|
+
res.status(400).json({ message: "Email or phone number is required" });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const identifier = email || phone;
|
|
19
|
+
if (!identifier) {
|
|
20
|
+
res.status(400).json({ message: "Invalid identifier" });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
// Resolve Query to check for registered customers
|
|
25
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
26
|
+
const { data: customers } = await query.graph({
|
|
27
|
+
entity: "customer",
|
|
28
|
+
fields: ["has_account"],
|
|
29
|
+
filters: { email: identifier, has_account: true }
|
|
30
|
+
});
|
|
31
|
+
if (customers.length > 0) {
|
|
32
|
+
res.status(403).json({
|
|
33
|
+
message: "This email is registered. Please log in to view orders.",
|
|
34
|
+
is_registered: true
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const otp = await otpService.generate(identifier);
|
|
39
|
+
// Generate content using template
|
|
40
|
+
const templatePath = path_1.default.join("src", "templates", "emails", "otp-verification-default.html");
|
|
41
|
+
const renderedTemplate = (0, template_1.loadAndRenderTemplate)(templatePath, {
|
|
42
|
+
otp,
|
|
43
|
+
});
|
|
44
|
+
const subject = `Your Verification Code: ${otp}`;
|
|
45
|
+
const expires_in = "15 minutes";
|
|
46
|
+
// Fallback or use rendered content
|
|
47
|
+
const htmlContent = renderedTemplate || `<div style="font-family:sans-serif;padding:20px;"><h2>Verification Code</h2><p>Your code is: <b style="font-size:24px;color:#2563eb;">${otp}</b></p><p>Expires in ${expires_in}.</p></div>`;
|
|
48
|
+
const textContent = `Your verification code is: ${otp}. It expires in ${expires_in}.`;
|
|
49
|
+
try {
|
|
50
|
+
// Resolve Notification Service
|
|
51
|
+
let notificationService = req.scope.resolve(utils_1.Modules.NOTIFICATION, { allowUnregistered: true });
|
|
52
|
+
if (!notificationService) {
|
|
53
|
+
try {
|
|
54
|
+
notificationService = req.scope.resolve("notificationService");
|
|
55
|
+
}
|
|
56
|
+
catch (e) { }
|
|
57
|
+
}
|
|
58
|
+
if (!notificationService) {
|
|
59
|
+
console.error("[OTP Service] No notification service found");
|
|
60
|
+
res.status(200).json({ message: "OTP generated but notification service unavailable" });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Inspect provider if possible
|
|
64
|
+
try {
|
|
65
|
+
const provider = req.scope.resolve("notificationProvider_email", { allowUnregistered: true });
|
|
66
|
+
if (provider) {
|
|
67
|
+
console.log(`[OTP Debug] Email provider detected: ${provider.constructor?.name}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (e) { }
|
|
71
|
+
// EXACT structure from send-order-email.ts
|
|
72
|
+
const payload = {
|
|
73
|
+
to: identifier,
|
|
74
|
+
channel: "email",
|
|
75
|
+
subject: subject,
|
|
76
|
+
html: htmlContent,
|
|
77
|
+
text: textContent,
|
|
78
|
+
body: htmlContent,
|
|
79
|
+
data: {
|
|
80
|
+
subject: subject,
|
|
81
|
+
html: htmlContent,
|
|
82
|
+
text: textContent,
|
|
83
|
+
otp,
|
|
84
|
+
otp_code: otp,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
console.log(`[!!! OTP VERSION 5 !!!] Sending to: ${identifier}. OTP: ${otp}`);
|
|
88
|
+
try {
|
|
89
|
+
if (typeof notificationService.createNotifications === "function") {
|
|
90
|
+
console.log("[OTP Debug] Executing createNotifications");
|
|
91
|
+
await notificationService.createNotifications([payload]);
|
|
92
|
+
}
|
|
93
|
+
else if (typeof notificationService.create === "function") {
|
|
94
|
+
console.log("[OTP Debug] Executing create");
|
|
95
|
+
await notificationService.create(payload);
|
|
96
|
+
}
|
|
97
|
+
else if (typeof notificationService.send === "function") {
|
|
98
|
+
console.log("[OTP Debug] Executing send");
|
|
99
|
+
await notificationService.send("otp-request", {
|
|
100
|
+
to: identifier,
|
|
101
|
+
data: payload.data
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// SMTP Fallback for debugging
|
|
105
|
+
if (process.env.OTP_DEBUG_SMTP === "true") {
|
|
106
|
+
try {
|
|
107
|
+
const nodemailer = require("nodemailer");
|
|
108
|
+
const transporter = nodemailer.createTransport({
|
|
109
|
+
host: process.env.SMTP_HOST,
|
|
110
|
+
port: process.env.SMTP_PORT ? Number(process.env.SMTP_PORT) : undefined,
|
|
111
|
+
secure: process.env.SMTP_SECURE === "true",
|
|
112
|
+
auth: process.env.SMTP_AUTH_USER ? { user: process.env.SMTP_AUTH_USER, pass: process.env.SMTP_AUTH_PASS } : undefined,
|
|
113
|
+
});
|
|
114
|
+
await transporter.sendMail({
|
|
115
|
+
from: process.env.SMTP_FROM || process.env.SMTP_AUTH_USER,
|
|
116
|
+
to: identifier,
|
|
117
|
+
subject: subject,
|
|
118
|
+
html: htmlContent,
|
|
119
|
+
text: textContent,
|
|
120
|
+
});
|
|
121
|
+
console.log("[OTP Debug] SMTP Direct sent");
|
|
122
|
+
}
|
|
123
|
+
catch (sErr) { }
|
|
124
|
+
}
|
|
125
|
+
console.log(`[!!! OTP VERSION 5 !!!] Completed for ${identifier}.`);
|
|
126
|
+
}
|
|
127
|
+
catch (sendError) {
|
|
128
|
+
console.error(`[OTP Service] Send failed: ${sendError}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (notifError) {
|
|
132
|
+
console.error(`[OTP Service] Notif error: ${notifError}`);
|
|
133
|
+
}
|
|
134
|
+
res.status(200).json({ message: "OTP sent successfully" });
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
138
|
+
res.status(500).json({ message: "Failed to generate OTP", error: errorMessage });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL290cC9yZXF1ZXN0L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBUUEsb0JBMklDO0FBbEpELGtFQUE2RDtBQUM3RCxxREFBOEU7QUFDOUUseURBQWtFO0FBQ2xFLGdEQUF1QjtBQUV2QixNQUFNLFVBQVUsR0FBRyxJQUFJLHdCQUFVLEVBQUUsQ0FBQTtBQUU1QixLQUFLLFVBQVUsSUFBSSxDQUN0QixHQUFrQixFQUNsQixHQUFtQjtJQUVuQixNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUEwQyxDQUFBO0lBRXZFLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxtQ0FBbUMsRUFBRSxDQUFDLENBQUE7UUFDdEUsT0FBTTtJQUNWLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxLQUFLLElBQUksS0FBSyxDQUFBO0lBQ2pDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNkLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLENBQUMsQ0FBQTtRQUN2RCxPQUFNO0lBQ1YsQ0FBQztJQUVELElBQUksQ0FBQztRQUNELGtEQUFrRDtRQUNsRCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNoRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztZQUMxQyxNQUFNLEVBQUUsVUFBVTtZQUNsQixNQUFNLEVBQUUs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
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const otp_service_1 = require("../../../../services/otp-service");
|
|
6
|
+
const otpService = new otp_service_1.OtpService();
|
|
7
|
+
async function POST(req, res) {
|
|
8
|
+
const { email, phone, otp } = req.body;
|
|
9
|
+
if ((!email && !phone) || !otp) {
|
|
10
|
+
res.status(400).json({ message: "Email/Phone and OTP are required" });
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const identifier = email || phone;
|
|
14
|
+
if (!identifier) {
|
|
15
|
+
res.status(400).json({ message: "Invalid identifier" });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const isValid = await otpService.verify(identifier, otp);
|
|
20
|
+
if (!isValid) {
|
|
21
|
+
res.status(401).json({ message: "Invalid or expired OTP" });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Fetch the guest customer ID to include in the token
|
|
25
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
26
|
+
const { data: customers } = await query.graph({
|
|
27
|
+
entity: "customer",
|
|
28
|
+
fields: ["id"],
|
|
29
|
+
filters: {
|
|
30
|
+
email: identifier,
|
|
31
|
+
has_account: false
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const customerId = customers.length > 0 ? customers[0].id : undefined;
|
|
35
|
+
const token = otpService.generateToken(identifier, customerId);
|
|
36
|
+
res.status(200).json({
|
|
37
|
+
message: "OTP verified successfully",
|
|
38
|
+
token,
|
|
39
|
+
customer_id: customerId
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
44
|
+
res.status(500).json({ message: "Failed to verify OTP", error: errorMessage });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL290cC92ZXJpZnkvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFNQSxvQkFpREM7QUF0REQscURBQXFFO0FBQ3JFLGtFQUE2RDtBQUU3RCxNQUFNLFVBQVUsR0FBRyxJQUFJLHdCQUFVLEVBQUUsQ0FBQTtBQUU1QixLQUFLLFVBQVUsSUFBSSxDQUN0QixHQUFrQixFQUNsQixHQUFtQjtJQUVuQixNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUMsSUFBdUQsQ0FBQTtJQUV6RixJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzdCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLGtDQUFrQyxFQUFFLENBQUMsQ0FBQTtRQUNyRSxPQUFNO0lBQ1YsQ0FBQztJQUVELE1BQU0sVUFBVSxHQUFHLEtBQUssSUFBSSxLQUFLLENBQUE7SUFFakMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFBO1FBQ3ZELE9BQU07SUFDVixDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsTUFBTSxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQTtRQUV4RCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDWCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxDQUFDLENBQUE7WUFDM0QsT0FBTTtRQUNWLENBQUM7UUFFRCxzREFBc0Q7UUFDdEQsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDaEUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7WUFDMUMsTUFBTSxFQUFFLFVBQVU7WUFDbEIsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ2QsT0FBTyxFQUFFO2dCQUNMLEtBQUssRUFBRSxVQUFVO2dCQUNqQixXQUFXLEVBQUUsS0FBSzthQUNyQjtTQUNKLENBQUMsQ0FBQTtRQUVGLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7UUFDckUsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUE7UUFFOUQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDakIsT0FBTyxFQUFFLDJCQUEyQjtZQUNwQyxLQUFLO1lBQ0wsV0FBVyxFQUFFLFVBQVU7U0FDMUIsQ0FBQyxDQUFBO0lBQ04sQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDYixNQUFNLFlBQVksR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUE7UUFDN0UsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUE7SUFDbEYsQ0FBQztBQUNMLENBQUMifQ==
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OtpService = void 0;
|
|
7
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
+
// In-memory store for OTPs.
|
|
9
|
+
// NOTE: In a real production environment with multiple server instances,
|
|
10
|
+
// this should be replaced with Redis or a database table.
|
|
11
|
+
const otpStore = new Map();
|
|
12
|
+
class OtpService {
|
|
13
|
+
/**
|
|
14
|
+
* Generates a 6-digit OTP for the given identifier (email/phone).
|
|
15
|
+
* Stores it with a 15-minute expiration.
|
|
16
|
+
*/
|
|
17
|
+
async generate(identifier) {
|
|
18
|
+
const otp = Math.floor(100000 + Math.random() * 900000).toString();
|
|
19
|
+
otpStore.set(identifier, {
|
|
20
|
+
otp,
|
|
21
|
+
expiresAt: Date.now() + 15 * 60 * 1000, // 15 minutes
|
|
22
|
+
});
|
|
23
|
+
return otp;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Verifies the OTP for the given identifier.
|
|
27
|
+
* key feature: Deletes the OTP upon successful verification to prevent replay.
|
|
28
|
+
*/
|
|
29
|
+
async verify(identifier, code) {
|
|
30
|
+
const data = otpStore.get(identifier);
|
|
31
|
+
if (!data) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (Date.now() > data.expiresAt) {
|
|
35
|
+
otpStore.delete(identifier);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (data.otp !== code) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
// OTP is valid, consume it
|
|
42
|
+
otpStore.delete(identifier);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generates a JWT token scoped for guest access.
|
|
47
|
+
*/
|
|
48
|
+
generateToken(identifier, customerId) {
|
|
49
|
+
// In production, use a secure secret from environment variables
|
|
50
|
+
const secret = process.env.JWT_SECRET || "medusa-secret-guest-access";
|
|
51
|
+
return jsonwebtoken_1.default.sign({
|
|
52
|
+
guest_identifier: identifier,
|
|
53
|
+
customer_id: customerId,
|
|
54
|
+
scope: "guest_orders"
|
|
55
|
+
}, secret, { expiresIn: "1h" });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.OtpService = OtpService;
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvb3RwLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0VBQThCO0FBRTlCLDZCQUE2QjtBQUM3QiwwRUFBMEU7QUFDMUUsMERBQTBEO0FBQzFELE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUE4QyxDQUFBO0FBRXRFLE1BQWEsVUFBVTtJQUNuQjs7O09BR0c7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUFDLFVBQWtCO1FBQzdCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQTtRQUVsRSxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRTtZQUNyQixHQUFHO1lBQ0gsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksRUFBRSxhQUFhO1NBQ3hELENBQUMsQ0FBQTtRQUVGLE9BQU8sR0FBRyxDQUFBO0lBQ2QsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBa0IsRUFBRSxJQUFZO1FBQ3pDLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFckMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1IsT0FBTyxLQUFLLENBQUE7UUFDaEIsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUM5QixRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzNCLE9BQU8sS0FBSyxDQUFBO1FBQ2hCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDcEIsT0FBTyxLQUFLLENBQUE7UUFDaEIsQ0FBQztRQUVELDJCQUEyQjtRQUMzQixRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQzNCLE9BQU8sSUFBSSxDQUFBO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUFDLFVBQWtCLEVBQUUsVUFBbUI7UUFDakQsZ0VBQWdFO1FBQ2hFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLDRCQUE0QixDQUFBO1FBRXJFLE9BQU8sc0JBQUcsQ0FBQyxJQUFJLENBQ1g7WUFDSSxnQkFBZ0IsRUFBRSxVQUFVO1lBQzVCLFdBQVcsRUFBRSxVQUFVO1lBQ3ZCLEtBQUssRUFBRSxjQUFjO1NBQ3hCLEVBQ0QsTUFBTSxFQUNOLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUN0QixDQUFBO0lBQ0wsQ0FBQztDQUNKO0FBMURELGdDQTBEQyJ9
|
|
@@ -22,7 +22,10 @@ function prepareEmailPayload(to, subject, htmlContent) {
|
|
|
22
22
|
html: htmlContent,
|
|
23
23
|
text: textContent,
|
|
24
24
|
body: htmlContent, // Some providers expect 'body' field
|
|
25
|
-
|
|
25
|
+
// NOTE: We intentionally do NOT set `template` to raw HTML here. Some
|
|
26
|
+
// notification providers interpret `template` as a template identifier and
|
|
27
|
+
// may switch to template-based sending which can ignore or strip content.
|
|
28
|
+
// Omit `template` when sending raw HTML content.
|
|
26
29
|
data: {
|
|
27
30
|
subject,
|
|
28
31
|
html: htmlContent,
|
|
@@ -106,6 +109,16 @@ async function sendOrderEmailHandler({ event: { data }, container, }) {
|
|
|
106
109
|
: typeof totalValue === "string"
|
|
107
110
|
? totalValue
|
|
108
111
|
: "N/A";
|
|
112
|
+
// Check if the email belongs to a registered customer
|
|
113
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
114
|
+
const { data: customers } = await query.graph({
|
|
115
|
+
entity: "customer",
|
|
116
|
+
fields: ["has_account"],
|
|
117
|
+
filters: { email: email, has_account: true }
|
|
118
|
+
});
|
|
119
|
+
const isRegistered = customers.length > 0;
|
|
120
|
+
const storefrontUrl = process.env.STOREFRONT_URL || "http://localhost:8000";
|
|
121
|
+
const claimLink = `${storefrontUrl}/account/orders/claim?order_id=${orderData.id}`;
|
|
109
122
|
const templateData = {
|
|
110
123
|
order_id: orderData.id || "N/A",
|
|
111
124
|
order_status: orderData.status || "N/A",
|
|
@@ -115,6 +128,9 @@ async function sendOrderEmailHandler({ event: { data }, container, }) {
|
|
|
115
128
|
order_items: orderData.items || [],
|
|
116
129
|
shipping_address: orderData.shipping_address || {},
|
|
117
130
|
billing_address: orderData.billing_address || {},
|
|
131
|
+
// Security/User Context
|
|
132
|
+
is_registered: isRegistered,
|
|
133
|
+
claim_link: isRegistered ? claimLink : undefined,
|
|
118
134
|
};
|
|
119
135
|
// Load and render template
|
|
120
136
|
const renderedTemplate = (0, template_1.loadAndRenderTemplate)(templatePath, templateData);
|
|
@@ -131,15 +147,99 @@ async function sendOrderEmailHandler({ event: { data }, container, }) {
|
|
|
131
147
|
// Prepare email payload
|
|
132
148
|
const subject = "Order Confirmation";
|
|
133
149
|
const payload = prepareEmailPayload(email, subject, renderedTemplate);
|
|
134
|
-
//
|
|
150
|
+
// Diagnostic summary & send email
|
|
151
|
+
console.log(`[Order Email Subscriber] Payload keys: ${Object.keys(payload).join(", ")} ; templatePresent=${payload.template ? 'yes' : 'no'}`);
|
|
135
152
|
try {
|
|
136
153
|
if (typeof notificationService.createNotifications === "function") {
|
|
137
|
-
|
|
154
|
+
console.log(`[Order Email Subscriber] Using createNotifications to send email`);
|
|
155
|
+
const res = await notificationService.createNotifications([payload]);
|
|
156
|
+
try {
|
|
157
|
+
console.log(`[Order Email Subscriber] createNotifications response: ${JSON.stringify(res)}`);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
console.log(`[Order Email Subscriber] createNotifications response: <non-serializable>`);
|
|
161
|
+
}
|
|
138
162
|
console.log(`[Order Email Subscriber] Email sent successfully for order ${orderId}`);
|
|
163
|
+
// Optional SMTP fallback for debugging/delivery verification. Enable by
|
|
164
|
+
// setting FORCE_SMTP_REDELIVER=true. This attempts a direct Nodemailer
|
|
165
|
+
// send using SMTP env vars and logs the SMTP response (messageId, accepted, etc.).
|
|
166
|
+
if (process.env.FORCE_SMTP_REDELIVER === "true") {
|
|
167
|
+
try {
|
|
168
|
+
console.log("[Order Email Subscriber] SMTP fallback enabled - attempting direct send via Nodemailer");
|
|
169
|
+
// @ts-ignore - optional dependency
|
|
170
|
+
const nodemailer = require("nodemailer");
|
|
171
|
+
const transportOpts = {
|
|
172
|
+
host: process.env.SMTP_HOST,
|
|
173
|
+
port: process.env.SMTP_PORT ? Number(process.env.SMTP_PORT) : undefined,
|
|
174
|
+
secure: process.env.SMTP_SECURE === "true",
|
|
175
|
+
auth: process.env.SMTP_AUTH_USER ? { user: process.env.SMTP_AUTH_USER, pass: process.env.SMTP_AUTH_PASS } : undefined,
|
|
176
|
+
logger: true,
|
|
177
|
+
debug: true,
|
|
178
|
+
};
|
|
179
|
+
const transporter = nodemailer.createTransport(transportOpts);
|
|
180
|
+
const mailOptions = {
|
|
181
|
+
from: process.env.SMTP_FROM || process.env.SMTP_AUTH_USER,
|
|
182
|
+
to: payload.to,
|
|
183
|
+
subject: payload.subject,
|
|
184
|
+
html: payload.html,
|
|
185
|
+
text: payload.text,
|
|
186
|
+
};
|
|
187
|
+
const sendRes = await transporter.sendMail(mailOptions);
|
|
188
|
+
try {
|
|
189
|
+
console.log(`[Order Email Subscriber] SMTP fallback sendMail response: ${JSON.stringify(sendRes)}`);
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
console.log(`[Order Email Subscriber] SMTP fallback sendMail response: <non-serializable>`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
console.error("[Order Email Subscriber] SMTP fallback failed:", err instanceof Error ? err.message : String(err));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
139
199
|
}
|
|
140
200
|
else if (typeof notificationService.create === "function") {
|
|
141
|
-
|
|
201
|
+
console.log(`[Order Email Subscriber] Using create to send email`);
|
|
202
|
+
const res = await notificationService.create(payload);
|
|
203
|
+
try {
|
|
204
|
+
console.log(`[Order Email Subscriber] create response: ${JSON.stringify(res)}`);
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
console.log(`[Order Email Subscriber] create response: <non-serializable>`);
|
|
208
|
+
}
|
|
142
209
|
console.log(`[Order Email Subscriber] Email sent successfully for order ${orderId}`);
|
|
210
|
+
if (process.env.FORCE_SMTP_REDELIVER === "true") {
|
|
211
|
+
try {
|
|
212
|
+
console.log("[Order Email Subscriber] SMTP fallback enabled - attempting direct send via Nodemailer");
|
|
213
|
+
// @ts-ignore - optional dependency
|
|
214
|
+
const nodemailer = require("nodemailer");
|
|
215
|
+
const transportOpts = {
|
|
216
|
+
host: process.env.SMTP_HOST,
|
|
217
|
+
port: process.env.SMTP_PORT ? Number(process.env.SMTP_PORT) : undefined,
|
|
218
|
+
secure: process.env.SMTP_SECURE === "true",
|
|
219
|
+
auth: process.env.SMTP_AUTH_USER ? { user: process.env.SMTP_AUTH_USER, pass: process.env.SMTP_AUTH_PASS } : undefined,
|
|
220
|
+
logger: true,
|
|
221
|
+
debug: true,
|
|
222
|
+
};
|
|
223
|
+
const transporter = nodemailer.createTransport(transportOpts);
|
|
224
|
+
const mailOptions = {
|
|
225
|
+
from: process.env.SMTP_FROM || process.env.SMTP_AUTH_USER,
|
|
226
|
+
to: payload.to,
|
|
227
|
+
subject: payload.subject,
|
|
228
|
+
html: payload.html,
|
|
229
|
+
text: payload.text,
|
|
230
|
+
};
|
|
231
|
+
const sendRes = await transporter.sendMail(mailOptions);
|
|
232
|
+
try {
|
|
233
|
+
console.log(`[Order Email Subscriber] SMTP fallback sendMail response: ${JSON.stringify(sendRes)}`);
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
console.log(`[Order Email Subscriber] SMTP fallback sendMail response: <non-serializable>`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
console.error("[Order Email Subscriber] SMTP fallback failed:", err instanceof Error ? err.message : String(err));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
143
243
|
}
|
|
144
244
|
else {
|
|
145
245
|
console.error("[Order Email Subscriber] Notification service does not support sending notifications");
|
|
@@ -163,4 +263,4 @@ async function sendOrderEmailHandler({ event: { data }, container, }) {
|
|
|
163
263
|
exports.config = {
|
|
164
264
|
event: "order.placed",
|
|
165
265
|
};
|
|
166
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1vcmRlci1lbWFpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9zZW5kLW9yZGVyLWVtYWlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWdFQSx3Q0FnSkM7QUEvTUQscURBQThFO0FBRTlFLDhEQUdpQztBQUNqQyxnREFBaUY7QUFPakY7O0dBRUc7QUFDSCxTQUFTLG1CQUFtQixDQUMxQixFQUFVLEVBQ1YsT0FBZSxFQUNmLFdBQW1CO0lBRW5CLHNDQUFzQztJQUN0QyxNQUFNLFdBQVcsR0FBRyxXQUFXO1NBQzVCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsbUJBQW1CO1NBQzNDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsc0JBQXNCO1NBQzNDLElBQUksRUFBRSxDQUFBO0lBRVQsTUFBTSxPQUFPLEdBYVQ7UUFDRixFQUFFO1FBQ0YsT0FBTyxFQUFFLE9BQU87UUFDaEIsT0FBTztRQUNQLHVDQUF1QztRQUN2QyxJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsV0FBVyxFQUFFLHFDQUFxQztRQUN4RCxRQUFRLEVBQUUsV0FBVyxFQUFFLHlDQUF5QztRQUNoRSxJQUFJLEVBQUU7WUFDSixPQUFPO1lBQ1AsSUFBSSxFQUFFLFdBQVc7WUFDakIsSUFBSSxFQUFFLFdBQVc7U0FDbEI7S0FDRixDQUFBO0lBRUQsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQztBQUVEOzs7R0FHRztBQUNZLEtBQUssVUFBVSxxQkFBcUIsQ0FBQyxFQUNsRCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFDZixTQUFTLEdBQzRCO0lBQ3JDLElBQUksQ0FBQztRQUNILHdDQUF3QztRQUN4QyxJQUFJLFlBQVksR0FBa0IsSUFBSSxDQUFBO1FBQ3RDLElBQUksQ0FBQztZQUNILE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FB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
|
|
266
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1vcmRlci1lbWFpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9zZW5kLW9yZGVyLWVtYWlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQW1FQSx3Q0E4TkM7QUFoU0QscURBQThFO0FBRTlFLDhEQUdpQztBQUNqQyxnREFBaUY7QUFPakY7O0dBRUc7QUFDSCxTQUFTLG1CQUFtQixDQUMxQixFQUFVLEVBQ1YsT0FBZSxFQUNmLFdBQW1CO0lBRW5CLHNDQUFzQztJQUN0QyxNQUFNLFdBQVcsR0FBRyxXQUFXO1NBQzVCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsbUJBQW1CO1NBQzNDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsc0JBQXNCO1NBQzNDLElBQUksRUFBRSxDQUFBO0lBRVQsTUFBTSxPQUFPLEdBYVQ7UUFDRixFQUFFO1FBQ0YsT0FBTyxFQUFFLE9BQU87UUFDaEIsT0FBTztRQUNQLHVDQUF1QztRQUN2QyxJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsV0FBVyxFQUFFLHFDQUFxQztRQUN4RCxzRUFBc0U7UUFDdEUsMkVBQTJFO1FBQzNFLDBFQUEwRTtRQUMxRSxpREFBaUQ7UUFDakQsSUFBSSxFQUFFO1lBQ0osT0FBTztZQUNQLElBQUksRUFBRSxXQUFXO1lBQ2pCLElBQUksRUFBRSxXQUFXO1NBQ2xCO0tBQ0YsQ0FBQTtJQUVELE9BQU8sT0FBTyxDQUFBO0FBQ2hCLENBQUM7QUFFRDs7O0dBR0c7QUFDWSxLQUFLLFVBQVUscUJBQXFCLENBQUMsRUFDbEQsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQ2YsU0FBUyxHQUM0QjtJQUNyQyxJQUFJLENBQUM7UUFDSCx3Q0FBd0M7UUFDeEMsSUFBSSxZQUFZLEdBQWtCLElBQUksQ0FBQTtRQUN0QyxJQUFJLENBQUM7WUFDSCxNQUFN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
|
package/README.md
CHANGED
|
@@ -39,8 +39,10 @@ This starter is compatible with versions >= 2.4.0 of `@medusajs/medusa`.
|
|
|
39
39
|
## Features
|
|
40
40
|
|
|
41
41
|
- **Order Management**: Cancel and reorder functionality for orders
|
|
42
|
-
- **Order
|
|
42
|
+
- **Guest Order Portal**: Complete look-up system for guest users (OTP-based)
|
|
43
|
+
- **Order Confirmation Emails**: Automatically sends email notifications when orders are placed (with "Claim Order" support for registered users)
|
|
43
44
|
- **Return Orders Admin Panel**: Complete return orders management section in the Medusa Admin Panel with list view, filtering, search, detail pages, and status management
|
|
45
|
+
- **Guest Returns & Invoices**: Secure endpoints for guest users to initiate returns and download invoices
|
|
44
46
|
|
|
45
47
|
## Configuration
|
|
46
48
|
|
|
@@ -112,6 +114,29 @@ The plugin supports the following return statuses:
|
|
|
112
114
|
|
|
113
115
|
Status updates are tracked in the return's metadata with timestamps and admin user IDs.
|
|
114
116
|
|
|
117
|
+
## Guest Order Portal
|
|
118
|
+
|
|
119
|
+
The Guest Order Portal allows users who placed orders without an account to view their order status, initiate returns, and download invoices securely via an OTP (One-Time Password) system.
|
|
120
|
+
|
|
121
|
+
### Security Features
|
|
122
|
+
|
|
123
|
+
- **Strict Separation**: Guest orders are strictly filtered by unique guest customer IDs. Registered account orders will never be exposed in the guest portal.
|
|
124
|
+
- **Access Control**: The portal uses short-lived JWT tokens issued upon successful OTP verification.
|
|
125
|
+
- **Account Protection**: Emails belonging to registered accounts are blocked from the guest OTP flow to prevent unauthorized access and encourage secure logins.
|
|
126
|
+
|
|
127
|
+
### Store API Endpoints
|
|
128
|
+
|
|
129
|
+
The plugin provides the following store API endpoints for the Guest Order Portal:
|
|
130
|
+
|
|
131
|
+
- `POST /store/otp/request` - Request an OTP for an email or phone number.
|
|
132
|
+
- `POST /store/otp/verify` - Verify the OTP and receive a guest JWT token.
|
|
133
|
+
- `GET /store/guest-orders` - List summary of orders for the verified guest identifier.
|
|
134
|
+
- `GET /store/guest-orders/:id` - Get full details for a specific guest order (includes items, shipping status, etc.).
|
|
135
|
+
- `POST /store/guest-orders/:id/returns` - Initiate a return request for a guest order.
|
|
136
|
+
- `GET /store/guest-orders/:id/invoice` - Download a PDF invoice for the guest order.
|
|
137
|
+
|
|
138
|
+
**Note**: All `GET` and `POST` requests to guest order endpoints require the JWT token in the `Authorization: Bearer <token>` header.
|
|
139
|
+
|
|
115
140
|
## Email Templates
|
|
116
141
|
|
|
117
142
|
The plugin supports custom HTML templates for order confirmation emails. Templates use variable replacement with `{{variable_name}}` syntax.
|
|
@@ -177,6 +202,8 @@ The following variables are available in order confirmation email templates:
|
|
|
177
202
|
| `{{order_items}}` | Order items array (JSON stringified) | `[{"title":"Product","quantity":1}]` |
|
|
178
203
|
| `{{shipping_address}}` | Shipping address object (JSON stringified) | `{"first_name":"John",...}` |
|
|
179
204
|
| `{{billing_address}}` | Billing address object (JSON stringified) | `{"first_name":"John",...}` |
|
|
205
|
+
| `{{is_registered}}` | Whether the customer email has a registered account | `true` |
|
|
206
|
+
| `{{claim_link}}` | Link for registered users to claim their guest order | `http://.../claim?order_id=...` |
|
|
180
207
|
|
|
181
208
|
## Getting Started
|
|
182
209
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "order-management",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "A starter for Medusa plugins.",
|
|
5
5
|
"author": "Medusa (https://medusajs.com)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,14 +36,16 @@
|
|
|
36
36
|
"@medusajs/admin-sdk": "2.11.2",
|
|
37
37
|
"@medusajs/cli": "2.11.2",
|
|
38
38
|
"@medusajs/framework": "2.11.2",
|
|
39
|
+
"@medusajs/icons": "2.11.2",
|
|
39
40
|
"@medusajs/medusa": "2.11.2",
|
|
40
41
|
"@medusajs/test-utils": "2.11.2",
|
|
41
42
|
"@medusajs/ui": "4.0.25",
|
|
42
|
-
"@medusajs/icons": "2.11.2",
|
|
43
43
|
"@swc/core": "1.5.7",
|
|
44
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
44
45
|
"@types/node": "^20.0.0",
|
|
45
46
|
"@types/react": "^18.3.2",
|
|
46
47
|
"@types/react-dom": "^18.2.25",
|
|
48
|
+
"jsonwebtoken": "^9.0.3",
|
|
47
49
|
"prop-types": "^15.8.1",
|
|
48
50
|
"react": "^18.2.0",
|
|
49
51
|
"react-dom": "^18.2.0",
|
|
@@ -56,10 +58,10 @@
|
|
|
56
58
|
"@medusajs/admin-sdk": "2.11.2",
|
|
57
59
|
"@medusajs/cli": "2.11.2",
|
|
58
60
|
"@medusajs/framework": "2.11.2",
|
|
59
|
-
"@medusajs/
|
|
61
|
+
"@medusajs/icons": "2.11.2",
|
|
60
62
|
"@medusajs/medusa": "2.11.2",
|
|
61
|
-
"@medusajs/
|
|
62
|
-
"@medusajs/
|
|
63
|
+
"@medusajs/test-utils": "2.11.2",
|
|
64
|
+
"@medusajs/ui": "4.0.25"
|
|
63
65
|
},
|
|
64
66
|
"engines": {
|
|
65
67
|
"node": ">=20"
|