customer-registration 0.0.115 → 0.0.116
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/api/auth/customer/emailpass/register/route.js +34 -0
- package/.medusa/server/src/api/auth/customer/shared/__tests__/parse-register-body.test.js +87 -0
- package/.medusa/server/src/api/auth/customer/shared/complete-registration-token.js +34 -0
- package/.medusa/server/src/api/auth/customer/shared/customer-login-post.js +3 -1
- package/.medusa/server/src/api/auth/customer/shared/enforce-registration-verification.js +14 -8
- package/.medusa/server/src/api/auth/customer/shared/parse-register-body.js +58 -0
- package/.medusa/server/vitest.config.mjs +8 -0
- package/README.md +24 -13
- package/package.json +1 -1
- package/.medusa/server/src/api/auth/customer/phonepass/route.js +0 -50
|
@@ -0,0 +1,34 @@
|
|
|
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 config_1 = require("../../../../../config");
|
|
6
|
+
const complete_registration_token_1 = require("../../shared/complete-registration-token");
|
|
7
|
+
const parse_register_body_1 = require("../../shared/parse-register-body");
|
|
8
|
+
/**
|
|
9
|
+
* Unified registration: emailpass and/or phonepass via `service.register`, depending on
|
|
10
|
+
* plugin `registration.identifier` and JSON body. Response: `{ token }` (Medusa default).
|
|
11
|
+
*/
|
|
12
|
+
const POST = async (req, res) => {
|
|
13
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
14
|
+
const options = (0, config_1.resolveCustomerRegistrationOptions)(config);
|
|
15
|
+
const registrationIdentifier = options.registration
|
|
16
|
+
.identifier;
|
|
17
|
+
const parsed = (0, parse_register_body_1.parseCustomerRegisterBody)(req.body, registrationIdentifier);
|
|
18
|
+
const service = req.scope.resolve(utils_1.Modules.AUTH);
|
|
19
|
+
const authData = {
|
|
20
|
+
url: req.url,
|
|
21
|
+
headers: req.headers,
|
|
22
|
+
query: req.query,
|
|
23
|
+
body: req.body,
|
|
24
|
+
protocol: req.protocol,
|
|
25
|
+
};
|
|
26
|
+
const provider = parsed.mode === "email" ? "emailpass" : "phonepass";
|
|
27
|
+
const { success, error, authIdentity } = await service.register(provider, authData);
|
|
28
|
+
if (!success || !authIdentity) {
|
|
29
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, error || "Registration failed");
|
|
30
|
+
}
|
|
31
|
+
await (0, complete_registration_token_1.respondWithRegistrationToken)(req, res, authIdentity);
|
|
32
|
+
};
|
|
33
|
+
exports.POST = POST;
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvZW1haWxwYXNzL3JlZ2lzdGVyL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHFEQUlrQztBQUNsQyxrREFHOEI7QUFDOUIsMEZBQXVGO0FBQ3ZGLDBFQUd5QztBQUV6Qzs7O0dBR0c7QUFDSSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDcEUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDekUsTUFBTSxPQUFPLEdBQUcsSUFBQSwyQ0FBa0MsRUFBQyxNQUEyQixDQUFDLENBQUE7SUFDL0UsTUFBTSxzQkFBc0IsR0FBRyxPQUFPLENBQUMsWUFBWTtTQUNoRCxVQUEwQyxDQUFBO0lBRTdDLE1BQU0sTUFBTSxHQUFHLElBQUEsK0NBQXlCLEVBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxDQUFBO0lBRTFFLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUUvQyxNQUFNLFFBQVEsR0FBRztRQUNmLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRztRQUNaLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztRQUNwQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7UUFDaEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO1FBQ2QsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO0tBQ0EsQ0FBQTtJQUN4QixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUE7SUFFcEUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEdBQUcsTUFBTSxPQUFPLENBQUMsUUFBUSxDQUM3RCxRQUFRLEVBQ1IsUUFBUSxDQUNULENBQUE7SUFFRCxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDOUIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsS0FBSyxJQUFJLHFCQUFxQixDQUMvQixDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sSUFBQSwwREFBNEIsRUFBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFlBQXVDLENBQUMsQ0FBQTtBQUN2RixDQUFDLENBQUE7QUFoQ1ksUUFBQSxJQUFJLFFBZ0NoQiJ9
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const parse_register_body_1 = require("../parse-register-body");
|
|
6
|
+
(0, vitest_1.describe)("parseCustomerRegisterBody", () => {
|
|
7
|
+
const okCases = [
|
|
8
|
+
{
|
|
9
|
+
name: "email config",
|
|
10
|
+
body: { email: "a@b.co", password: "x" },
|
|
11
|
+
registrationIdentifier: "email",
|
|
12
|
+
want: { mode: "email" },
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "phone config",
|
|
16
|
+
body: { phone: "+15551", password: "x" },
|
|
17
|
+
registrationIdentifier: "phone",
|
|
18
|
+
want: { mode: "phone" },
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "both config email only",
|
|
22
|
+
body: { email: "u@v.com", password: "Secret1!" },
|
|
23
|
+
registrationIdentifier: "both",
|
|
24
|
+
want: { mode: "email" },
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
vitest_1.it.each(okCases)("$name", ({ body, registrationIdentifier, want }) => {
|
|
28
|
+
(0, vitest_1.expect)((0, parse_register_body_1.parseCustomerRegisterBody)(body, registrationIdentifier)).toEqual(want);
|
|
29
|
+
});
|
|
30
|
+
const errCases = [
|
|
31
|
+
{
|
|
32
|
+
name: "missing password",
|
|
33
|
+
body: { email: "a@b.co" },
|
|
34
|
+
registrationIdentifier: "email",
|
|
35
|
+
wantType: utils_1.MedusaError.Types.INVALID_DATA,
|
|
36
|
+
wantSubstring: "Password is required",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "both rejects phone-only",
|
|
40
|
+
body: { phone: "+1", password: "x" },
|
|
41
|
+
registrationIdentifier: "both",
|
|
42
|
+
wantType: utils_1.MedusaError.Types.INVALID_DATA,
|
|
43
|
+
wantSubstring: "email and password is required first",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "both rejects email+phone",
|
|
47
|
+
body: { email: "a@b.co", phone: "+1", password: "x" },
|
|
48
|
+
registrationIdentifier: "both",
|
|
49
|
+
wantType: utils_1.MedusaError.Types.INVALID_DATA,
|
|
50
|
+
wantSubstring: "only email and password",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "email rejects phone-only",
|
|
54
|
+
body: { phone: "+1", password: "x" },
|
|
55
|
+
registrationIdentifier: "email",
|
|
56
|
+
wantType: utils_1.MedusaError.Types.INVALID_DATA,
|
|
57
|
+
wantSubstring: "Register with your email",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "phone rejects email-only",
|
|
61
|
+
body: { email: "a@b.co", password: "x" },
|
|
62
|
+
registrationIdentifier: "phone",
|
|
63
|
+
wantType: utils_1.MedusaError.Types.INVALID_DATA,
|
|
64
|
+
wantSubstring: "Register with your phone",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "email XOR violated",
|
|
68
|
+
body: { email: "a@b.co", phone: "+1", password: "x" },
|
|
69
|
+
registrationIdentifier: "email",
|
|
70
|
+
wantType: utils_1.MedusaError.Types.INVALID_DATA,
|
|
71
|
+
wantSubstring: "not both",
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
vitest_1.it.each(errCases)("$name", ({ body, registrationIdentifier, wantType, wantSubstring }) => {
|
|
75
|
+
try {
|
|
76
|
+
(0, parse_register_body_1.parseCustomerRegisterBody)(body, registrationIdentifier);
|
|
77
|
+
vitest_1.expect.fail("expected MedusaError");
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
(0, vitest_1.expect)(e).toBeInstanceOf(utils_1.MedusaError);
|
|
81
|
+
const err = e;
|
|
82
|
+
(0, vitest_1.expect)(err.type).toBe(wantType);
|
|
83
|
+
(0, vitest_1.expect)(err.message).toContain(wantSubstring);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtcmVnaXN0ZXItYm9keS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwaS9hdXRoL2N1c3RvbWVyL3NoYXJlZC9fX3Rlc3RzX18vcGFyc2UtcmVnaXN0ZXItYm9keS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQTZDO0FBQzdDLHFEQUF1RDtBQUN2RCxnRUFHK0I7QUFFL0IsSUFBQSxpQkFBUSxFQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtJQUN6QyxNQUFNLE9BQU8sR0FLUjtRQUNIO1lBQ0UsSUFBSSxFQUFFLGNBQWM7WUFDcEIsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO1lBQ3hDLHNCQUFzQixFQUFFLE9BQU87WUFDL0IsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtTQUN4QjtRQUNEO1lBQ0UsSUFBSSxFQUFFLGNBQWM7WUFDcEIsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO1lBQ3hDLHNCQUFzQixFQUFFLE9BQU87WUFDL0IsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtTQUN4QjtRQUNEO1lBQ0UsSUFBSSxFQUFFLHdCQUF3QjtZQUM5QixJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUU7WUFDaEQsc0JBQXNCLEVBQUUsTUFBTTtZQUM5QixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO1NBQ3hCO0tBQ0YsQ0FBQTtJQUVELFdBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsc0JBQXNCLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRTtRQUNuRSxJQUFBLGVBQU0sRUFB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
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.respondWithRegistrationToken = respondWithRegistrationToken;
|
|
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
|
+
* After a successful `authModuleService.register(...)`, issues the standard
|
|
8
|
+
* Medusa registration JWT and responds with `{ token }`.
|
|
9
|
+
*/
|
|
10
|
+
async function respondWithRegistrationToken(req, res, authIdentity) {
|
|
11
|
+
const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
12
|
+
const { http } = config.projectConfig ?? {};
|
|
13
|
+
if (!http?.jwtSecret) {
|
|
14
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "JWT secret is not configured");
|
|
15
|
+
}
|
|
16
|
+
let token;
|
|
17
|
+
try {
|
|
18
|
+
token = await (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({
|
|
19
|
+
authIdentity: authIdentity,
|
|
20
|
+
actorType: "customer",
|
|
21
|
+
}, {
|
|
22
|
+
secret: http.jwtSecret,
|
|
23
|
+
expiresIn: http.jwtExpiresIn || "7d",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (jwtError) {
|
|
27
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `JWT generation failed: ${jwtError instanceof Error ? jwtError.message : "Unknown error"}`);
|
|
28
|
+
}
|
|
29
|
+
if (!token || typeof token !== "string") {
|
|
30
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Failed to generate registration token");
|
|
31
|
+
}
|
|
32
|
+
res.status(200).json({ token });
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxldGUtcmVnaXN0cmF0aW9uLXRva2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwaS9hdXRoL2N1c3RvbWVyL3NoYXJlZC9jb21wbGV0ZS1yZWdpc3RyYXRpb24tdG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFjQSxvRUE2Q0M7QUF6REQscURBR2tDO0FBQ2xDLDJGQUFvRztBQUlwRzs7O0dBR0c7QUFDSSxLQUFLLFVBQVUsNEJBQTRCLENBQ2hELEdBQWtCLEVBQ2xCLEdBQW1CLEVBQ25CLFlBQXFDO0lBRXJDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FFcEQsQ0FBQTtJQUVwQixNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUE7SUFFM0MsSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw4QkFBOEIsQ0FDL0IsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLEtBQXlCLENBQUE7SUFDN0IsSUFBSSxDQUFDO1FBQ0gsS0FBSyxHQUFHLE1BQU0sSUFBQSxvREFBK0IsRUFDM0M7WUFDRSxZQUFZLEVBQUUsWUFBMEM7WUFDeEQsU0FBUyxFQUFFLFVBQVU7U0FDdEIsRUFDRDtZQUNFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUztZQUN0QixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJO1NBQ3JDLENBQ0YsQ0FBQTtJQUNILENBQUM7SUFBQyxPQUFPLFFBQVEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsMEJBQTBCLFFBQVEsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUMzRixDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDeEMsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyx1Q0FBdUMsQ0FDeEMsQ0FBQTtJQUNILENBQUM7SUFFRCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUE7QUFDakMsQ0FBQyJ9
|
|
@@ -57,6 +57,7 @@ async function runEmailPassAuthFlow(req, res, config, authData) {
|
|
|
57
57
|
customerId: resolvedCustomerId,
|
|
58
58
|
req,
|
|
59
59
|
logLabel: email,
|
|
60
|
+
loginChannel: "email",
|
|
60
61
|
});
|
|
61
62
|
await (0, complete_customer_login_1.completeCustomerLogin)(req, res, config, authIdentity, resolvedCustomerId, {
|
|
62
63
|
kind: "email",
|
|
@@ -113,6 +114,7 @@ async function runPhonePassAuthFlow(req, res, config, authData) {
|
|
|
113
114
|
customerId,
|
|
114
115
|
req,
|
|
115
116
|
logLabel,
|
|
117
|
+
loginChannel: "phone",
|
|
116
118
|
});
|
|
117
119
|
await (0, complete_customer_login_1.completeCustomerLogin)(req, res, config, authIdentity, customerId, {
|
|
118
120
|
kind: "phone",
|
|
@@ -137,4 +139,4 @@ async function handleCustomerLogin(req, res) {
|
|
|
137
139
|
}
|
|
138
140
|
return runPhonePassAuthFlow(req, res, config, authData);
|
|
139
141
|
}
|
|
140
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
142
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXItbG9naW4tcG9zdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYXV0aC9jdXN0b21lci9zaGFyZWQvY3VzdG9tZXItbG9naW4tcG9zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWlEQSxvREE0RUM7QUFLRCxvREF3RkM7QUFNRCxrREF3QkM7QUF0UEQscURBSWtDO0FBRWxDLCtDQUF1RTtBQUN2RSx1RUFBMEY7QUFDMUYsMkZBQXFGO0FBQ3JGLG1GQUEyRTtBQUMzRSx5REFHMkI7QUFFM0IsU0FBUyxZQUFZLENBQ25CLE1BQW1DO0lBRW5DLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqQyxJQUFJLFFBQVEsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDekUsT0FBTyxRQUFRLENBQUE7SUFDakIsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN2QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdEIsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2hFLE9BQU8sS0FBVSxDQUFBO1FBQ25CLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQWNEOztHQUVHO0FBQ0ksS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxHQUFrQixFQUNsQixHQUFtQixFQUNuQixNQUE4QyxFQUM5QyxRQUE2QjtJQUU3QixNQUFNLE9B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
|
|
@@ -5,10 +5,14 @@ const utils_1 = require("@medusajs/framework/utils");
|
|
|
5
5
|
const otp_verification_1 = require("../../../../modules/otp-verification");
|
|
6
6
|
const config_1 = require("../../../../config");
|
|
7
7
|
/**
|
|
8
|
-
* Enforces
|
|
9
|
-
*
|
|
8
|
+
* Enforces OTP verification for login according to `registration.identifier` and `require_verification`.
|
|
9
|
+
*
|
|
10
|
+
* - `email` / `phone`: only that channel must be verified.
|
|
11
|
+
* - `both`: only the channel used to log in must be verified (`loginChannel`).
|
|
12
|
+
*
|
|
13
|
+
* When phone is enforced but unverified, includes `pending_phone` UX for pending number changes.
|
|
10
14
|
*/
|
|
11
|
-
async function enforceRegistrationVerification({ customerId, req, logLabel, }) {
|
|
15
|
+
async function enforceRegistrationVerification({ customerId, req, logLabel, loginChannel, }) {
|
|
12
16
|
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
13
17
|
const options = (0, config_1.resolveCustomerRegistrationOptions)(configModule);
|
|
14
18
|
const { identifier, require_verification } = options.registration;
|
|
@@ -17,12 +21,14 @@ async function enforceRegistrationVerification({ customerId, req, logLabel, }) {
|
|
|
17
21
|
}
|
|
18
22
|
const otpService = req.scope.resolve(otp_verification_1.OTP_VERIFICATION_MODULE);
|
|
19
23
|
const verificationStatus = await otpService.getCustomerVerificationByCustomerId(req.scope, customerId);
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
const enforceEmail = identifier === "email" ||
|
|
25
|
+
(identifier === "both" && loginChannel === "email");
|
|
26
|
+
const enforcePhone = identifier === "phone" ||
|
|
27
|
+
(identifier === "both" && loginChannel === "phone");
|
|
28
|
+
if (enforceEmail && !verificationStatus.email_verified) {
|
|
22
29
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Email not verified.");
|
|
23
30
|
}
|
|
24
|
-
if (
|
|
25
|
-
!verificationStatus.phone_verified) {
|
|
31
|
+
if (enforcePhone && !verificationStatus.phone_verified) {
|
|
26
32
|
const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
27
33
|
const row = await knex.raw(`SELECT metadata->>'pending_phone' AS pending_phone FROM customer WHERE id = ? LIMIT 1`, [customerId]);
|
|
28
34
|
const pendingPhone = (row.rows?.[0] ?? row[0]?.[0])?.pending_phone ?? null;
|
|
@@ -35,4 +41,4 @@ async function enforceRegistrationVerification({ customerId, req, logLabel, }) {
|
|
|
35
41
|
: "Phone not verified.");
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5mb3JjZS1yZWdpc3RyYXRpb24tdmVyaWZpY2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwaS9hdXRoL2N1c3RvbWVyL3NoYXJlZC9lbmZvcmNlLXJlZ2lzdHJhdGlvbi12ZXJpZmljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFzQkEsMEVBb0VDO0FBekZELHFEQUdrQztBQUdsQywyRUFBOEU7QUFFOUUsK0NBRzJCO0FBRTNCOzs7Ozs7O0dBT0c7QUFDSSxLQUFLLFVBQVUsK0JBQStCLENBQUMsRUFDcEQsVUFBVSxFQUNWLEdBQUcsRUFDSCxRQUFRLEVBQ1IsWUFBWSxHQVFiO0lBQ0MsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ3BDLGlDQUF5QixDQUFDLGFBQWEsQ0FDeEMsQ0FBQTtJQUNELE1BQU0sT0FBTyxHQUFHLElBQUEsMkNBQWtDLEVBQUMsWUFBWSxDQUFDLENBQUE7SUFDaEUsTUFBTSxFQUFFLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUE7SUFFakUsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDMUIsT0FBTTtJQUNSLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FDbEMsMENBQXVCLENBQ3hCLENBQUE7SUFFRCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sVUFBVSxDQUFDLG1DQUFtQyxDQUM3RSxHQUFHLENBQUMsS0FBK0IsRUFDbkMsVUFBVSxDQUNYLENBQUE7SUFFRCxNQUFNLFlBQVksR0FDaEIsVUFBVSxLQUFLLE9BQU87UUFDdEIsQ0FBQyxVQUFVLEtBQUssTUFBTSxJQUFJLFlBQVksS0FBSyxPQUFPLENBQUMsQ0FBQTtJQUVyRCxNQUFNLFlBQVksR0FDaEIsVUFBVSxLQUFLLE9BQU87UUFDdEIsQ0FBQyxVQUFVLEtBQUssTUFBTSxJQUFJLFlBQVksS0FBSyxPQUFPLENBQUMsQ0FBQTtJQUVyRCxJQUFJLFlBQVksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZELE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHFCQUFxQixDQUN0QixDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksWUFBWSxJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkQsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7UUFDdkUsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUN4Qix1RkFBdUYsRUFDdkYsQ0FBQyxVQUFVLENBQUMsQ0FDYixDQUFBO1FBQ0QsTUFBTSxZQUFZLEdBQ2hCLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxJQUFJLElBQUksQ0FBQTtRQUV2RCxPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFO1lBQ2xELFFBQVE7WUFDUixVQUFVO1NBQ1gsQ0FBQyxDQUFBO1FBRUYsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsWUFBWTtZQUNWLENBQUMsQ0FBQyw4RUFBOEU7WUFDaEYsQ0FBQyxDQUFDLHFCQUFxQixDQUMxQixDQUFBO0lBQ0gsQ0FBQztBQUNILENBQUMifQ==
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCustomerRegisterBody = parseCustomerRegisterBody;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
function nonEmptyString(value) {
|
|
6
|
+
if (typeof value !== "string") {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
const t = value.trim();
|
|
10
|
+
return t.length > 0 ? t : undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Chooses email vs phone registration from the JSON body and enforces `registration.identifier`.
|
|
14
|
+
* Requires `password` (non-empty string). For `"both"`, only `email` + `password` is allowed (no phone-only; no extra phone field).
|
|
15
|
+
*/
|
|
16
|
+
function parseCustomerRegisterBody(body, registrationIdentifier) {
|
|
17
|
+
const record = body !== null && typeof body === "object"
|
|
18
|
+
? body
|
|
19
|
+
: {};
|
|
20
|
+
const password = nonEmptyString(record.password);
|
|
21
|
+
if (!password) {
|
|
22
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Password is required.");
|
|
23
|
+
}
|
|
24
|
+
const email = nonEmptyString(record.email);
|
|
25
|
+
const phone = nonEmptyString(record.phone);
|
|
26
|
+
if (registrationIdentifier === "both") {
|
|
27
|
+
if (phone && !email) {
|
|
28
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Registration with email and password is required first. Use email and password only on this step.");
|
|
29
|
+
}
|
|
30
|
+
if (!email) {
|
|
31
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Email and password are required.");
|
|
32
|
+
}
|
|
33
|
+
if (phone) {
|
|
34
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Provide only email and password. Add your phone when creating the customer.");
|
|
35
|
+
}
|
|
36
|
+
return { mode: "email" };
|
|
37
|
+
}
|
|
38
|
+
if (email && phone) {
|
|
39
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Provide either email or phone, not both.");
|
|
40
|
+
}
|
|
41
|
+
if (!email && !phone) {
|
|
42
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Either email or phone is required.");
|
|
43
|
+
}
|
|
44
|
+
if (registrationIdentifier === "email") {
|
|
45
|
+
if (phone && !email) {
|
|
46
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Phone registration is not enabled for this store. Register with your email.");
|
|
47
|
+
}
|
|
48
|
+
return { mode: "email" };
|
|
49
|
+
}
|
|
50
|
+
if (registrationIdentifier === "phone") {
|
|
51
|
+
if (email && !phone) {
|
|
52
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Email registration is not enabled for this store. Register with your phone number.");
|
|
53
|
+
}
|
|
54
|
+
return { mode: "phone" };
|
|
55
|
+
}
|
|
56
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid registration configuration.");
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtcmVnaXN0ZXItYm9keS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYXV0aC9jdXN0b21lci9zaGFyZWQvcGFyc2UtcmVnaXN0ZXItYm9keS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW9CQSw4REFnRkM7QUFwR0QscURBQXVEO0FBUXZELFNBQVMsY0FBYyxDQUFDLEtBQWM7SUFDcEMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM5QixPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBQ0QsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFBO0lBQ3RCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO0FBQ3JDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQix5QkFBeUIsQ0FDdkMsSUFBYSxFQUNiLHNCQUFvRDtJQUVwRCxNQUFNLE1BQU0sR0FDVixJQUFJLEtBQUssSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVE7UUFDdkMsQ0FBQyxDQUFFLElBQWdDO1FBQ25DLENBQUMsQ0FBQyxFQUFFLENBQUE7SUFFUixNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ2hELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHVCQUF1QixDQUN4QixDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDMUMsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUUxQyxJQUFJLHNCQUFzQixLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQ3RDLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsbUdBQW1HLENBQ3BHLENBQUE7UUFDSCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsa0NBQWtDLENBQ25DLENBQUE7UUFDSCxDQUFDO1FBQ0QsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLDZFQUE2RSxDQUM5RSxDQUFBO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUE7SUFDMUIsQ0FBQztJQUVELElBQUksS0FBSyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ25CLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLDBDQUEwQyxDQUMzQyxDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixvQ0FBb0MsQ0FDckMsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLHNCQUFzQixLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsNkVBQTZFLENBQzlFLENBQUE7UUFDSCxDQUFDO1FBQ0QsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQTtJQUMxQixDQUFDO0lBRUQsSUFBSSxzQkFBc0IsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUN2QyxJQUFJLEtBQUssSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG9GQUFvRixDQUNyRixDQUFBO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUE7SUFDMUIsQ0FBQztJQUVELE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHFDQUFxQyxDQUN0QyxDQUFBO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
export default defineConfig({
|
|
3
|
+
test: {
|
|
4
|
+
include: ["src/**/*.test.ts"],
|
|
5
|
+
exclude: ["node_modules", ".medusa/**", ".medusa/server/**"],
|
|
6
|
+
},
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidml0ZXN0LmNvbmZpZy5tanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi92aXRlc3QuY29uZmlnLm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBRTVDLGVBQWUsWUFBWSxDQUFDO0lBQzFCLElBQUksRUFBRTtRQUNKLE9BQU8sRUFBRSxDQUFDLGtCQUFrQixDQUFDO1FBQzdCLE9BQU8sRUFBRSxDQUFDLGNBQWMsRUFBRSxZQUFZLEVBQUUsbUJBQW1CLENBQUM7S0FDN0Q7Q0FDRixDQUFDLENBQUEifQ==
|
package/README.md
CHANGED
|
@@ -13,7 +13,8 @@ A comprehensive Medusa v2 plugin that provides OTP-based verification for email
|
|
|
13
13
|
- **Throttling & Rate Limiting**: Built-in protection against OTP spam
|
|
14
14
|
- **Database Migrations**: Automatic schema updates for verification columns
|
|
15
15
|
- **Account Deletion Request Flow**: Two-step OTP flow to request and confirm account deletion with optional cancel flow
|
|
16
|
-
- **
|
|
16
|
+
- **Unified registration & login**: **`POST /auth/customer/emailpass/register`** creates an **emailpass** or **phonepass** identity (from JSON body + `registration.identifier`); **`POST /auth/customer/emailpass`** logs in with `{ email, password }` or `{ phone, password }` per `login.identifier`
|
|
17
|
+
- **Per-channel OTP at login**: When `registration.identifier` is **`"both"`** and `require_verification` is on, **email login** only requires **email** verified; **phone login** only requires **phone** verified — you can use either method after completing that channel’s OTP
|
|
17
18
|
- **Authenticated Contact Change**: Dedicated OTP-verified routes for updating phone or email — new value is embedded in the signed JWT, no metadata staging required
|
|
18
19
|
|
|
19
20
|
## Quick Start
|
|
@@ -77,8 +78,6 @@ npx medusa db:migrate
|
|
|
77
78
|
|
|
78
79
|
4. **Use the API** — see [API Endpoints](#api-endpoints) below.
|
|
79
80
|
|
|
80
|
-
📖 **For complete documentation, see [USAGE.md](./USAGE.md)**
|
|
81
|
-
|
|
82
81
|
---
|
|
83
82
|
|
|
84
83
|
## Installation
|
|
@@ -135,7 +134,21 @@ Controls which auth providers are accepted at login. Defaults to `registration.i
|
|
|
135
134
|
| `"phone"` | Same endpoint with `{ "phone", "password" }` only |
|
|
136
135
|
| `"both"` | Same endpoint; **either** email **or** phone (not both) plus `password` in the JSON body |
|
|
137
136
|
|
|
138
|
-
|
|
137
|
+
Login always uses **`POST /auth/customer/emailpass`** (single URL). There is **no** `/auth/customer/phonepass` route; phone registration uses the same **`POST /auth/customer/emailpass/register`** as email registration.
|
|
138
|
+
|
|
139
|
+
Credentials are normally sent in the **JSON body**; the same keys can be supplied on the **query string** for missing fields (see `buildUnifiedLoginAuthData`) — prefer **body** for passwords.
|
|
140
|
+
|
|
141
|
+
### `require_verification` and login
|
|
142
|
+
|
|
143
|
+
When **`registration.require_verification`** is **`true`** (default), login checks OTP flags **for the credential you use** (see [`enforce-registration-verification.ts`](src/api/auth/customer/shared/enforce-registration-verification.ts)):
|
|
144
|
+
|
|
145
|
+
- **`registration.identifier: "email"`** — signing in with **email** requires **`email_verified`**.
|
|
146
|
+
- **`registration.identifier: "phone"`** — signing in with **phone** requires **`phone_verified`**.
|
|
147
|
+
- **`registration.identifier: "both"`** — signing in with **email** requires **`email_verified`** only (phone may still be unverified). Signing in with **phone** requires **`phone_verified`** only (email may still be unverified).
|
|
148
|
+
|
|
149
|
+
So with **`both`**, a customer can **log in with email** after email OTP even if **phone** OTP is still pending, and the reverse for phone login.
|
|
150
|
+
|
|
151
|
+
When **`require_verification`** is **`false`**, these checks are skipped.
|
|
139
152
|
|
|
140
153
|
### Full options reference
|
|
141
154
|
|
|
@@ -227,13 +240,12 @@ POST /store/customers/otp/verify
|
|
|
227
240
|
|
|
228
241
|
### Login & registration (customer auth)
|
|
229
242
|
|
|
230
|
-
Implementation lives under [`src/api/auth/customer/`](src/api/auth/customer/): **`emailpass/`** (login
|
|
243
|
+
Implementation lives under [`src/api/auth/customer/`](src/api/auth/customer/): **`emailpass/`** (login, **register**, password reset), **`shared/`** (credential parsing, verification, JWT helpers).
|
|
231
244
|
|
|
232
245
|
| Endpoint | Method | Description |
|
|
233
246
|
|---|---|---|
|
|
234
|
-
| `/auth/customer/emailpass` | POST | **
|
|
235
|
-
| `/auth/customer/emailpass
|
|
236
|
-
| `/auth/customer/phonepass` | POST | Create **phonepass** identity only — [`phonepass/route.ts`](src/api/auth/customer/phonepass/route.ts). Returns a short-lived JWT for `POST /store/customers`. **Not** used for login. |
|
|
247
|
+
| `/auth/customer/emailpass/register` | POST | **Register.** JSON: `password` plus identifier per `registration.identifier` — **`email`** only for `"email"` and `"both"` (for `"both"`, phone is added on `POST /store/customers`); **`phone`** only for `"phone"`. Dispatches to `register("emailpass")` or `register("phonepass")`. Response: `{ "token" }` (pre-customer JWT). See [`emailpass/register/route.ts`](src/api/auth/customer/emailpass/register/route.ts), [`parse-register-body.ts`](src/api/auth/customer/shared/parse-register-body.ts), [`complete-registration-token.ts`](src/api/auth/customer/shared/complete-registration-token.ts). |
|
|
248
|
+
| `/auth/customer/emailpass` | POST | **Login.** JSON: `password` plus **exactly one** of `email` or `phone` (XOR), validated against `login.identifier`. Optional query params can fill missing keys (body wins). [`emailpass/route.ts`](src/api/auth/customer/emailpass/route.ts) → [`handleCustomerLogin`](src/api/auth/customer/shared/customer-login-post.ts). |
|
|
237
249
|
|
|
238
250
|
Password reset URLs are unchanged; see [Password Reset](#password-reset).
|
|
239
251
|
|
|
@@ -416,8 +428,8 @@ export default defineConfig({
|
|
|
416
428
|
### 2. Registration flow
|
|
417
429
|
|
|
418
430
|
```bash
|
|
419
|
-
# Step 1 — create phonepass auth identity
|
|
420
|
-
POST /auth/customer/
|
|
431
|
+
# Step 1 — create phonepass auth identity (unified register URL)
|
|
432
|
+
POST /auth/customer/emailpass/register
|
|
421
433
|
{ "phone": "+15551234567", "password": "SecretPass1!" }
|
|
422
434
|
# Response: { "token": "<pre-customer jwt>" }
|
|
423
435
|
|
|
@@ -524,12 +536,11 @@ await completePasswordReset(
|
|
|
524
536
|
- Node.js >= 20
|
|
525
537
|
- Notification module configured with at least one provider (email/SMS)
|
|
526
538
|
- Database migrations applied (`npx medusa db:migrate`)
|
|
527
|
-
-
|
|
539
|
+
- **`phonepass`** auth provider registered in `medusa-config` (required when customers can **register** or **log in** with phone — i.e. `registration.identifier` and/or `login.identifier` is `"phone"` or `"both"`)
|
|
528
540
|
|
|
529
541
|
## Documentation
|
|
530
542
|
|
|
531
|
-
|
|
532
|
-
- **[README.md](./README.md)** — This file (overview and quick start)
|
|
543
|
+
This **README** is the main overview: configuration, auth routes, OTP behaviour, and API tables.
|
|
533
544
|
|
|
534
545
|
## Development
|
|
535
546
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "customer-registration",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.116",
|
|
4
4
|
"description": "Medusa plugin that overrides store customer registration, enforces email/phone verification flags, and provides OTP management module.",
|
|
5
5
|
"author": "Medusa (https://medusajs.com)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1,50 +0,0 @@
|
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvcGhvbmVwYXNzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLHFEQUlrQztBQUNsQywyRkFBb0c7QUFFcEc7Ozs7OztHQU1HO0FBQ0ksTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQ3pFLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUUvQyxNQUFNLFFBQVEsR0FBRztRQUNmLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRztRQUNaLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztRQUNwQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7UUFDaEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO1FBQ2QsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO0tBQ0EsQ0FBQTtJQUV4QixNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxRQUFRLENBQzdELFdBQVcsRUFDWCxRQUFRLENBQ1QsQ0FBQTtJQUVELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM5QixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixLQUFLLElBQUkscUJBQXFCLENBQy9CLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUE7SUFFckMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw4QkFBOEIsQ0FDL0IsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLEtBQXlCLENBQUE7SUFDN0IsSUFBSSxDQUFDO1FBQ0gsS0FBSyxHQUFHLE1BQU0sSUFBQSxvREFBK0IsRUFDM0M7WUFDRSxZQUFZO1lBQ1osU0FBUyxFQUFFLFVBQVU7U0FDdEIsRUFDRDtZQUNFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUztZQUN0QixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJO1NBQ3JDLENBQ0YsQ0FBQTtJQUNILENBQUM7SUFBQyxPQUFPLFFBQVEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsMEJBQTBCLFFBQVEsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUMzRixDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDeEMsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyx1Q0FBdUMsQ0FDeEMsQ0FBQTtJQUNILENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtBQUN4QyxDQUFDLENBQUE7QUE1RFksUUFBQSxJQUFJLFFBNERoQiJ9
|