customer-registration 0.0.111 → 0.0.113
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/admin/index.js +3249 -2
- package/.medusa/server/src/admin/index.mjs +3232 -2
- package/.medusa/server/src/api/admin/account-deletion-requests/route.js +30 -0
- package/.medusa/server/src/api/admin/account-deletion-requests/validators.js +12 -0
- package/.medusa/server/src/api/auth/customer/emailpass/reset-password/route.js +1 -26
- package/.medusa/server/src/api/auth/customer/emailpass/route.js +24 -97
- package/.medusa/server/src/api/auth/customer/phonepass/register/route.js +50 -0
- package/.medusa/server/src/api/auth/customer/phonepass/route.js +105 -0
- package/.medusa/server/src/api/middlewares/guard-account-deletion.js +29 -0
- package/.medusa/server/src/api/middlewares/ip-rate-limit.js +48 -0
- package/.medusa/server/src/api/middlewares/validate-customer-registration.js +60 -0
- package/.medusa/server/src/api/middlewares.js +30 -0
- package/.medusa/server/src/api/store/customers/account-deletion/cancel-confirm/route.js +36 -0
- package/.medusa/server/src/api/store/customers/account-deletion/cancel-request/route.js +55 -0
- package/.medusa/server/src/api/store/customers/account-deletion/confirm/route.js +43 -0
- package/.medusa/server/src/api/store/customers/account-deletion/request/route.js +40 -0
- package/.medusa/server/src/api/store/customers/account-deletion/validators.js +27 -0
- package/.medusa/server/src/api/store/customers/me/contact/route.js +95 -0
- package/.medusa/server/src/api/store/customers/me/contact/verify/route.js +83 -0
- package/.medusa/server/src/api/store/customers/me/route.js +53 -0
- package/.medusa/server/src/api/store/customers/otp/send/route.js +1 -6
- package/.medusa/server/src/api/store/customers/otp/verify/route.js +95 -3
- package/.medusa/server/src/api/store/customers/route.js +89 -0
- package/.medusa/server/src/config.js +44 -13
- package/.medusa/server/src/jobs/process-account-deletions.js +69 -0
- package/.medusa/server/src/modules/account-deletion-request/index.js +17 -0
- package/.medusa/server/src/modules/account-deletion-request/migrations/Migration20250221000000CreateAccountDeletionRequestTable.js +42 -0
- package/.medusa/server/src/modules/account-deletion-request/migrations/Migration20250221100000AddCompletedStatusToAccountDeletionRequest.js +30 -0
- package/.medusa/server/src/modules/account-deletion-request/models/account-deletion-request.js +26 -0
- package/.medusa/server/src/modules/account-deletion-request/service.js +90 -0
- package/.medusa/server/src/modules/otp-verification/migrations/Migration20250221000000AddAccountDeletionOtpPurposes.js +35 -0
- package/.medusa/server/src/modules/otp-verification/models/otp-verification.js +9 -2
- package/.medusa/server/src/modules/otp-verification/service.js +79 -1
- package/.medusa/server/src/providers/phonepass/index.js +9 -0
- package/.medusa/server/src/providers/phonepass/service.js +133 -0
- package/.medusa/server/src/subscribers/password-reset.js +1 -42
- package/.medusa/server/src/workflows/change-password.js +40 -64
- package/.medusa/server/src/workflows/send-contact-change-otp-workflow.js +41 -0
- package/.medusa/server/src/workflows/steps/determine-contact-method-step.js +8 -2
- package/.medusa/server/src/workflows/steps/generate-contact-change-otp-step.js +24 -0
- package/.medusa/server/src/workflows/steps/index.js +6 -2
- package/.medusa/server/src/workflows/steps/resolve-channel-config-step.js +10 -1
- package/.medusa/server/src/workflows/steps/send-notification-step.js +1 -11
- package/.medusa/server/src/workflows/steps/sync-phonepass-entity-id-step.js +63 -0
- package/.medusa/server/src/workflows/steps/update-password-step.js +21 -29
- package/.medusa/server/src/workflows/update-contact-workflow.js +100 -0
- package/.medusa/server/src/workflows/verify-phone.js +11 -4
- package/README.md +389 -147
- package/package.json +12 -3
- package/.medusa/server/src/subscribers/customer-updated.js +0 -100
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const account_deletion_request_1 = require("../../../modules/account-deletion-request");
|
|
5
|
+
const validators_1 = require("./validators");
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const query = validators_1.AdminListAccountDeletionRequestsSchema.parse(req.query ?? {});
|
|
8
|
+
const service = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
9
|
+
const selector = {};
|
|
10
|
+
if (query.status) {
|
|
11
|
+
selector.status = query.status;
|
|
12
|
+
}
|
|
13
|
+
const order = {
|
|
14
|
+
[query.order ?? "created_at"]: (query.order_direction ??
|
|
15
|
+
"DESC"),
|
|
16
|
+
};
|
|
17
|
+
const { requests, count } = await service.listForAdmin(selector, {
|
|
18
|
+
take: query.limit,
|
|
19
|
+
skip: query.offset,
|
|
20
|
+
order,
|
|
21
|
+
});
|
|
22
|
+
res.status(200).json({
|
|
23
|
+
requests,
|
|
24
|
+
count,
|
|
25
|
+
offset: query.offset,
|
|
26
|
+
limit: query.limit,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
exports.GET = GET;
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FjY291bnQtZGVsZXRpb24tcmVxdWVzdHMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0Esd0ZBQTJGO0FBRTNGLDZDQUFxRTtBQUU5RCxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDbkUsTUFBTSxLQUFLLEdBQUcsbURBQXNDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUE7SUFFM0UsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQy9CLDBEQUErQixDQUNoQyxDQUFBO0lBRUQsTUFBTSxRQUFRLEdBQTRCLEVBQUUsQ0FBQTtJQUM1QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNqQixRQUFRLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUE7SUFDaEMsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHO1FBQ1osQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLFlBQVksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLGVBQWU7WUFDbkQsTUFBTSxDQUFtQjtLQUM1QixDQUFBO0lBRUQsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFO1FBQy9ELElBQUksRUFBRSxLQUFLLENBQUMsS0FBSztRQUNqQixJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU07UUFDbEIsS0FBSztLQUNOLENBQUMsQ0FBQTtJQUVGLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ25CLFFBQVE7UUFDUixLQUFLO1FBQ0wsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO1FBQ3BCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztLQUNuQixDQUFDLENBQUE7QUFDSixDQUFDLENBQUE7QUE3QlksUUFBQSxHQUFHLE9BNkJmIn0=
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdminListAccountDeletionRequestsSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.AdminListAccountDeletionRequestsSchema = zod_1.z.object({
|
|
6
|
+
status: zod_1.z.enum(["pending", "confirmed", "cancelled", "completed"]).optional(),
|
|
7
|
+
limit: zod_1.z.coerce.number().int().positive().max(100).default(20),
|
|
8
|
+
offset: zod_1.z.coerce.number().int().nonnegative().default(0),
|
|
9
|
+
order: zod_1.z.enum(["created_at", "updated_at", "customer_id"]).optional(),
|
|
10
|
+
order_direction: zod_1.z.enum(["ASC", "DESC"]).default("DESC"),
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYWRtaW4vYWNjb3VudC1kZWxldGlvbi1yZXF1ZXN0cy92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUF1QjtBQUVWLFFBQUEsc0NBQXNDLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM3RCxNQUFNLEVBQUUsT0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQzdFLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO0lBQzlELE1BQU0sRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDeEQsS0FBSyxFQUFFLE9BQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO0lBQ3JFLGVBQWUsRUFBRSxPQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztDQUN6RCxDQUFDLENBQUEifQ==
|
|
@@ -24,7 +24,6 @@ function htmlToPlainText(html) {
|
|
|
24
24
|
* Send password reset email using notification service
|
|
25
25
|
*/
|
|
26
26
|
async function sendPasswordResetEmail(email, token, resetUrl, templatePath, subject, container) {
|
|
27
|
-
console.log("[reset-password] Sending password reset email directly...");
|
|
28
27
|
const notificationService = container.resolve(utils_1.Modules.NOTIFICATION);
|
|
29
28
|
if (!notificationService) {
|
|
30
29
|
console.error("[reset-password] Notification service is not configured");
|
|
@@ -61,41 +60,18 @@ async function sendPasswordResetEmail(email, token, resetUrl, templatePath, subj
|
|
|
61
60
|
template: htmlContent, // Some providers expect 'template' field
|
|
62
61
|
subject, // Include subject at root level too
|
|
63
62
|
};
|
|
64
|
-
// Log payload structure (sanitized for security)
|
|
65
|
-
console.log("[reset-password] Email payload structure:", {
|
|
66
|
-
to: payload.to,
|
|
67
|
-
channel: payload.channel,
|
|
68
|
-
subject: payload.subject,
|
|
69
|
-
hasHtml: !!payload.html,
|
|
70
|
-
hasText: !!payload.text,
|
|
71
|
-
hasBody: !!payload.body,
|
|
72
|
-
hasTemplate: !!payload.template,
|
|
73
|
-
dataKeys: Object.keys(payload.data || {}),
|
|
74
|
-
htmlLength: payload.html?.length || 0,
|
|
75
|
-
textLength: payload.text?.length || 0,
|
|
76
|
-
});
|
|
77
63
|
try {
|
|
78
64
|
if (typeof notificationService.create === "function") {
|
|
79
|
-
console.log("[reset-password] Using notificationService.create method");
|
|
80
65
|
await notificationService.create(payload);
|
|
81
|
-
console.log(`[reset-password] ✓ Password reset email sent successfully to ${email}`);
|
|
82
66
|
}
|
|
83
67
|
else if (typeof notificationService.createNotifications === "function") {
|
|
84
|
-
console.log("[reset-password] Using notificationService.createNotifications method");
|
|
85
68
|
await notificationService.createNotifications([payload]);
|
|
86
|
-
console.log(`[reset-password] ✓ Password reset email sent successfully to ${email}`);
|
|
87
69
|
}
|
|
88
70
|
else {
|
|
89
|
-
console.error("[reset-password] Notification service does not support sending notifications");
|
|
90
71
|
}
|
|
91
72
|
}
|
|
92
73
|
catch (error) {
|
|
93
|
-
console.error(`[reset-password] Failed to send password reset email to ${email}:`, error);
|
|
94
74
|
if (error instanceof Error) {
|
|
95
|
-
console.error("[reset-password] Error details:", {
|
|
96
|
-
message: error.message,
|
|
97
|
-
stack: error.stack,
|
|
98
|
-
});
|
|
99
75
|
}
|
|
100
76
|
throw error;
|
|
101
77
|
}
|
|
@@ -187,7 +163,6 @@ const POST = async (req, res) => {
|
|
|
187
163
|
await sendPasswordResetEmail(normalizedEmail, resetToken, resetUrl || "", pluginOptions.password_reset.template, pluginOptions.password_reset.subject, req.scope);
|
|
188
164
|
}
|
|
189
165
|
catch (emailError) {
|
|
190
|
-
console.error("[reset-password] Failed to send email:", emailError);
|
|
191
166
|
// Continue anyway - don't reveal if email exists
|
|
192
167
|
}
|
|
193
168
|
// Return 201 (Created) to match Medusa's built-in route response
|
|
@@ -201,4 +176,4 @@ const POST = async (req, res) => {
|
|
|
201
176
|
}
|
|
202
177
|
};
|
|
203
178
|
exports.POST = POST;
|
|
204
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
179
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvZW1haWxwYXNzL3Jlc2V0LXBhc3N3b3JkL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUEyRjtBQUUzRiwyRkFBb0c7QUFDcEcsOEVBQStFO0FBQy9FLGtEQUc4QjtBQUU5Qjs7R0FFRztBQUNILFNBQVMsZUFBZSxDQUFDLElBQVk7SUFDbkMsT0FBTyxJQUFJO1NBQ1IsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxtQkFBbUI7U0FDM0MsT0FBTyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQyw0QkFBNEI7U0FDcEQsT0FBTyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyx1QkFBdUI7U0FDOUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxzQkFBc0I7U0FDNUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxzQkFBc0I7U0FDNUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQyx3QkFBd0I7U0FDaEQsT0FBTyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyx1QkFBdUI7U0FDOUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQyw2QkFBNkI7U0FDekQsSUFBSSxFQUFFLENBQUE7QUFDWCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsc0JBQXNCLENBQ25DLEtBQWEsRUFDYixLQUFhLEVBQ2IsUUFBZ0IsRUFDaEIsWUFBb0IsRUFDcEIsT0FBZSxFQUNmLFNBQWM7SUFHZCxNQUFNLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLFlBQVksQ0FHakUsQ0FBQTtJQUVELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sQ0FBQyxL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
|
|
@@ -3,15 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.POST = exports.GET = void 0;
|
|
4
4
|
const utils_1 = require("@medusajs/framework/utils");
|
|
5
5
|
const generate_jwt_token_1 = require("@medusajs/medusa/api/auth/utils/generate-jwt-token");
|
|
6
|
+
const account_deletion_request_1 = require("../../../../modules/account-deletion-request");
|
|
6
7
|
const otp_verification_1 = require("../../../../modules/otp-verification");
|
|
8
|
+
const config_1 = require("../../../../config");
|
|
7
9
|
const GET = async (req, res) => {
|
|
8
|
-
console.log("[emailpass-auth] Authentication request received", {
|
|
9
|
-
method: req.method,
|
|
10
|
-
url: req.url,
|
|
11
|
-
hasBody: !!req.body,
|
|
12
|
-
hasQuery: !!req.query,
|
|
13
|
-
});
|
|
14
10
|
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
11
|
+
const loginOptions = (0, config_1.resolveCustomerRegistrationOptions)(config);
|
|
12
|
+
if (loginOptions.login.identifier === "phone") {
|
|
13
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Email login is not enabled. Please log in with your phone number.");
|
|
14
|
+
}
|
|
15
15
|
const service = req.scope.resolve(utils_1.Modules.AUTH);
|
|
16
16
|
const authData = {
|
|
17
17
|
url: req.url,
|
|
@@ -21,28 +21,11 @@ const GET = async (req, res) => {
|
|
|
21
21
|
protocol: req.protocol,
|
|
22
22
|
};
|
|
23
23
|
const { success, error, authIdentity, location } = await service.authenticate("emailpass", authData);
|
|
24
|
-
console.log("[emailpass-auth] Authentication result", {
|
|
25
|
-
success,
|
|
26
|
-
hasError: !!error,
|
|
27
|
-
error,
|
|
28
|
-
hasAuthIdentity: !!authIdentity,
|
|
29
|
-
authIdentityId: authIdentity?.id,
|
|
30
|
-
hasLocation: !!location,
|
|
31
|
-
});
|
|
32
24
|
if (location) {
|
|
33
|
-
console.log("[emailpass-auth] Redirecting to location", { location });
|
|
34
25
|
return res.status(200).json({ location });
|
|
35
26
|
}
|
|
36
27
|
if (success && authIdentity) {
|
|
37
28
|
const email = authIdentity.provider_identities?.[0]?.entity_id ?? "";
|
|
38
|
-
console.log("[emailpass-auth] Processing successful authentication", {
|
|
39
|
-
email,
|
|
40
|
-
authIdentityId: authIdentity.id,
|
|
41
|
-
hasProviderIdentities: !!authIdentity.provider_identities,
|
|
42
|
-
providerIdentitiesCount: authIdentity.provider_identities?.length || 0,
|
|
43
|
-
hasAppMetadata: !!authIdentity.app_metadata,
|
|
44
|
-
appMetadataCustomerId: authIdentity.app_metadata?.customer_id,
|
|
45
|
-
});
|
|
46
29
|
await enforceEmailAndPhoneVerification({
|
|
47
30
|
email,
|
|
48
31
|
req,
|
|
@@ -50,39 +33,24 @@ const GET = async (req, res) => {
|
|
|
50
33
|
// Ensure authIdentity has customer_id in app_metadata
|
|
51
34
|
// The generateJwtTokenForAuthIdentity function requires app_metadata.customer_id
|
|
52
35
|
let customerId = authIdentity.app_metadata?.customer_id;
|
|
53
|
-
console.log("[emailpass-auth] Checking customer ID", {
|
|
54
|
-
email,
|
|
55
|
-
customerIdFromMetadata: customerId,
|
|
56
|
-
hasAppMetadata: !!authIdentity.app_metadata,
|
|
57
|
-
});
|
|
58
36
|
if (!customerId) {
|
|
59
37
|
// Try to get customer_id from provider_identity entity_id (email)
|
|
60
38
|
// and look up the customer
|
|
61
|
-
console.log("[emailpass-auth] Customer ID not in metadata, looking up by email", {
|
|
62
|
-
email: email.toLowerCase(),
|
|
63
|
-
});
|
|
64
39
|
const customerModule = req.scope.resolve(utils_1.Modules.CUSTOMER);
|
|
65
40
|
const customers = await customerModule.listCustomers({
|
|
66
41
|
email: email.toLowerCase(),
|
|
67
42
|
});
|
|
68
|
-
console.log("[emailpass-auth] Customer lookup result", {
|
|
69
|
-
email: email.toLowerCase(),
|
|
70
|
-
customersFound: customers?.length || 0,
|
|
71
|
-
customerId: customers && customers.length > 0 ? customers[0].id : null,
|
|
72
|
-
});
|
|
73
43
|
if (customers && customers.length > 0) {
|
|
74
44
|
customerId = customers[0].id;
|
|
75
45
|
}
|
|
76
46
|
}
|
|
77
47
|
if (!customerId) {
|
|
78
|
-
console.error("[emailpass-auth] Unable to determine customer ID", {
|
|
79
|
-
email,
|
|
80
|
-
hasAppMetadata: !!authIdentity.app_metadata,
|
|
81
|
-
appMetadata: authIdentity.app_metadata,
|
|
82
|
-
providerIdentities: authIdentity.provider_identities,
|
|
83
|
-
});
|
|
84
48
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Unable to determine customer ID for authentication");
|
|
85
49
|
}
|
|
50
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
51
|
+
if (await accountDeletionService.hasPendingRequest(customerId)) {
|
|
52
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Customer has an active account deletion request");
|
|
53
|
+
}
|
|
86
54
|
// Ensure app_metadata has customer_id
|
|
87
55
|
const authIdentityWithCustomerId = {
|
|
88
56
|
...authIdentity,
|
|
@@ -100,20 +68,6 @@ const GET = async (req, res) => {
|
|
|
100
68
|
});
|
|
101
69
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "JWT secret is not configured");
|
|
102
70
|
}
|
|
103
|
-
// Log before token generation
|
|
104
|
-
console.log("[emailpass-auth] Generating JWT token", {
|
|
105
|
-
email,
|
|
106
|
-
customerId,
|
|
107
|
-
authIdentityId: authIdentityWithCustomerId?.id,
|
|
108
|
-
actorType: "customer",
|
|
109
|
-
jwtSecretExists: !!http.jwtSecret,
|
|
110
|
-
jwtSecretType: typeof http.jwtSecret,
|
|
111
|
-
jwtSecretHasLength: typeof http.jwtSecret === "string" ? !!http.jwtSecret.length : false,
|
|
112
|
-
jwtSecretLength: typeof http.jwtSecret === "string" ? http.jwtSecret.length : undefined,
|
|
113
|
-
jwtExpiresIn: http.jwtExpiresIn || "7d",
|
|
114
|
-
hasAppMetadata: !!authIdentityWithCustomerId?.app_metadata,
|
|
115
|
-
appMetadataCustomerId: authIdentityWithCustomerId?.app_metadata?.customer_id,
|
|
116
|
-
});
|
|
117
71
|
let token;
|
|
118
72
|
try {
|
|
119
73
|
token = await (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({
|
|
@@ -134,38 +88,10 @@ const GET = async (req, res) => {
|
|
|
134
88
|
});
|
|
135
89
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `JWT generation failed: ${jwtError instanceof Error ? jwtError.message : "Unknown error"}`);
|
|
136
90
|
}
|
|
137
|
-
// Log token generation result
|
|
138
|
-
console.log("[emailpass-auth] JWT token generation result", {
|
|
139
|
-
email,
|
|
140
|
-
customerId,
|
|
141
|
-
tokenExists: !!token,
|
|
142
|
-
tokenType: typeof token,
|
|
143
|
-
tokenLength: typeof token === "string" ? token.length : 0,
|
|
144
|
-
tokenPreview: typeof token === "string" ? token.substring(0, 20) + "..." : "N/A",
|
|
145
|
-
});
|
|
146
91
|
// Validate token was generated successfully
|
|
147
92
|
if (!token || typeof token !== "string") {
|
|
148
|
-
console.error("[emailpass-auth] Invalid token generated", {
|
|
149
|
-
email,
|
|
150
|
-
customerId,
|
|
151
|
-
token,
|
|
152
|
-
tokenType: typeof token,
|
|
153
|
-
tokenValue: token,
|
|
154
|
-
jwtSecretExists: !!http.jwtSecret,
|
|
155
|
-
authIdentityId: authIdentityWithCustomerId?.id,
|
|
156
|
-
authIdentityStructure: {
|
|
157
|
-
id: authIdentityWithCustomerId?.id,
|
|
158
|
-
provider_identities: authIdentityWithCustomerId?.provider_identities?.length,
|
|
159
|
-
app_metadata: authIdentityWithCustomerId?.app_metadata,
|
|
160
|
-
},
|
|
161
|
-
});
|
|
162
93
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to generate authentication token for customer ${customerId}. Token type: ${typeof token}, Token value: ${token}`);
|
|
163
94
|
}
|
|
164
|
-
console.log("[emailpass-auth] Authentication successful, returning token", {
|
|
165
|
-
email,
|
|
166
|
-
customerId,
|
|
167
|
-
tokenLength: token.length,
|
|
168
|
-
});
|
|
169
95
|
return res.status(200).json({ token });
|
|
170
96
|
}
|
|
171
97
|
console.error("[emailpass-auth] Authentication failed", {
|
|
@@ -181,21 +107,22 @@ const POST = async (req, res) => {
|
|
|
181
107
|
};
|
|
182
108
|
exports.POST = POST;
|
|
183
109
|
const enforceEmailAndPhoneVerification = async ({ email, req, }) => {
|
|
184
|
-
|
|
185
|
-
|
|
110
|
+
// Read identifier + require_verification from plugin config
|
|
111
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
112
|
+
const options = (0, config_1.resolveCustomerRegistrationOptions)(configModule);
|
|
113
|
+
const { identifier, require_verification } = options.registration;
|
|
114
|
+
// If verification is disabled entirely, skip all checks
|
|
115
|
+
if (!require_verification) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
186
118
|
const otpService = req.scope.resolve(otp_verification_1.OTP_VERIFICATION_MODULE);
|
|
187
119
|
const verificationStatus = await otpService.getCustomerVerificationByEmail(req.scope, email);
|
|
188
|
-
|
|
189
|
-
email,
|
|
190
|
-
email_verified: verificationStatus.email_verified,
|
|
191
|
-
verificationStatus,
|
|
192
|
-
});
|
|
193
|
-
if (!verificationStatus.email_verified) {
|
|
194
|
-
console.error("[emailpass-auth] Email not verified", {
|
|
195
|
-
email,
|
|
196
|
-
verificationStatus,
|
|
197
|
-
});
|
|
120
|
+
if ((identifier === "email" || identifier === "both") && !verificationStatus.email_verified) {
|
|
198
121
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Email not verified.");
|
|
199
122
|
}
|
|
123
|
+
if ((identifier === "phone" || identifier === "both") && !verificationStatus.phone_verified) {
|
|
124
|
+
console.error("[emailpass-auth] Phone not verified", { email });
|
|
125
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Phone not verified.");
|
|
126
|
+
}
|
|
200
127
|
};
|
|
201
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvZW1haWxwYXNzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQU1BLHFEQUlrQztBQUNsQywyRkFBb0c7QUFDcEcsMkZBQThGO0FBRTlGLDJFQUE4RTtBQUk5RSwrQ0FHMkI7QUFFcEIsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUM5QixpQ0FBeUIsQ0FBQyxhQUFhLENBQ3hDLENBQUE7SUFFRCxNQUFNLFlBQVksR0FBRyxJQUFBLDJDQUFrQyxFQUFDLE1BQTJCLENBQUMsQ0FBQTtJQUNwRixJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsVUFBVSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQzlDLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG1FQUFtRSxDQUNwRSxDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUUvQyxNQUFNLFFBQVEsR0FBRztRQUNmLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRztRQUNaLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztRQUNwQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7UUFDaEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO1FBQ2QsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO0tBQ0EsQ0FBQTtJQUV4QixNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLEdBQzlDLE1BQU0sT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVB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
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const generate_jwt_token_1 = require("@medusajs/medusa/api/auth/utils/generate-jwt-token");
|
|
6
|
+
/**
|
|
7
|
+
* Register a new customer with phone + password.
|
|
8
|
+
*
|
|
9
|
+
* On success the caller receives a short-lived JWT token. Use it as the
|
|
10
|
+
* Bearer token when calling `POST /store/customers` to create the customer
|
|
11
|
+
* record and link it to this auth identity.
|
|
12
|
+
*/
|
|
13
|
+
const POST = async (req, res) => {
|
|
14
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
15
|
+
const service = req.scope.resolve(utils_1.Modules.AUTH);
|
|
16
|
+
const authData = {
|
|
17
|
+
url: req.url,
|
|
18
|
+
headers: req.headers,
|
|
19
|
+
query: req.query,
|
|
20
|
+
body: req.body,
|
|
21
|
+
protocol: req.protocol,
|
|
22
|
+
};
|
|
23
|
+
const { success, error, authIdentity } = await service.register("phonepass", authData);
|
|
24
|
+
if (!success || !authIdentity) {
|
|
25
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, error || "Registration failed");
|
|
26
|
+
}
|
|
27
|
+
const { http } = config.projectConfig;
|
|
28
|
+
if (!http.jwtSecret) {
|
|
29
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "JWT secret is not configured");
|
|
30
|
+
}
|
|
31
|
+
let token;
|
|
32
|
+
try {
|
|
33
|
+
token = await (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({
|
|
34
|
+
authIdentity,
|
|
35
|
+
actorType: "customer",
|
|
36
|
+
}, {
|
|
37
|
+
secret: http.jwtSecret,
|
|
38
|
+
expiresIn: http.jwtExpiresIn || "7d",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (jwtError) {
|
|
42
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `JWT generation failed: ${jwtError instanceof Error ? jwtError.message : "Unknown error"}`);
|
|
43
|
+
}
|
|
44
|
+
if (!token || typeof token !== "string") {
|
|
45
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Failed to generate registration token");
|
|
46
|
+
}
|
|
47
|
+
return res.status(200).json({ token });
|
|
48
|
+
};
|
|
49
|
+
exports.POST = POST;
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvcGhvbmVwYXNzL3JlZ2lzdGVyL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHFEQUlrQztBQUNsQywyRkFBb0c7QUFFcEc7Ozs7OztHQU1HO0FBQ0ksTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQ3pFLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUUvQyxNQUFNLFFBQVEsR0FBRztRQUNmLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRztRQUNaLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztRQUNwQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7UUFDaEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO1FBQ2QsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO0tBQ0EsQ0FBQTtJQUV4QixNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxRQUFRLENBQzdELFdBQVcsRUFDWCxRQUFRLENBQ1QsQ0FBQTtJQUVELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM5QixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixLQUFLLElBQUkscUJBQXFCLENBQy9CLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUE7SUFFckMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw4QkFBOEIsQ0FDL0IsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLEtBQXlCLENBQUE7SUFDN0IsSUFBSSxDQUFDO1FBQ0gsS0FBSyxHQUFHLE1BQU0sSUFBQSxvREFBK0IsRUFDM0M7WUFDRSxZQUFZO1lBQ1osU0FBUyxFQUFFLFVBQVU7U0FDdEIsRUFDRDtZQUNFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUztZQUN0QixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJO1NBQ3JDLENBQ0YsQ0FBQTtJQUNILENBQUM7SUFBQyxPQUFPLFFBQVEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsMEJBQTBCLFFBQVEsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUMzRixDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDeEMsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyx1Q0FBdUMsQ0FDeEMsQ0FBQTtJQUNILENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtBQUN4QyxDQUFDLENBQUE7QUE1RFksUUFBQSxJQUFJLFFBNERoQiJ9
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const generate_jwt_token_1 = require("@medusajs/medusa/api/auth/utils/generate-jwt-token");
|
|
6
|
+
const account_deletion_request_1 = require("../../../../modules/account-deletion-request");
|
|
7
|
+
const otp_verification_1 = require("../../../../modules/otp-verification");
|
|
8
|
+
const config_1 = require("../../../../config");
|
|
9
|
+
const POST = async (req, res) => {
|
|
10
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
11
|
+
const loginOptions = (0, config_1.resolveCustomerRegistrationOptions)(config);
|
|
12
|
+
if (loginOptions.login.identifier === "email") {
|
|
13
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Phone login is not enabled. Please log in with your email.");
|
|
14
|
+
}
|
|
15
|
+
const service = req.scope.resolve(utils_1.Modules.AUTH);
|
|
16
|
+
const authData = {
|
|
17
|
+
url: req.url,
|
|
18
|
+
headers: req.headers,
|
|
19
|
+
query: req.query,
|
|
20
|
+
body: req.body,
|
|
21
|
+
protocol: req.protocol,
|
|
22
|
+
};
|
|
23
|
+
const { success, error, authIdentity } = await service.authenticate("phonepass", authData);
|
|
24
|
+
if (success && authIdentity) {
|
|
25
|
+
const phone = authIdentity.provider_identities?.[0]?.entity_id ?? "";
|
|
26
|
+
await enforcePhoneVerification({ authIdentity, req });
|
|
27
|
+
let customerId = authIdentity.app_metadata?.customer_id;
|
|
28
|
+
if (!customerId) {
|
|
29
|
+
const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
30
|
+
if (knex) {
|
|
31
|
+
const result = await knex.raw(`SELECT id FROM customer WHERE phone = ? LIMIT 1`, [phone]);
|
|
32
|
+
const row = result.rows?.[0] ?? result[0]?.[0];
|
|
33
|
+
if (row?.id) {
|
|
34
|
+
customerId = row.id;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!customerId) {
|
|
39
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Unable to determine customer ID for authentication");
|
|
40
|
+
}
|
|
41
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
42
|
+
if (await accountDeletionService.hasPendingRequest(customerId)) {
|
|
43
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Customer has an active account deletion request");
|
|
44
|
+
}
|
|
45
|
+
const authIdentityWithCustomerId = {
|
|
46
|
+
...authIdentity,
|
|
47
|
+
app_metadata: {
|
|
48
|
+
...authIdentity.app_metadata,
|
|
49
|
+
customer_id: customerId,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const { http } = config.projectConfig;
|
|
53
|
+
if (!http.jwtSecret) {
|
|
54
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "JWT secret is not configured");
|
|
55
|
+
}
|
|
56
|
+
let token;
|
|
57
|
+
try {
|
|
58
|
+
token = await (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({
|
|
59
|
+
authIdentity: authIdentityWithCustomerId,
|
|
60
|
+
actorType: "customer",
|
|
61
|
+
}, {
|
|
62
|
+
secret: http.jwtSecret,
|
|
63
|
+
expiresIn: http.jwtExpiresIn || "7d",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (jwtError) {
|
|
67
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `JWT generation failed: ${jwtError instanceof Error ? jwtError.message : "Unknown error"}`);
|
|
68
|
+
}
|
|
69
|
+
if (!token || typeof token !== "string") {
|
|
70
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Failed to generate authentication token");
|
|
71
|
+
}
|
|
72
|
+
return res.status(200).json({ token });
|
|
73
|
+
}
|
|
74
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, error || "Authentication failed");
|
|
75
|
+
};
|
|
76
|
+
exports.POST = POST;
|
|
77
|
+
const enforcePhoneVerification = async ({ authIdentity, req, }) => {
|
|
78
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
79
|
+
const options = (0, config_1.resolveCustomerRegistrationOptions)(configModule);
|
|
80
|
+
const { require_verification } = options.registration;
|
|
81
|
+
if (!require_verification) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Use customer_id — not phone — for the verification lookup.
|
|
85
|
+
// Phone is mutable: after a phone update customer.phone becomes the NEW number
|
|
86
|
+
// while provider_identity.entity_id still holds the OLD one. Querying
|
|
87
|
+
// WHERE phone = entity_id would find no row and return phone_verified = false
|
|
88
|
+
// even when the customer's actual record is marked verified.
|
|
89
|
+
const customerId = authIdentity.app_metadata?.customer_id;
|
|
90
|
+
if (!customerId) {
|
|
91
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Phone not verified.");
|
|
92
|
+
}
|
|
93
|
+
const otpService = req.scope.resolve(otp_verification_1.OTP_VERIFICATION_MODULE);
|
|
94
|
+
const verificationStatus = await otpService.getCustomerVerificationByCustomerId(req.scope, customerId);
|
|
95
|
+
if (!verificationStatus.phone_verified) {
|
|
96
|
+
// Surface a helpful message when a phone change is pending verification
|
|
97
|
+
const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
98
|
+
const row = await knex.raw(`SELECT metadata->>'pending_phone' AS pending_phone FROM customer WHERE id = ? LIMIT 1`, [customerId]);
|
|
99
|
+
const pendingPhone = (row.rows?.[0] ?? row[0]?.[0])?.pending_phone ?? null;
|
|
100
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, pendingPhone
|
|
101
|
+
? "Your new phone number is pending verification. Please verify it to continue."
|
|
102
|
+
: "Phone not verified.");
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvcGhvbmVwYXNzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUtBLHFEQUlrQztBQUNsQywyRkFBb0c7QUFDcEcsMkZBQThGO0FBRTlGLDJFQUE4RTtBQUc5RSwrQ0FHMkI7QUFFcEIsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBRXpFLE1BQU0sWUFBWSxHQUFHLElBQUEsMkNBQWtDLEVBQUMsTUFBMkIsQ0FBQyxDQUFBO0lBQ3BGLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBQUssT0FBTyxFQUFFLENBQUM7UUFDOUMsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsNERBQTRELENBQzdELENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBRS9DLE1BQU0sUUFBUSxHQUFHO1FBQ2YsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHO1FBQ1osT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPO1FBQ3BCLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSztRQUNoQixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7UUFDZCxRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVE7S0FDQSxDQUFBO0lBRXhCLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxHQUNwQyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FB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
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.guardAccountDeletion = guardAccountDeletion;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const account_deletion_request_1 = require("../../modules/account-deletion-request");
|
|
6
|
+
/** Paths under /store that a customer with a pending deletion is allowed to call. */
|
|
7
|
+
const STORE_ACCOUNT_DELETION_PATH = "/store/customers/account-deletion/";
|
|
8
|
+
/**
|
|
9
|
+
* Blocks requests when the authenticated customer has an active account_deletion_request
|
|
10
|
+
* (status "pending" or "confirmed"). Login (auth) is allowed; all other store APIs are
|
|
11
|
+
* blocked except account-deletion routes (request, confirm, cancel-request, cancel-confirm).
|
|
12
|
+
*/
|
|
13
|
+
async function guardAccountDeletion(req, res, next) {
|
|
14
|
+
const authContext = req.auth_context;
|
|
15
|
+
const customerId = authContext?.actor_id ?? authContext?.user_id;
|
|
16
|
+
if (!customerId) {
|
|
17
|
+
return next();
|
|
18
|
+
}
|
|
19
|
+
const path = req.url?.split("?")[0] ?? "";
|
|
20
|
+
if (path.includes(STORE_ACCOUNT_DELETION_PATH)) {
|
|
21
|
+
return next();
|
|
22
|
+
}
|
|
23
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
24
|
+
if (await accountDeletionService.hasActiveRequest(customerId)) {
|
|
25
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Customer has an active account deletion request");
|
|
26
|
+
}
|
|
27
|
+
next();
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VhcmQtYWNjb3VudC1kZWxldGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvbWlkZGxld2FyZXMvZ3VhcmQtYWNjb3VudC1kZWxldGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWlCQSxvREE2QkM7QUF6Q0QscURBQXVEO0FBQ3ZELHFGQUF3RjtBQUd4RixxRkFBcUY7QUFDckYsTUFBTSwyQkFBMkIsR0FBRyxvQ0FBb0MsQ0FBQTtBQUV4RTs7OztHQUlHO0FBQ0ksS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxHQUFrQixFQUNsQixHQUFtQixFQUNuQixJQUF3QjtJQUV4QixNQUFNLFdBQVcsR0FBSSxHQUVuQixDQUFDLFlBQVksQ0FBQTtJQUNmLE1BQU0sVUFBVSxHQUFHLFdBQVcsRUFBRSxRQUFRLElBQUksV0FBVyxFQUFFLE9BQU8sQ0FBQTtJQUVoRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUNmLENBQUM7SUFFRCxNQUFNLElBQUksR0FBSSxHQUF3QixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBO0lBQy9ELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQyxFQUFFLENBQUM7UUFDL0MsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUNmLENBQUM7SUFFRCxNQUFNLHNCQUFzQixHQUMxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBZ0MsMERBQStCLENBQUMsQ0FBQTtJQUNuRixJQUFJLE1BQU0sc0JBQXNCLENBQUMsZ0JBQWdCLENBQUMsVUFBb0IsQ0FBQyxFQUFFLENBQUM7UUFDeEUsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsaURBQWlELENBQ2xELENBQUE7SUFDSCxDQUFDO0lBRUQsSUFBSSxFQUFFLENBQUE7QUFDUixDQUFDIn0=
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ipRateLimit = ipRateLimit;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
/**
|
|
6
|
+
* Creates a per-IP in-memory rate limiter middleware.
|
|
7
|
+
* Uses a simple fixed-window counter — no external dependency needed.
|
|
8
|
+
*
|
|
9
|
+
* Each path that needs limiting should get its own factory call so the
|
|
10
|
+
* counters are isolated:
|
|
11
|
+
*
|
|
12
|
+
* middlewares: [ipRateLimit({ max: 5, windowMs: 60_000 })]
|
|
13
|
+
*/
|
|
14
|
+
function ipRateLimit(options = {}) {
|
|
15
|
+
const max = options.max ?? 10;
|
|
16
|
+
const windowMs = options.windowMs ?? 60_000;
|
|
17
|
+
const buckets = new Map();
|
|
18
|
+
// Prune expired entries every 5 minutes to avoid unbounded growth.
|
|
19
|
+
const pruneInterval = setInterval(() => {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
for (const [key, entry] of buckets) {
|
|
22
|
+
if (entry.resetAt <= now) {
|
|
23
|
+
buckets.delete(key);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}, 5 * 60_000);
|
|
27
|
+
// Allow the Node process to exit even if the interval is still active.
|
|
28
|
+
if (pruneInterval.unref) {
|
|
29
|
+
pruneInterval.unref();
|
|
30
|
+
}
|
|
31
|
+
return async function rateLimitMiddleware(req, _res, next) {
|
|
32
|
+
const ip = req.headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
|
|
33
|
+
req.socket?.remoteAddress ||
|
|
34
|
+
"unknown";
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
const existing = buckets.get(ip);
|
|
37
|
+
if (!existing || existing.resetAt <= now) {
|
|
38
|
+
buckets.set(ip, { count: 1, resetAt: now + windowMs });
|
|
39
|
+
return next();
|
|
40
|
+
}
|
|
41
|
+
existing.count += 1;
|
|
42
|
+
if (existing.count > max) {
|
|
43
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Too many requests. Please try again later.");
|
|
44
|
+
}
|
|
45
|
+
return next();
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXAtcmF0ZS1saW1pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvbWlkZGxld2FyZXMvaXAtcmF0ZS1saW1pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTRCQSxrQ0FrREM7QUF6RUQscURBQXVEO0FBY3ZEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBZ0IsV0FBVyxDQUFDLFVBQTRCLEVBQUU7SUFDeEQsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUE7SUFDN0IsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUE7SUFFM0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUE7SUFFOUMsbUVBQW1FO0lBQ25FLE1BQU0sYUFBYSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7UUFDckMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ3RCLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNuQyxJQUFJLEtBQUssQ0FBQyxPQUFPLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ3pCLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDckIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFBO0lBRWQsdUVBQXVFO0lBQ3ZFLElBQUksYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUN2QixDQUFDO0lBRUQsT0FBTyxLQUFLLFVBQVUsbUJBQW1CLENBQ3ZDLEdBQWtCLEVBQ2xCLElBQW9CLEVBQ3BCLElBQXdCO1FBRXhCLE1BQU0sRUFBRSxHQUNMLEdBQUcsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQVksRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFO1lBQ2pFLEdBQUcsQ0FBQyxNQUFNLEVBQUUsYUFBYTtZQUN6QixTQUFTLENBQUE7UUFFWCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDdEIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUVoQyxJQUFJLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxPQUFPLElBQUksR0FBRyxFQUFFLENBQUM7WUFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEdBQUcsUUFBUSxFQUFFLENBQUMsQ0FBQTtZQUN0RCxPQUFPLElBQUksRUFBRSxDQUFBO1FBQ2YsQ0FBQztRQUVELFFBQVEsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFBO1FBRW5CLElBQUksUUFBUSxDQUFDLEtBQUssR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUM3Qiw0Q0FBNEMsQ0FDN0MsQ0FBQTtRQUNILENBQUM7UUFFRCxPQUFPLElBQUksRUFBRSxDQUFBO0lBQ2YsQ0FBQyxDQUFBO0FBQ0gsQ0FBQyJ9
|