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,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateCustomerRegistration = validateCustomerRegistration;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const config_1 = require("../../config");
|
|
6
|
+
const VALID_IDENTIFIERS = ["email", "phone", "both"];
|
|
7
|
+
const EMAIL_REGEX = /^\S+@\S+\.\S+$/;
|
|
8
|
+
const PHONE_REGEX = /^\+?[0-9]{8,15}$/;
|
|
9
|
+
/**
|
|
10
|
+
* Validates registration fields on `POST /store/customers` based on the
|
|
11
|
+
* plugin's `registration.identifier` config:
|
|
12
|
+
*
|
|
13
|
+
* - "email" → email required, format checked
|
|
14
|
+
* - "phone" → phone required, format checked
|
|
15
|
+
* - "both" → email and phone both required, both format-checked
|
|
16
|
+
*
|
|
17
|
+
* Format validation applies to any field that is present, regardless of
|
|
18
|
+
* whether it was required, so bad data is always rejected early.
|
|
19
|
+
*/
|
|
20
|
+
async function validateCustomerRegistration(req, res, next) {
|
|
21
|
+
// Defensive guard — the matcher in middlewares.ts already limits to POST,
|
|
22
|
+
// but protect against accidental broader mounting.
|
|
23
|
+
if (req.method !== "POST") {
|
|
24
|
+
return next();
|
|
25
|
+
}
|
|
26
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
27
|
+
const options = (0, config_1.resolveCustomerRegistrationOptions)(configModule);
|
|
28
|
+
const identifier = options.registration.identifier;
|
|
29
|
+
// Fail fast if the config value is somehow outside the known set
|
|
30
|
+
if (!VALID_IDENTIFIERS.includes(identifier)) {
|
|
31
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Invalid registration identifier configuration: "${identifier}". Must be one of: ${VALID_IDENTIFIERS.join(", ")}`);
|
|
32
|
+
}
|
|
33
|
+
const { email, phone } = (req.body ?? {});
|
|
34
|
+
const emailNormalized = email?.trim() || undefined;
|
|
35
|
+
const phoneNormalized = phone?.trim() || undefined;
|
|
36
|
+
// --- Presence checks (identifier-specific) ---
|
|
37
|
+
if (identifier === "email" && !emailNormalized) {
|
|
38
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Email is required for registration");
|
|
39
|
+
}
|
|
40
|
+
if (identifier === "phone" && !phoneNormalized) {
|
|
41
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Phone is required for registration");
|
|
42
|
+
}
|
|
43
|
+
if (identifier === "both") {
|
|
44
|
+
if (!emailNormalized) {
|
|
45
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Email is required for registration");
|
|
46
|
+
}
|
|
47
|
+
if (!phoneNormalized) {
|
|
48
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Phone is required for registration");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// --- Format checks (applied to any field that is present) ---
|
|
52
|
+
if (emailNormalized && !EMAIL_REGEX.test(emailNormalized)) {
|
|
53
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid email format");
|
|
54
|
+
}
|
|
55
|
+
if (phoneNormalized && !PHONE_REGEX.test(phoneNormalized)) {
|
|
56
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid phone number format. Must be 8–15 digits, optionally prefixed with +");
|
|
57
|
+
}
|
|
58
|
+
next();
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUtY3VzdG9tZXItcmVnaXN0cmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwaS9taWRkbGV3YXJlcy92YWxpZGF0ZS1jdXN0b21lci1yZWdpc3RyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUEyQkEsb0VBaUZDO0FBdkdELHFEQUFrRjtBQUNsRix5Q0FHcUI7QUFFckIsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFVLENBQUE7QUFFN0QsTUFBTSxXQUFXLEdBQUcsZ0JBQWdCLENBQUE7QUFDcEMsTUFBTSxXQUFXLEdBQUcsa0JBQWtCLENBQUE7QUFFdEM7Ozs7Ozs7Ozs7R0FVRztBQUNJLEtBQUssVUFBVSw0QkFBNEIsQ0FDaEQsR0FBa0IsRUFDbEIsR0FBbUIsRUFDbkIsSUFBd0I7SUFFeEIsMEVBQTBFO0lBQzFFLG1EQUFtRDtJQUNuRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDMUIsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUNmLENBQUM7SUFFRCxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FDcEMsaUNBQXlCLENBQUMsYUFBYSxDQUN4QyxDQUFBO0lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBQSwyQ0FBa0MsRUFBQyxZQUFZLENBQUMsQ0FBQTtJQUNoRSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQTtJQUVsRCxpRUFBaUU7SUFDakUsSUFBSSxDQUFFLGlCQUF1QyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQ25FLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG1EQUFtRCxVQUFVLHNCQUFzQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDbEgsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBR3ZDLENBQUE7SUFFRCxNQUFNLGVBQWUsR0FBRyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksU0FBUyxDQUFBO0lBQ2xELE1BQU0sZUFBZSxHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxTQUFTLENBQUE7SUFFbEQsZ0RBQWdEO0lBRWhELElBQUksVUFBVSxLQUFLLE9BQU8sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQy9DLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG9DQUFvQyxDQUNyQyxDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksVUFBVSxLQUFLLE9BQU8sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQy9DLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG9DQUFvQyxDQUNyQyxDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixvQ0FBb0MsQ0FDckMsQ0FBQTtRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsb0NBQW9DLENBQ3JDLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELCtEQUErRDtJQUUvRCxJQUFJLGVBQWUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUMxRCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixzQkFBc0IsQ0FDdkIsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLGVBQWUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUMxRCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw4RUFBOEUsQ0FDL0UsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLEVBQUUsQ0FBQTtBQUNSLENBQUMifQ==
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const http_1 = require("@medusajs/framework/http");
|
|
4
|
+
const guard_account_deletion_1 = require("./middlewares/guard-account-deletion");
|
|
5
|
+
const validate_customer_registration_1 = require("./middlewares/validate-customer-registration");
|
|
6
|
+
const ip_rate_limit_1 = require("./middlewares/ip-rate-limit");
|
|
7
|
+
exports.default = (0, http_1.defineMiddlewares)({
|
|
8
|
+
routes: [
|
|
9
|
+
{
|
|
10
|
+
matcher: "/auth/customer/*",
|
|
11
|
+
middlewares: [guard_account_deletion_1.guardAccountDeletion],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
matcher: "/store/*",
|
|
15
|
+
middlewares: [guard_account_deletion_1.guardAccountDeletion],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
matcher: "/store/customers",
|
|
19
|
+
method: ["POST"],
|
|
20
|
+
middlewares: [validate_customer_registration_1.validateCustomerRegistration],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
// Unauthenticated endpoint — rate-limit per IP to prevent OTP spam
|
|
24
|
+
matcher: "/store/customers/account-deletion/cancel-request",
|
|
25
|
+
method: ["POST"],
|
|
26
|
+
middlewares: [(0, ip_rate_limit_1.ipRateLimit)({ max: 5, windowMs: 60_000 })],
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBQTREO0FBQzVELGlGQUEyRTtBQUMzRSxpR0FBMkY7QUFDM0YsK0RBQXlEO0FBRXpELGtCQUFlLElBQUEsd0JBQWlCLEVBQUM7SUFDL0IsTUFBTSxFQUFFO1FBQ047WUFDRSxPQUFPLEVBQUUsa0JBQWtCO1lBQzNCLFdBQVcsRUFBRSxDQUFDLDZDQUFvQixDQUFDO1NBQ3BDO1FBQ0Q7WUFDRSxPQUFPLEVBQUUsVUFBVTtZQUNuQixXQUFXLEVBQUUsQ0FBQyw2Q0FBb0IsQ0FBQztTQUNwQztRQUNEO1lBQ0UsT0FBTyxFQUFFLGtCQUFrQjtZQUMzQixNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDaEIsV0FBVyxFQUFFLENBQUMsNkRBQTRCLENBQUM7U0FDNUM7UUFDRDtZQUNFLG1FQUFtRTtZQUNuRSxPQUFPLEVBQUUsa0RBQWtEO1lBQzNELE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUNoQixXQUFXLEVBQUUsQ0FBQyxJQUFBLDJCQUFXLEVBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1NBQ3pEO0tBQ0Y7Q0FDRixDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,36 @@
|
|
|
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 otp_verification_1 = require("../../../../../modules/otp-verification");
|
|
6
|
+
const otp_verification_2 = require("../../../../../modules/otp-verification/models/otp-verification");
|
|
7
|
+
const account_deletion_request_1 = require("../../../../../modules/account-deletion-request");
|
|
8
|
+
const validators_1 = require("../validators");
|
|
9
|
+
const POST = async (req, res) => {
|
|
10
|
+
const parsed = validators_1.ConfirmCancelSchema.safeParse(req.body ?? {});
|
|
11
|
+
if (!parsed.success) {
|
|
12
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, parsed.error.errors.map((e) => e.message).join("; ") || "Invalid input");
|
|
13
|
+
}
|
|
14
|
+
const { token, code } = parsed.data;
|
|
15
|
+
const otpService = req.scope.resolve(otp_verification_1.OTP_VERIFICATION_MODULE);
|
|
16
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
17
|
+
const jwtSecret = config?.projectConfig?.http
|
|
18
|
+
?.jwtSecret || "supersecret";
|
|
19
|
+
const verifyResult = await otpService.verifyOtp({ token, code }, jwtSecret);
|
|
20
|
+
if (verifyResult.type !== otp_verification_2.OtpPurpose.ACCOUNT_DELETION_CANCEL) {
|
|
21
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid verification type for cancel confirmation");
|
|
22
|
+
}
|
|
23
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
24
|
+
const request = await accountDeletionService.cancelRequest(verifyResult.customer_id);
|
|
25
|
+
return res.status(200).json({
|
|
26
|
+
cancelled: true,
|
|
27
|
+
request: {
|
|
28
|
+
id: request.id,
|
|
29
|
+
customer_id: request.customer_id,
|
|
30
|
+
status: request.status,
|
|
31
|
+
cancelled_at: request.cancelled_at,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
exports.POST = POST;
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9hY2NvdW50LWRlbGV0aW9uL2NhbmNlbC1jb25maXJtL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUdrQztBQUNsQyw4RUFBaUY7QUFFakYsc0dBQTRGO0FBQzVGLDhGQUFpRztBQUVqRyw4Q0FBbUQ7QUFFNUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLGdDQUFtQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQzVELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQWUsQ0FDeEUsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUE7SUFFbkMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ2xDLDBDQUF1QixDQUN4QixDQUFBO0lBQ0QsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDekUsTUFBTSxTQUFTLEdBQ1osTUFBTSxFQUFFLGFBQW1ELEVBQUUsSUFBSTtRQUNoRSxFQUFFLFNBQVMsSUFBSSxhQUFhLENBQUE7SUFFaEMsTUFBTSxZQUFZLEdBQUcsTUFBTSxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBRTNFLElBQUksWUFBWSxDQUFDLElBQUksS0FBSyw2QkFBVSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDN0QsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsbURBQW1ELENBQ3BELENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FDOUMsMERBQStCLENBQ2hDLENBQUE7SUFFRCxNQUFNLE9BQU8sR0FBRyxNQUFNLHNCQUFzQixDQUFDLGFBQWEsQ0FDeEQsWUFBWSxDQUFDLFdBQVcsQ0FDekIsQ0FBQTtJQUVELE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDMUIsU0FBUyxFQUFFLElBQUk7UUFDZixPQUFPLEVBQUU7WUFDUCxFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUU7WUFDZCxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVc7WUFDaEMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtTQUNuQztLQUNGLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQTdDWSxRQUFBLElBQUksUUE2Q2hCIn0=
|
|
@@ -0,0 +1,55 @@
|
|
|
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 = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const account_deletion_request_1 = require("../../../../../modules/account-deletion-request");
|
|
9
|
+
const otp_verification_1 = require("../../../../../modules/otp-verification/models/otp-verification");
|
|
10
|
+
const send_otp_workflow_1 = __importDefault(require("../../../../../workflows/send-otp-workflow"));
|
|
11
|
+
const validators_1 = require("../validators");
|
|
12
|
+
const POST = async (req, res) => {
|
|
13
|
+
const parsed = validators_1.CancelRequestSchema.safeParse(req.body ?? {});
|
|
14
|
+
if (!parsed.success) {
|
|
15
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, parsed.error.errors.map((e) => e.message).join("; ") || "Invalid input");
|
|
16
|
+
}
|
|
17
|
+
const { email, phone } = parsed.data;
|
|
18
|
+
const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
19
|
+
if (!knex) {
|
|
20
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Database connection not available");
|
|
21
|
+
}
|
|
22
|
+
let customerId;
|
|
23
|
+
if (email) {
|
|
24
|
+
const result = await knex.raw(`SELECT id FROM customer WHERE email = ? LIMIT 1`, [email.toLowerCase().trim()]);
|
|
25
|
+
const row = result.rows?.[0] ?? result[0]?.[0];
|
|
26
|
+
customerId = row?.id;
|
|
27
|
+
}
|
|
28
|
+
else if (phone) {
|
|
29
|
+
const result = await knex.raw(`SELECT id FROM customer WHERE phone = ? LIMIT 1`, [phone.trim()]);
|
|
30
|
+
const row = result.rows?.[0] ?? result[0]?.[0];
|
|
31
|
+
customerId = row?.id;
|
|
32
|
+
}
|
|
33
|
+
if (!customerId) {
|
|
34
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, email
|
|
35
|
+
? "Customer not found with this email"
|
|
36
|
+
: "Customer not found with this phone number");
|
|
37
|
+
}
|
|
38
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
39
|
+
const active = await accountDeletionService.getActiveByCustomerId(customerId);
|
|
40
|
+
if (!active) {
|
|
41
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "No active deletion request found for this customer");
|
|
42
|
+
}
|
|
43
|
+
const { result: workflowResult } = await (0, send_otp_workflow_1.default)(req.scope).run({
|
|
44
|
+
input: {
|
|
45
|
+
customer_id: customerId,
|
|
46
|
+
type: otp_verification_1.OtpPurpose.ACCOUNT_DELETION_CANCEL,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
return res.status(200).json({
|
|
50
|
+
token: workflowResult.token,
|
|
51
|
+
expires_at: workflowResult.expires_at,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
exports.POST = POST;
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9hY2NvdW50LWRlbGV0aW9uL2NhbmNlbC1yZXF1ZXN0L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLHFEQUdrQztBQUNsQyw4RkFBaUc7QUFFakcsc0dBQTRGO0FBQzVGLG1HQUF3RTtBQUN4RSw4Q0FBbUQ7QUFFNUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLGdDQUFtQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQzVELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQWUsQ0FDeEUsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUE7SUFFcEMsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDdkUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyxtQ0FBbUMsQ0FDcEMsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLFVBQThCLENBQUE7SUFFbEMsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNWLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FDM0IsaURBQWlELEVBQ2pELENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQzdCLENBQUE7UUFDRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDOUMsVUFBVSxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUE7SUFDdEIsQ0FBQztTQUFNLElBQUksS0FBSyxFQUFFLENBQUM7UUFDakIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUMzQixpREFBaUQsRUFDakQsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FDZixDQUFBO1FBQ0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzlDLFVBQVUsR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFBO0lBQ3RCLENBQUM7SUFFRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFDM0IsS0FBSztZQUNILENBQUMsQ0FBQyxvQ0FBb0M7WUFDdEMsQ0FBQyxDQUFDLDJDQUEyQyxDQUNoRCxDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQzlDLDBEQUErQixDQUNoQyxDQUFBO0lBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxzQkFBc0IsQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUM3RSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUMzQixvREFBb0QsQ0FDckQsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLE1BQU0sSUFBQSwyQkFBZSxFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDdEUsS0FBSyxFQUFFO1lBQ0wsV0FBVyxFQUFFLFVBQVU7WUFDdkIsSUFBSSxFQUFFLDZCQUFVLENBQUMsdUJBQXVCO1NBQ3pDO0tBQ0YsQ0FBQyxDQUFBO0lBRUYsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMxQixLQUFLLEVBQUUsY0FBYyxDQUFDLEtBQUs7UUFDM0IsVUFBVSxFQUFFLGNBQWMsQ0FBQyxVQUFVO0tBQ3RDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQXJFWSxRQUFBLElBQUksUUFxRWhCIn0=
|
|
@@ -0,0 +1,43 @@
|
|
|
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 otp_verification_1 = require("../../../../../modules/otp-verification");
|
|
6
|
+
const otp_verification_2 = require("../../../../../modules/otp-verification/models/otp-verification");
|
|
7
|
+
const account_deletion_request_1 = require("../../../../../modules/account-deletion-request");
|
|
8
|
+
const config_1 = require("../../../../../config");
|
|
9
|
+
const validators_1 = require("../validators");
|
|
10
|
+
const DEFAULT_SCHEDULED_DAYS = 7;
|
|
11
|
+
const POST = async (req, res) => {
|
|
12
|
+
const parsed = validators_1.ConfirmDeletionSchema.safeParse(req.body ?? {});
|
|
13
|
+
if (!parsed.success) {
|
|
14
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, parsed.error.errors.map((e) => e.message).join("; ") || "Invalid input");
|
|
15
|
+
}
|
|
16
|
+
const { token, code } = parsed.data;
|
|
17
|
+
const otpService = req.scope.resolve(otp_verification_1.OTP_VERIFICATION_MODULE);
|
|
18
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
19
|
+
const jwtSecret = config?.projectConfig?.http
|
|
20
|
+
?.jwtSecret || "supersecret";
|
|
21
|
+
const verifyResult = await otpService.verifyOtp({ token, code }, jwtSecret);
|
|
22
|
+
if (verifyResult.type !== otp_verification_2.OtpPurpose.ACCOUNT_DELETION_REQUEST) {
|
|
23
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid verification type for account deletion confirmation");
|
|
24
|
+
}
|
|
25
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
26
|
+
const pluginOptions = (0, config_1.resolveCustomerRegistrationOptions)(configModule);
|
|
27
|
+
const scheduledDays = pluginOptions?.account_deletion_request?.scheduled_days ??
|
|
28
|
+
DEFAULT_SCHEDULED_DAYS;
|
|
29
|
+
const deletion_scheduled_at = new Date(Date.now() + scheduledDays * 24 * 60 * 60 * 1000);
|
|
30
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
31
|
+
const request = await accountDeletionService.createConfirmed(verifyResult.customer_id, deletion_scheduled_at);
|
|
32
|
+
return res.status(200).json({
|
|
33
|
+
request: {
|
|
34
|
+
id: request.id,
|
|
35
|
+
customer_id: request.customer_id,
|
|
36
|
+
reason: request.reason,
|
|
37
|
+
deletion_scheduled_at: request.deletion_scheduled_at,
|
|
38
|
+
status: request.status,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
exports.POST = POST;
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9hY2NvdW50LWRlbGV0aW9uL2NvbmZpcm0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBR2tDO0FBQ2xDLDhFQUFpRjtBQUVqRixzR0FBNEY7QUFDNUYsOEZBQWlHO0FBRWpHLGtEQUEwRTtBQUUxRSw4Q0FBcUQ7QUFFckQsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUE7QUFFekIsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLGtDQUFxQixDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQzlELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQWUsQ0FDeEUsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUE7SUFFbkMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ2xDLDBDQUF1QixDQUN4QixDQUFBO0lBQ0QsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDekUsTUFBTSxTQUFTLEdBQ1osTUFBTSxFQUFFLGFBQW1ELEVBQUUsSUFBSTtRQUNoRSxFQUFFLFNBQVMsSUFBSSxhQUFhLENBQUE7SUFFaEMsTUFBTSxZQUFZLEdBQUcsTUFBTSxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBRTNFLElBQUksWUFBWSxDQUFDLElBQUksS0FBSyw2QkFBVSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDOUQsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsNkRBQTZELENBQzlELENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ3BDLGlDQUF5QixDQUFDLGFBQWEsQ0FDbkIsQ0FBQTtJQUN0QixNQUFNLGFBQWEsR0FBRyxJQUFBLDJDQUFrQyxFQUFDLFlBQVksQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sYUFBYSxHQUNqQixhQUFhLEVBQUUsd0JBQXdCLEVBQUUsY0FBYztRQUN2RCxzQkFBc0IsQ0FBQTtJQUN4QixNQUFNLHFCQUFxQixHQUFHLElBQUksSUFBSSxDQUNwQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsYUFBYSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FDakQsQ0FBQTtJQUVELE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQzlDLDBEQUErQixDQUNoQyxDQUFBO0lBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxzQkFBc0IsQ0FBQyxlQUFlLENBQzFELFlBQVksQ0FBQyxXQUFXLEVBQ3hCLHFCQUFxQixDQUN0QixDQUFBO0lBRUQsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMxQixPQUFPLEVBQUU7WUFDUCxFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUU7WUFDZCxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVc7WUFDaEMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLHFCQUFxQixFQUFFLE9BQU8sQ0FBQyxxQkFBcUI7WUFDcEQsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3ZCO0tBQ0YsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFBO0FBekRZLFFBQUEsSUFBSSxRQXlEaEIifQ==
|
|
@@ -0,0 +1,40 @@
|
|
|
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 = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const account_deletion_request_1 = require("../../../../../modules/account-deletion-request");
|
|
9
|
+
const otp_verification_1 = require("../../../../../modules/otp-verification/models/otp-verification");
|
|
10
|
+
const send_otp_workflow_1 = __importDefault(require("../../../../../workflows/send-otp-workflow"));
|
|
11
|
+
const validators_1 = require("../validators");
|
|
12
|
+
const POST = async (req, res) => {
|
|
13
|
+
const authContext = req
|
|
14
|
+
.auth_context;
|
|
15
|
+
const customerId = authContext?.actor_id ?? authContext?.user_id;
|
|
16
|
+
if (!customerId) {
|
|
17
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Authentication required");
|
|
18
|
+
}
|
|
19
|
+
const parsed = validators_1.RequestDeletionSchema.safeParse(req.body ?? {});
|
|
20
|
+
if (!parsed.success) {
|
|
21
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, parsed.error.errors.map((e) => e.message).join("; ") || "Invalid input");
|
|
22
|
+
}
|
|
23
|
+
const accountDeletionService = req.scope.resolve(account_deletion_request_1.ACCOUNT_DELETION_REQUEST_MODULE);
|
|
24
|
+
const active = await accountDeletionService.getActiveByCustomerId(customerId);
|
|
25
|
+
if (active) {
|
|
26
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "An active deletion request already exists. Cancel it first.");
|
|
27
|
+
}
|
|
28
|
+
const { result } = await (0, send_otp_workflow_1.default)(req.scope).run({
|
|
29
|
+
input: {
|
|
30
|
+
customer_id: customerId,
|
|
31
|
+
type: otp_verification_1.OtpPurpose.ACCOUNT_DELETION_REQUEST,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
return res.status(200).json({
|
|
35
|
+
token: result.token,
|
|
36
|
+
expires_at: result.expires_at,
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
exports.POST = POST;
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9hY2NvdW50LWRlbGV0aW9uL3JlcXVlc3Qvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EscURBQXVEO0FBQ3ZELDhGQUFpRztBQUVqRyxzR0FBNEY7QUFDNUYsbUdBQXdFO0FBQ3hFLDhDQUFxRDtBQUU5QyxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDcEUsTUFBTSxXQUFXLEdBQUksR0FBa0U7U0FDcEYsWUFBWSxDQUFBO0lBQ2YsTUFBTSxVQUFVLEdBQUcsV0FBVyxFQUFFLFFBQVEsSUFBSSxXQUFXLEVBQUUsT0FBTyxDQUFBO0lBRWhFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qix5QkFBeUIsQ0FDMUIsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxrQ0FBcUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUM5RCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFlLENBQ3hFLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FDOUMsMERBQStCLENBQ2hDLENBQUE7SUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLHNCQUFzQixDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQzdFLElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw2REFBNkQsQ0FDOUQsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLDJCQUFlLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUN0RCxLQUFLLEVBQUU7WUFDTCxXQUFXLEVBQUUsVUFBVTtZQUN2QixJQUFJLEVBQUUsNkJBQVUsQ0FBQyx3QkFBd0I7U0FDMUM7S0FDRixDQUFDLENBQUE7SUFFRixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzFCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztRQUNuQixVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7S0FDOUIsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFBO0FBM0NZLFFBQUEsSUFBSSxRQTJDaEIifQ==
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfirmCancelSchema = exports.CancelRequestSchema = exports.ConfirmDeletionSchema = exports.RequestDeletionSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.RequestDeletionSchema = zod_1.z.object({
|
|
6
|
+
reason: zod_1.z.string().max(2000).optional().nullable(),
|
|
7
|
+
});
|
|
8
|
+
exports.ConfirmDeletionSchema = zod_1.z.object({
|
|
9
|
+
token: zod_1.z.string().min(1, "Token is required"),
|
|
10
|
+
code: zod_1.z.string().min(1, "OTP code is required"),
|
|
11
|
+
});
|
|
12
|
+
exports.CancelRequestSchema = zod_1.z
|
|
13
|
+
.object({
|
|
14
|
+
email: zod_1.z.string().email("Valid email address").optional(),
|
|
15
|
+
phone: zod_1.z
|
|
16
|
+
.string()
|
|
17
|
+
.regex(/^\+?[0-9]{8,15}$/, "Invalid phone number format")
|
|
18
|
+
.optional(),
|
|
19
|
+
})
|
|
20
|
+
.refine((data) => data.email || data.phone, {
|
|
21
|
+
message: "Either email or phone is required",
|
|
22
|
+
});
|
|
23
|
+
exports.ConfirmCancelSchema = zod_1.z.object({
|
|
24
|
+
token: zod_1.z.string().min(1, "Token is required"),
|
|
25
|
+
code: zod_1.z.string().min(1, "OTP code is required"),
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvc3RvcmUvY3VzdG9tZXJzL2FjY291bnQtZGVsZXRpb24vdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBdUI7QUFFVixRQUFBLHFCQUFxQixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDNUMsTUFBTSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQ25ELENBQUMsQ0FBQTtBQUVXLFFBQUEscUJBQXFCLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM1QyxLQUFLLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsbUJBQW1CLENBQUM7SUFDN0MsSUFBSSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLHNCQUFzQixDQUFDO0NBQ2hELENBQUMsQ0FBQTtBQUVXLFFBQUEsbUJBQW1CLEdBQUcsT0FBQztLQUNqQyxNQUFNLENBQUM7SUFDTixLQUFLLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUN6RCxLQUFLLEVBQUUsT0FBQztTQUNMLE1BQU0sRUFBRTtTQUNSLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSw2QkFBNkIsQ0FBQztTQUN4RCxRQUFRLEVBQUU7Q0FDZCxDQUFDO0tBQ0QsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7SUFDMUMsT0FBTyxFQUFFLG1DQUFtQztDQUM3QyxDQUFDLENBQUE7QUFFUyxRQUFBLG1CQUFtQixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDMUMsS0FBSyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixDQUFDO0lBQzdDLElBQUksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxzQkFBc0IsQ0FBQztDQUNoRCxDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,95 @@
|
|
|
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 = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const otp_verification_1 = require("../../../../../modules/otp-verification/models/otp-verification");
|
|
9
|
+
const config_1 = require("../../../../../config");
|
|
10
|
+
const send_contact_change_otp_workflow_1 = __importDefault(require("../../../../../workflows/send-contact-change-otp-workflow"));
|
|
11
|
+
const EMAIL_REGEX = /^\S+@\S+\.\S+$/;
|
|
12
|
+
const PHONE_REGEX = /^\+?[0-9]{8,15}$/;
|
|
13
|
+
/**
|
|
14
|
+
* POST /store/customers/me/contact
|
|
15
|
+
*
|
|
16
|
+
* Authenticated endpoint for requesting a phone or email change.
|
|
17
|
+
* Validates the new value, checks for duplicates, generates an OTP with the
|
|
18
|
+
* new_value embedded in the signed JWT (no metadata staging), sends the OTP
|
|
19
|
+
* to the new contact, and returns the token + expiry for use at /verify.
|
|
20
|
+
*
|
|
21
|
+
* Request body (exactly one field required):
|
|
22
|
+
* { phone: string } | { email: string }
|
|
23
|
+
*/
|
|
24
|
+
const POST = async (req, res) => {
|
|
25
|
+
const customerId = req.auth_context.actor_id;
|
|
26
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
27
|
+
const options = (0, config_1.resolveCustomerRegistrationOptions)(configModule);
|
|
28
|
+
const { phone: rawPhone, email: rawEmail } = (req.body ?? {});
|
|
29
|
+
const phone = rawPhone?.trim() || undefined;
|
|
30
|
+
const email = rawEmail?.trim() || undefined;
|
|
31
|
+
if (!phone && !email) {
|
|
32
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Either phone or email is required");
|
|
33
|
+
}
|
|
34
|
+
if (phone && email) {
|
|
35
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Only one of phone or email can be changed at a time");
|
|
36
|
+
}
|
|
37
|
+
const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
38
|
+
const customerService = req.scope.resolve(utils_1.Modules.CUSTOMER);
|
|
39
|
+
const customer = await customerService.retrieveCustomer(customerId);
|
|
40
|
+
if (phone) {
|
|
41
|
+
if (!PHONE_REGEX.test(phone)) {
|
|
42
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid phone number format. Must be 8–15 digits, optionally prefixed with +");
|
|
43
|
+
}
|
|
44
|
+
if (phone === customer.phone) {
|
|
45
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "New phone number is the same as the current one");
|
|
46
|
+
}
|
|
47
|
+
// Reject if login.identifier doesn't support phone
|
|
48
|
+
if (options.login.identifier !== "phone" &&
|
|
49
|
+
options.login.identifier !== "both") {
|
|
50
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Phone-based login is not enabled for this store");
|
|
51
|
+
}
|
|
52
|
+
// Duplicate check
|
|
53
|
+
const existing = await knex.raw(`SELECT id FROM customer WHERE phone = ? AND has_account = true LIMIT 1`, [phone]);
|
|
54
|
+
if (existing.rows?.[0] ?? existing[0]?.[0]) {
|
|
55
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.DUPLICATE_ERROR, "A customer with this phone number already exists");
|
|
56
|
+
}
|
|
57
|
+
const { result } = await (0, send_contact_change_otp_workflow_1.default)(req.scope).run({
|
|
58
|
+
input: {
|
|
59
|
+
customer_id: customerId,
|
|
60
|
+
new_value: phone,
|
|
61
|
+
contact_type: "phone",
|
|
62
|
+
otp_type: otp_verification_1.OtpPurpose.PHONE_VERIFICATION,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return res.status(200).json({ token: result.token, expires_at: result.expires_at });
|
|
66
|
+
}
|
|
67
|
+
// email branch
|
|
68
|
+
if (!EMAIL_REGEX.test(email)) {
|
|
69
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid email format");
|
|
70
|
+
}
|
|
71
|
+
if (email === customer.email) {
|
|
72
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "New email is the same as the current one");
|
|
73
|
+
}
|
|
74
|
+
// Reject if login.identifier doesn't support email
|
|
75
|
+
if (options.login.identifier !== "email" &&
|
|
76
|
+
options.login.identifier !== "both") {
|
|
77
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Email-based login is not enabled for this store");
|
|
78
|
+
}
|
|
79
|
+
// Duplicate check
|
|
80
|
+
const existingEmail = await knex.raw(`SELECT id FROM customer WHERE email = ? AND has_account = true LIMIT 1`, [email]);
|
|
81
|
+
if (existingEmail.rows?.[0] ?? existingEmail[0]?.[0]) {
|
|
82
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.DUPLICATE_ERROR, "A customer with this email already exists");
|
|
83
|
+
}
|
|
84
|
+
const { result } = await (0, send_contact_change_otp_workflow_1.default)(req.scope).run({
|
|
85
|
+
input: {
|
|
86
|
+
customer_id: customerId,
|
|
87
|
+
new_value: email,
|
|
88
|
+
contact_type: "email",
|
|
89
|
+
otp_type: otp_verification_1.OtpPurpose.EMAIL_VERIFICATION,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
return res.status(200).json({ token: result.token, expires_at: result.expires_at });
|
|
93
|
+
};
|
|
94
|
+
exports.POST = POST;
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9tZS9jb250YWN0L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLHFEQUlrQztBQUVsQyxzR0FBNEY7QUFDNUYsa0RBRzhCO0FBQzlCLGlJQUFvRztBQUVwRyxNQUFNLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQTtBQUNwQyxNQUFNLFdBQVcsR0FBRyxrQkFBa0IsQ0FBQTtBQUV0Qzs7Ozs7Ozs7OztHQVVHO0FBQ0ksTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUN2QixHQUErQixFQUMvQixHQUFtQixFQUNuQixFQUFFO0lBQ0YsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUE7SUFFNUMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBQSwyQ0FBa0MsRUFBQyxZQUFpQyxDQUFDLENBQUE7SUFFckYsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBRzNELENBQUE7SUFFRCxNQUFNLEtBQUssR0FBRyxRQUFRLEVBQUUsSUFBSSxFQUFFLElBQUksU0FBUyxDQUFBO0lBQzNDLE1BQU0sS0FBSyxHQUFHLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxTQUFTLENBQUE7SUFFM0MsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG1DQUFtQyxDQUNwQyxDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxJ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
|
|
@@ -0,0 +1,83 @@
|
|
|
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 = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const generate_jwt_token_1 = require("@medusajs/medusa/api/auth/utils/generate-jwt-token");
|
|
9
|
+
const otp_verification_1 = require("../../../../../../modules/otp-verification");
|
|
10
|
+
const config_1 = require("../../../../../../config");
|
|
11
|
+
const update_contact_workflow_1 = __importDefault(require("../../../../../../workflows/update-contact-workflow"));
|
|
12
|
+
/**
|
|
13
|
+
* POST /store/customers/me/contact/verify
|
|
14
|
+
*
|
|
15
|
+
* Authenticated endpoint for confirming a phone or email change.
|
|
16
|
+
*
|
|
17
|
+
* 1. Decodes the JWT from /store/customers/me/contact — extracts new_value
|
|
18
|
+
* and contact_type without any database lookup.
|
|
19
|
+
* 2. Validates the OTP code against the stored hashed record.
|
|
20
|
+
* 3. Runs updateContactWorkflow which atomically:
|
|
21
|
+
* - Writes new_value to customer.phone / customer.email
|
|
22
|
+
* - Sets phone_verified / email_verified = true
|
|
23
|
+
* - Updates provider_identity.entity_id (phonepass / emailpass) when the
|
|
24
|
+
* changed field is the active login identifier.
|
|
25
|
+
* 4. Returns the updated customer + a fresh JWT so the caller is immediately
|
|
26
|
+
* re-authenticated with the new identity.
|
|
27
|
+
*
|
|
28
|
+
* Request body: { token: string; code: string }
|
|
29
|
+
*/
|
|
30
|
+
const POST = async (req, res) => {
|
|
31
|
+
const customerId = req.auth_context.actor_id;
|
|
32
|
+
const { token, code } = (req.body ?? {});
|
|
33
|
+
if (!token) {
|
|
34
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "token is required");
|
|
35
|
+
}
|
|
36
|
+
if (!code) {
|
|
37
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "code is required");
|
|
38
|
+
}
|
|
39
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
40
|
+
const { http } = config.projectConfig;
|
|
41
|
+
const jwtSecret = http?.jwtSecret || "supersecret";
|
|
42
|
+
const otpService = req.scope.resolve(otp_verification_1.OTP_VERIFICATION_MODULE);
|
|
43
|
+
// Decode the contact-change JWT — new_value lives here, not in metadata
|
|
44
|
+
const decoded = otpService.decodeContactChangeToken(token, jwtSecret);
|
|
45
|
+
// Ensure the token belongs to the authenticated customer
|
|
46
|
+
if (decoded.customer_id !== customerId) {
|
|
47
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Token does not match the authenticated customer");
|
|
48
|
+
}
|
|
49
|
+
// Validate the OTP record (expiry, attempts, already-used)
|
|
50
|
+
// and verify the submitted code against the stored hash.
|
|
51
|
+
// These are the same private-method-backed operations used by verifyOtp().
|
|
52
|
+
await otpService.verifyOtp({ token, code }, jwtSecret);
|
|
53
|
+
const options = (0, config_1.resolveCustomerRegistrationOptions)(config);
|
|
54
|
+
const { result } = await (0, update_contact_workflow_1.default)(req.scope).run({
|
|
55
|
+
input: {
|
|
56
|
+
customer_id: customerId,
|
|
57
|
+
new_value: decoded.new_value,
|
|
58
|
+
contact_type: decoded.contact_type,
|
|
59
|
+
login_identifier: options.login.identifier,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
// Generate a fresh login token so the caller stays authenticated
|
|
63
|
+
let loginToken;
|
|
64
|
+
try {
|
|
65
|
+
const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
66
|
+
const authRow = await knex.raw(`SELECT id FROM auth_identity WHERE app_metadata->>'customer_id' = ? LIMIT 1`, [customerId]);
|
|
67
|
+
const authIdentityId = (authRow.rows?.[0] ?? authRow[0]?.[0])?.id;
|
|
68
|
+
if (authIdentityId) {
|
|
69
|
+
const authService = req.scope.resolve(utils_1.Modules.AUTH);
|
|
70
|
+
const authIdentity = await authService.retrieveAuthIdentity(authIdentityId);
|
|
71
|
+
loginToken = await (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({ authIdentity, actorType: "customer" }, { secret: jwtSecret, expiresIn: http.jwtExpiresIn || "7d" });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Token generation is best-effort; the contact update already succeeded
|
|
76
|
+
}
|
|
77
|
+
return res.status(200).json({
|
|
78
|
+
customer: result.customer,
|
|
79
|
+
token: loginToken ?? null,
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
exports.POST = POST;
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9tZS9jb250YWN0L3ZlcmlmeS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxxREFJa0M7QUFDbEMsMkZBQW9HO0FBQ3BHLGlGQUFvRjtBQUVwRixxREFHaUM7QUFDakMsa0hBQXVGO0FBRXZGOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNJLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFDdkIsR0FBK0IsRUFDL0IsR0FBbUIsRUFDbkIsRUFBRTtJQUNGLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFBO0lBRTVDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBc0MsQ0FBQTtJQUU3RSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksbUJBQVcsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsbUJBQW1CLENBQUMsQ0FBQTtJQUM1RSxDQUFDO0lBQ0QsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsTUFBTSxJQUFJLG1CQUFXLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUE7SUFDM0UsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQ3pFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFBO0lBQ3JDLE1BQU0sU0FBUyxHQUFJLElBQUksRUFBRSxTQUFnQyxJQUFJLGFBQWEsQ0FBQTtJQUUxRSxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBeUIsMENBQXVCLENBQUMsQ0FBQTtJQUVyRix3RUFBd0U7SUFDeEUsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLHdCQUF3QixDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUVyRSx5REFBeUQ7SUFDekQsSUFBSSxPQUFPLENBQUMsV0FBVyxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLGlEQUFpRCxDQUNsRCxDQUFBO0lBQ0gsQ0FBQztJQUVELDJEQUEyRDtJQUMzRCx5REFBeUQ7SUFDekQsMkVBQTJFO0lBQzNFLE1BQU0sVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUV0RCxNQUFNLE9BQU8sR0FBRyxJQUFBLDJDQUFrQyxFQUFDLE1BQTJCLENBQUMsQ0FBQTtJQUUvRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLGlDQUFxQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDNUQsS0FBSyxFQUFFO1lBQ0wsV0FBVyxFQUFFLFVBQVU7WUFDdkIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtZQUNsQyxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVU7U0FDM0M7S0FDRixDQUFDLENBQUE7SUFFRixpRUFBaUU7SUFDakUsSUFBSSxVQUE4QixDQUFBO0lBQ2xDLElBQUksQ0FBQztRQUNILE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBQ3ZFLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FDNUIsNkVBQTZFLEVBQzdFLENBQUMsVUFBVSxDQUFDLENBQ2IsQ0FBQTtRQUNELE1BQU0sY0FBYyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFBO1FBRWpFLElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ25ELE1BQU0sWUFBWSxHQUFHLE1BQU0sV0FBVyxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBQzNFLFVBQVUsR0FBRyxNQUFNLElBQUEsb0RBQStCLEVBQ2hELEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFDdkMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksRUFBRSxDQUM1RCxDQUFBO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCx3RUFBd0U7SUFDMUUsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDMUIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO1FBQ3pCLEtBQUssRUFBRSxVQUFVLElBQUksSUFBSTtLQUMxQixDQUFDLENBQUE7QUFDSixDQUFDLENBQUE7QUExRVksUUFBQSxJQUFJLFFBMEVoQiJ9
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PATCH = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
/**
|
|
6
|
+
* Override of Medusa's built-in PATCH /store/customers/me.
|
|
7
|
+
*
|
|
8
|
+
* Phone and email changes require OTP verification and must go through the
|
|
9
|
+
* dedicated endpoint:
|
|
10
|
+
* POST /store/customers/me/contact — request the change + receive OTP token
|
|
11
|
+
* POST /store/customers/me/contact/verify — submit OTP code to apply the change
|
|
12
|
+
*
|
|
13
|
+
* All other profile fields (first_name, last_name, etc.) are applied directly
|
|
14
|
+
* via the customer service, matching Medusa's default behaviour.
|
|
15
|
+
*/
|
|
16
|
+
const PATCH = async (req, res) => {
|
|
17
|
+
const customerId = req.auth_context.actor_id;
|
|
18
|
+
const body = (req.body ?? {});
|
|
19
|
+
if (body.phone !== undefined) {
|
|
20
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Phone changes require OTP verification. Use POST /store/customers/me/contact to request a change.");
|
|
21
|
+
}
|
|
22
|
+
if (body.email !== undefined) {
|
|
23
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Email changes require OTP verification. Use POST /store/customers/me/contact to request a change.");
|
|
24
|
+
}
|
|
25
|
+
const customerService = req.scope.resolve(utils_1.Modules.CUSTOMER);
|
|
26
|
+
if (Object.keys(body).length > 0) {
|
|
27
|
+
await customerService.updateCustomers(customerId, body);
|
|
28
|
+
}
|
|
29
|
+
const updated = await refetchCustomer(customerId, req.scope);
|
|
30
|
+
return res.status(200).json({ customer: updated });
|
|
31
|
+
};
|
|
32
|
+
exports.PATCH = PATCH;
|
|
33
|
+
async function refetchCustomer(customerId, scope) {
|
|
34
|
+
const remoteQuery = scope.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
|
|
35
|
+
const queryObject = (0, utils_1.remoteQueryObjectFromString)({
|
|
36
|
+
entryPoint: "customer",
|
|
37
|
+
variables: { filters: { id: customerId } },
|
|
38
|
+
fields: [
|
|
39
|
+
"id",
|
|
40
|
+
"email",
|
|
41
|
+
"first_name",
|
|
42
|
+
"last_name",
|
|
43
|
+
"phone",
|
|
44
|
+
"has_account",
|
|
45
|
+
"metadata",
|
|
46
|
+
"created_at",
|
|
47
|
+
"updated_at",
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
const customers = await remoteQuery(queryObject);
|
|
51
|
+
return customers[0];
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9tZS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxxREFLa0M7QUFHbEM7Ozs7Ozs7Ozs7R0FVRztBQUNJLE1BQU0sS0FBSyxHQUFHLEtBQUssRUFDeEIsR0FBK0IsRUFDL0IsR0FBbUIsRUFDbkIsRUFBRTtJQUNGLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFBO0lBQzVDLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQTRCLENBQUE7SUFFeEQsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQzdCLG1HQUFtRyxDQUNwRyxDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUM3QixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUM3QixtR0FBbUcsQ0FDcEcsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLGVBQWUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBeUIsZUFBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBRW5GLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDakMsTUFBTSxlQUFlLENBQUMsZUFBZSxDQUNuQyxVQUFVLEVBQ1YsSUFBNkQsQ0FDOUQsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxNQUFNLGVBQWUsQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzVELE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQTtBQUNwRCxDQUFDLENBQUE7QUFoQ1ksUUFBQSxLQUFLLFNBZ0NqQjtBQUVELEtBQUssVUFBVSxlQUFlLENBQUMsVUFBa0IsRUFBRSxLQUFzQjtJQUN2RSxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQ3pFLE1BQU0sV0FBVyxHQUFHLElBQUEsbUNBQTJCLEVBQUM7UUFDOUMsVUFBVSxFQUFFLFVBQVU7UUFDdEIsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxFQUFFO1FBQzFDLE1BQU0sRUFBRTtZQUNOLElBQUk7WUFDSixPQUFPO1lBQ1AsWUFBWTtZQUNaLFdBQVc7WUFDWCxPQUFPO1lBQ1AsYUFBYTtZQUNiLFVBQVU7WUFDVixZQUFZO1lBQ1osWUFBWTtTQUNiO0tBQ0YsQ0FBQyxDQUFBO0lBQ0YsTUFBTSxTQUFTLEdBQUcsTUFBTSxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDaEQsT0FBTyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDckIsQ0FBQyJ9
|
|
@@ -9,15 +9,12 @@ const otp_verification_1 = require("../../../../../modules/otp-verification/mode
|
|
|
9
9
|
const send_otp_workflow_1 = __importDefault(require("../../../../../workflows/send-otp-workflow"));
|
|
10
10
|
const POST = async (req, res) => {
|
|
11
11
|
const { customer_id, type } = req.body;
|
|
12
|
-
console.log("=== [otp/send] Route Called ===");
|
|
13
|
-
console.log("Request body:", { customer_id, type });
|
|
14
12
|
if (!customer_id) {
|
|
15
13
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "customer_id is required");
|
|
16
14
|
}
|
|
17
15
|
if (!type || !Object.values(otp_verification_1.OtpPurpose).includes(type)) {
|
|
18
16
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Type must be one of: ${Object.values(otp_verification_1.OtpPurpose).join(", ")}`);
|
|
19
17
|
}
|
|
20
|
-
console.log("=== [otp/send] Starting Workflow ===");
|
|
21
18
|
// Execute workflow
|
|
22
19
|
const { result } = await (0, send_otp_workflow_1.default)(req.scope).run({
|
|
23
20
|
input: {
|
|
@@ -25,12 +22,10 @@ const POST = async (req, res) => {
|
|
|
25
22
|
type: type,
|
|
26
23
|
},
|
|
27
24
|
});
|
|
28
|
-
console.log("=== [otp/send] Workflow Completed ===");
|
|
29
|
-
console.log("Result:", { token: result.token, expires_at: result.expires_at });
|
|
30
25
|
return res.status(200).json({
|
|
31
26
|
token: result.token,
|
|
32
27
|
expires_at: result.expires_at,
|
|
33
28
|
});
|
|
34
29
|
};
|
|
35
30
|
exports.POST = POST;
|
|
36
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9vdHAvc2VuZC9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxxREFBdUQ7QUFDdkQsc0dBQTRGO0FBQzVGLG1HQUF3RTtBQUVqRSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDcEUsTUFBTSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsR0FBRyxHQUFHLENBQUMsSUFHakMsQ0FBQTtJQUVELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qix5QkFBeUIsQ0FDMUIsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyw2QkFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQWtCLENBQUMsRUFBRSxDQUFDO1FBQ3JFLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHdCQUF3QixNQUFNLENBQUMsTUFBTSxDQUFDLDZCQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDL0QsQ0FBQTtJQUNILENBQUM7SUFHRCxtQkFBbUI7SUFDbkIsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSwyQkFBZSxFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDdEQsS0FBSyxFQUFFO1lBQ0wsV0FBVztZQUNYLElBQUksRUFBRSxJQUFrQjtTQUN6QjtLQUNGLENBQUMsQ0FBQTtJQUVGLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDMUIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO1FBQ25CLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtLQUM5QixDQUFDLENBQUE7QUFDSixDQUFDLENBQUE7QUFqQ1ksUUFBQSxJQUFJLFFBaUNoQiJ9
|