@perseidesjs/auth-otp 2.0.0
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/.github/assets/dark_mode.png +0 -0
- package/.github/assets/light_mode.png +0 -0
- package/.github/assets/preview.gif +0 -0
- package/.medusa/server/src/api/auth/[actor_type]/otp/generate/route.js +35 -0
- package/.medusa/server/src/api/auth/[actor_type]/otp/generate/validators.js +8 -0
- package/.medusa/server/src/api/auth/[actor_type]/otp/pre-register/route.js +35 -0
- package/.medusa/server/src/api/auth/[actor_type]/otp/pre-register/validators.js +8 -0
- package/.medusa/server/src/api/auth/[actor_type]/otp/verify/route.js +51 -0
- package/.medusa/server/src/api/auth/[actor_type]/otp/verify/validators.js +9 -0
- package/.medusa/server/src/api/middlewares.js +32 -0
- package/.medusa/server/src/providers/otp/index.d.ts +2 -0
- package/.medusa/server/src/providers/otp/index.js +12 -0
- package/.medusa/server/src/providers/otp/services/otp.d.ts +17 -0
- package/.medusa/server/src/providers/otp/services/otp.js +130 -0
- package/.medusa/server/src/types/index.d.ts +111 -0
- package/.medusa/server/src/types/index.js +9 -0
- package/.medusa/server/src/utils/get-plugin-options.d.ts +20 -0
- package/.medusa/server/src/utils/get-plugin-options.js +31 -0
- package/.medusa/server/src/utils/otp.d.ts +14 -0
- package/.medusa/server/src/utils/otp.js +43 -0
- package/.medusa/server/src/workflows/generate-otp.d.ts +16 -0
- package/.medusa/server/src/workflows/generate-otp.js +43 -0
- package/.medusa/server/src/workflows/index.d.ts +20 -0
- package/.medusa/server/src/workflows/index.js +15 -0
- package/.medusa/server/src/workflows/pre-register-check.js +49 -0
- package/.medusa/server/src/workflows/steps/generate-otp-step.d.ts +13 -0
- package/.medusa/server/src/workflows/steps/generate-otp-step.js +28 -0
- package/.medusa/server/src/workflows/steps/get-actor-step.d.ts +17 -0
- package/.medusa/server/src/workflows/steps/get-actor-step.js +39 -0
- package/.medusa/server/src/workflows/steps/get-auth-identity-step.d.ts +18 -0
- package/.medusa/server/src/workflows/steps/get-auth-identity-step.js +37 -0
- package/.medusa/server/src/workflows/steps/get-stored-otp-step.d.ts +13 -0
- package/.medusa/server/src/workflows/steps/get-stored-otp-step.js +23 -0
- package/.medusa/server/src/workflows/steps/pre-register-check-actor-existence.js +19 -0
- package/.medusa/server/src/workflows/steps/validate-otp-step.d.ts +13 -0
- package/.medusa/server/src/workflows/steps/validate-otp-step.js +18 -0
- package/.medusa/server/src/workflows/verify-otp.d.ts +20 -0
- package/.medusa/server/src/workflows/verify-otp.js +43 -0
- package/CHANGELOG.md +30 -0
- package/LICENSE.md +21 -0
- package/README.md +29 -0
- package/package.json +84 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
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 get_plugin_options_1 = __importDefault(require("../../../../../utils/get-plugin-options"));
|
|
9
|
+
const generate_otp_1 = __importDefault(require("../../../../../workflows/generate-otp"));
|
|
10
|
+
const POST = async (req, res) => {
|
|
11
|
+
const logger = req.scope.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
|
|
12
|
+
const { identifier } = req.validatedBody;
|
|
13
|
+
const actorType = req.params.actor_type;
|
|
14
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
15
|
+
const pluginOptions = (0, get_plugin_options_1.default)(configModule);
|
|
16
|
+
const accessorsPerActor = pluginOptions.accessorsPerActor[actorType];
|
|
17
|
+
await (0, generate_otp_1.default)(req.scope).run({
|
|
18
|
+
input: {
|
|
19
|
+
identifier,
|
|
20
|
+
actorType,
|
|
21
|
+
accessorsPerActor
|
|
22
|
+
}
|
|
23
|
+
}).catch((error) => {
|
|
24
|
+
if (pluginOptions.http?.alwaysReturnSuccess) {
|
|
25
|
+
if (pluginOptions.http.warnOnError) {
|
|
26
|
+
logger.error(error);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
throw error;
|
|
31
|
+
});
|
|
32
|
+
res.send({ message: 'If an account exists with this identifier, an OTP will be sent.' });
|
|
33
|
+
};
|
|
34
|
+
exports.POST = POST;
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvW2FjdG9yX3R5cGVdL290cC9nZW5lcmF0ZS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFLQSxxREFBcUU7QUFDckUsaUdBQXNFO0FBQ3RFLHlGQUF1RTtBQUVoRSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQ3ZCLEdBQXNELEVBQ3RELEdBQW1CLEVBQ25CLEVBQUU7SUFDRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUVsRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQTtJQUN4QyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQTtJQUV2QyxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUMvRSxNQUFNLGFBQWEsR0FBRyxJQUFBLDRCQUFnQixFQUFDLFlBQVksQ0FBQyxDQUFBO0lBRXBELE1BQU0saUJBQWlCLEdBQUcsYUFBYSxDQUFDLGlCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBRXJFLE1BQU0sSUFBQSxzQkFBbUIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3ZDLEtBQUssRUFBRTtZQUNMLFVBQVU7WUFDVixTQUFTO1lBQ1QsaUJBQWlCO1NBQ2xCO0tBQ0YsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQ2pCLElBQUksYUFBYSxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRSxDQUFDO1lBQzVDLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNyQixDQUFDO1lBQ0QsT0FBTTtRQUNSLENBQUM7UUFDRCxNQUFNLEtBQUssQ0FBQTtJQUNiLENBQUMsQ0FBQyxDQUFBO0lBRUYsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxpRUFBaUUsRUFBRSxDQUFDLENBQUE7QUFDMUYsQ0FBQyxDQUFBO0FBL0JZLFFBQUEsSUFBSSxRQStCaEIifQ==
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostAuthActorTypeOtpGenerateSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.PostAuthActorTypeOtpGenerateSchema = zod_1.z.object({
|
|
6
|
+
identifier: zod_1.z.string().min(1),
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYXV0aC9bYWN0b3JfdHlwZV0vb3RwL2dlbmVyYXRlL3ZhbGlkYXRvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQXVCO0FBR1YsUUFBQSxrQ0FBa0MsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3pELFVBQVUsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztDQUM5QixDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,35 @@
|
|
|
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 get_plugin_options_1 = __importDefault(require("../../../../../utils/get-plugin-options"));
|
|
9
|
+
const pre_register_check_1 = __importDefault(require("../../../../../workflows/pre-register-check"));
|
|
10
|
+
const POST = async (req, res) => {
|
|
11
|
+
const logger = req.scope.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
|
|
12
|
+
const { identifier } = req.validatedBody;
|
|
13
|
+
const actorType = req.params.actor_type;
|
|
14
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
15
|
+
const pluginOptions = (0, get_plugin_options_1.default)(configModule);
|
|
16
|
+
const accessorsPerActor = pluginOptions.accessorsPerActor[actorType];
|
|
17
|
+
await (0, pre_register_check_1.default)(req.scope).run({
|
|
18
|
+
input: {
|
|
19
|
+
identifier,
|
|
20
|
+
actorType,
|
|
21
|
+
accessorsPerActor
|
|
22
|
+
}
|
|
23
|
+
}).catch((error) => {
|
|
24
|
+
if (pluginOptions.http?.alwaysReturnSuccess) {
|
|
25
|
+
if (pluginOptions.http.warnOnError) {
|
|
26
|
+
logger.error(error);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
throw error;
|
|
31
|
+
});
|
|
32
|
+
res.send({ message: 'Please validate the OTP to continue with the registration process.' });
|
|
33
|
+
};
|
|
34
|
+
exports.POST = POST;
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvW2FjdG9yX3R5cGVdL290cC9wcmUtcmVnaXN0ZXIvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBS0EscURBQXFFO0FBQ3JFLGlHQUFzRTtBQUV0RSxxR0FBa0Y7QUFFM0UsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUN2QixHQUF5RCxFQUN6RCxHQUFtQixFQUNuQixFQUFFO0lBQ0YsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsTUFBTSxDQUFDLENBQUE7SUFFbEUsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxhQUFhLENBQUE7SUFDeEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUE7SUFFdkMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDL0UsTUFBTSxhQUFhLEdBQUcsSUFBQSw0QkFBZ0IsRUFBQyxZQUFZLENBQUMsQ0FBQTtJQUVwRCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxpQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUVyRSxNQUFNLElBQUEsNEJBQXdCLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUM1QyxLQUFLLEVBQUU7WUFDTCxVQUFVO1lBQ1YsU0FBUztZQUNULGlCQUFpQjtTQUNsQjtLQUNGLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtRQUNqQixJQUFJLGFBQWEsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQztZQUM1QyxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ25DLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDckIsQ0FBQztZQUNELE9BQU07UUFDUixDQUFDO1FBQ0QsTUFBTSxLQUFLLENBQUE7SUFDYixDQUFDLENBQUMsQ0FBQTtJQUVGLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsb0VBQW9FLEVBQUUsQ0FBQyxDQUFBO0FBQzdGLENBQUMsQ0FBQTtBQS9CWSxRQUFBLElBQUksUUErQmhCIn0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostAuthActorTypeOtpPreRegisterSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.PostAuthActorTypeOtpPreRegisterSchema = zod_1.z.object({
|
|
6
|
+
identifier: zod_1.z.string().min(1),
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYXV0aC9bYWN0b3JfdHlwZV0vb3RwL3ByZS1yZWdpc3Rlci92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUF1QjtBQUdWLFFBQUEscUNBQXFDLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM1RCxVQUFVLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Q0FDOUIsQ0FBQyxDQUFBIn0=
|
|
@@ -0,0 +1,51 @@
|
|
|
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 get_plugin_options_1 = __importDefault(require("../../../../../utils/get-plugin-options"));
|
|
9
|
+
const verify_otp_1 = __importDefault(require("../../../../../workflows/verify-otp"));
|
|
10
|
+
const generate_jwt_token_1 = require("@medusajs/medusa/api/auth/utils/generate-jwt-token");
|
|
11
|
+
const framework_1 = require("@medusajs/framework");
|
|
12
|
+
const POST = async (req, res) => {
|
|
13
|
+
const { identifier, otp } = req.validatedBody;
|
|
14
|
+
const actorType = req.params.actor_type;
|
|
15
|
+
const configModule = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
|
|
16
|
+
const pluginOptions = (0, get_plugin_options_1.default)(configModule);
|
|
17
|
+
try {
|
|
18
|
+
const { result } = await (0, verify_otp_1.default)(req.scope).run({
|
|
19
|
+
input: {
|
|
20
|
+
identifier,
|
|
21
|
+
otp,
|
|
22
|
+
actorType,
|
|
23
|
+
accessorsPerActor: pluginOptions.accessorsPerActor[actorType]
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
if (result.isValid) {
|
|
27
|
+
const { http } = configModule.projectConfig;
|
|
28
|
+
const token = (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({ authIdentity: result.authIdentity, actorType }, {
|
|
29
|
+
secret: http.jwtSecret,
|
|
30
|
+
expiresIn: http.jwtExpiresIn
|
|
31
|
+
});
|
|
32
|
+
res.send({
|
|
33
|
+
token
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Invalid OTP`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (pluginOptions.http?.alwaysReturnSuccess) {
|
|
42
|
+
if (pluginOptions.http.warnOnError) {
|
|
43
|
+
framework_1.logger.error(error);
|
|
44
|
+
}
|
|
45
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Invalid OTP`);
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
exports.POST = POST;
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvW2FjdG9yX3R5cGVdL290cC92ZXJpZnkvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBS0EscURBQWtGO0FBQ2xGLGlHQUFzRTtBQUN0RSxxRkFBbUU7QUFDbkUsMkZBQW9HO0FBQ3BHLG1EQUE0QztBQUVyQyxNQUFNLElBQUksR0FBRyxLQUFLLEVBQ3ZCLEdBQW9ELEVBQ3BELEdBQW1CLEVBQ25CLEVBQUU7SUFDRixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxhQUFhLENBQUE7SUFDN0MsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUE7SUFFdkMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDL0UsTUFBTSxhQUFhLEdBQUcsSUFBQSw0QkFBZ0IsRUFBQyxZQUFZLENBQUMsQ0FBQTtJQUVwRCxJQUFJLENBQUM7UUFHSCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLG9CQUFpQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDeEQsS0FBSyxFQUFFO2dCQUNMLFVBQVU7Z0JBQ1YsR0FBRztnQkFDSCxTQUFTO2dCQUNULGlCQUFpQixFQUFFLGFBQWEsQ0FBQyxpQkFBa0IsQ0FBQyxTQUFTLENBQUM7YUFDL0Q7U0FDRixDQUFDLENBQUE7UUFFRixJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQixNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQTtZQUMzQyxNQUFNLEtBQUssR0FBRyxJQUFBLG9EQUErQixFQUFDLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFhLEVBQUUsU0FBUyxFQUFFLEVBQUU7Z0JBQy9GLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDdEIsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZO2FBQzdCLENBQUMsQ0FBQTtZQUVGLEdBQUcsQ0FBQyxJQUFJLENBQUM7Z0JBQ1AsS0FBSzthQUNOLENBQUMsQ0FBQTtRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLG1CQUFXLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLGFBQWEsQ0FBQyxDQUFBO1FBQ3RFLENBQUM7SUFDSCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLElBQUksYUFBYSxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRSxDQUFDO1lBQzVDLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbkMsa0JBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDckIsQ0FBQztZQUNELE1BQU0sSUFBSSxtQkFBVyxDQUFDLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQTtRQUN0RSxDQUFDO1FBQ0QsTUFBTSxLQUFLLENBQUE7SUFDYixDQUFDO0FBRUgsQ0FBQyxDQUFBO0FBN0NZLFFBQUEsSUFBSSxRQTZDaEIifQ==
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostAuthActorTypeOtpVerifySchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.PostAuthActorTypeOtpVerifySchema = zod_1.z.object({
|
|
6
|
+
identifier: zod_1.z.string().min(1),
|
|
7
|
+
otp: zod_1.z.string().min(1),
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvYXV0aC9bYWN0b3JfdHlwZV0vb3RwL3ZlcmlmeS92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUF1QjtBQUdWLFFBQUEsZ0NBQWdDLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUN2RCxVQUFVLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDN0IsR0FBRyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0NBQ3ZCLENBQUMsQ0FBQSJ9
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const http_1 = require("@medusajs/framework/http");
|
|
4
|
+
const validators_1 = require("./auth/[actor_type]/otp/generate/validators");
|
|
5
|
+
const validators_2 = require("./auth/[actor_type]/otp/verify/validators");
|
|
6
|
+
const validators_3 = require("./auth/[actor_type]/otp/pre-register/validators");
|
|
7
|
+
exports.default = (0, http_1.defineMiddlewares)({
|
|
8
|
+
routes: [
|
|
9
|
+
{
|
|
10
|
+
matcher: "/auth/:actor_type/otp/generate",
|
|
11
|
+
method: "POST",
|
|
12
|
+
middlewares: [
|
|
13
|
+
(0, http_1.validateAndTransformBody)(validators_1.PostAuthActorTypeOtpGenerateSchema),
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
matcher: "/auth/:actor_type/otp/verify",
|
|
18
|
+
method: "POST",
|
|
19
|
+
middlewares: [
|
|
20
|
+
(0, http_1.validateAndTransformBody)(validators_2.PostAuthActorTypeOtpVerifySchema),
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
matcher: "/auth/:actor_type/otp/pre-register",
|
|
25
|
+
method: "POST",
|
|
26
|
+
middlewares: [
|
|
27
|
+
(0, http_1.validateAndTransformBody)(validators_3.PostAuthActorTypeOtpPreRegisterSchema),
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBR2lDO0FBQ2pDLDRFQUFnRztBQUNoRywwRUFBNEY7QUFDNUYsZ0ZBQXVHO0FBRXZHLGtCQUFlLElBQUEsd0JBQWlCLEVBQUM7SUFDL0IsTUFBTSxFQUFFO1FBQ047WUFDRSxPQUFPLEVBQUUsZ0NBQWdDO1lBQ3pDLE1BQU0sRUFBRSxNQUFNO1lBQ2QsV0FBVyxFQUFFO2dCQUNYLElBQUEsK0JBQXdCLEVBQUMsK0NBQWtDLENBQUM7YUFDN0Q7U0FDRjtRQUNEO1lBQ0UsT0FBTyxFQUFFLDhCQUE4QjtZQUN2QyxNQUFNLEVBQUUsTUFBTTtZQUNkLFdBQVcsRUFBRTtnQkFDWCxJQUFBLCtCQUF3QixFQUFDLDZDQUFnQyxDQUFDO2FBQzNEO1NBQ0Y7UUFDRDtZQUNFLE9BQU8sRUFBRSxvQ0FBb0M7WUFDN0MsTUFBTSxFQUFFLE1BQU07WUFDZCxXQUFXLEVBQUU7Z0JBQ1gsSUFBQSwrQkFBd0IsRUFBQyxrREFBcUMsQ0FBQzthQUNoRTtTQUNGO0tBQ0Y7Q0FDRixDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
const otp_1 = __importDefault(require("./services/otp"));
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const services = [otp_1.default];
|
|
9
|
+
exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.AUTH, {
|
|
10
|
+
services
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL290cC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlEQUFtRDtBQUNuRCxxREFHa0M7QUFFbEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxhQUFzQixDQUFDLENBQUE7QUFFekMsa0JBQWUsSUFBQSxzQkFBYyxFQUFDLGVBQU8sQ0FBQyxJQUFJLEVBQUU7SUFDMUMsUUFBUTtDQUNULENBQUMsQ0FBQSJ9
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AuthenticationInput, AuthIdentityProviderService, AuthenticationResponse, ICacheService, Logger } from "@medusajs/framework/types";
|
|
2
|
+
import { AbstractAuthModuleProvider, ContainerRegistrationKeys, Modules } from "@medusajs/framework/utils";
|
|
3
|
+
type InjectedDependencies = {
|
|
4
|
+
[Modules.CACHE]: ICacheService;
|
|
5
|
+
[ContainerRegistrationKeys.LOGGER]: Logger;
|
|
6
|
+
};
|
|
7
|
+
export declare const OTP_RETURN_KEY = "otp_generated";
|
|
8
|
+
export declare const RECENTLY_REGISTERED_KEY = "recently_registered";
|
|
9
|
+
export declare class OtpAuthProviderService extends AbstractAuthModuleProvider {
|
|
10
|
+
static identifier: string;
|
|
11
|
+
protected cacheService_: ICacheService;
|
|
12
|
+
protected logger_: Logger;
|
|
13
|
+
constructor(container: InjectedDependencies);
|
|
14
|
+
authenticate(data: AuthenticationInput, authIdentityProviderService: AuthIdentityProviderService): Promise<AuthenticationResponse>;
|
|
15
|
+
register(data: AuthenticationInput, authIdentityProviderService: AuthIdentityProviderService): Promise<AuthenticationResponse>;
|
|
16
|
+
}
|
|
17
|
+
export default OtpAuthProviderService;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OtpAuthProviderService = exports.RECENTLY_REGISTERED_KEY = exports.OTP_RETURN_KEY = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
exports.OTP_RETURN_KEY = "otp_generated";
|
|
6
|
+
// Special key used to store recently registered identifiers for direct authentication
|
|
7
|
+
exports.RECENTLY_REGISTERED_KEY = "recently_registered";
|
|
8
|
+
class OtpAuthProviderService extends utils_1.AbstractAuthModuleProvider {
|
|
9
|
+
constructor(container) {
|
|
10
|
+
super();
|
|
11
|
+
this.cacheService_ = container[utils_1.Modules.CACHE];
|
|
12
|
+
this.logger_ = container[utils_1.ContainerRegistrationKeys.LOGGER];
|
|
13
|
+
}
|
|
14
|
+
async authenticate(data, authIdentityProviderService) {
|
|
15
|
+
if (!(0, utils_1.isDefined)(data.body?.identifier)) {
|
|
16
|
+
return {
|
|
17
|
+
success: false,
|
|
18
|
+
error: "Identifier is required"
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const identifier = data.body.identifier;
|
|
22
|
+
try {
|
|
23
|
+
// Check if this is a recently registered user (within the TTL window)
|
|
24
|
+
const isRecentlyRegistered = await this.cacheService_.get(`${exports.RECENTLY_REGISTERED_KEY}:${identifier}:${data.body.otp}`);
|
|
25
|
+
if (isRecentlyRegistered === "true") {
|
|
26
|
+
// If recently registered, allow direct authentication without OTP
|
|
27
|
+
try {
|
|
28
|
+
const authIdentity = await authIdentityProviderService.retrieve({
|
|
29
|
+
entity_id: identifier,
|
|
30
|
+
});
|
|
31
|
+
await this.cacheService_.invalidate(`${exports.RECENTLY_REGISTERED_KEY}:${identifier}`);
|
|
32
|
+
return {
|
|
33
|
+
success: true,
|
|
34
|
+
authIdentity
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
error: "Authentication failed"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// If not recently registered and no OTP provided, we need to generate a new OTP
|
|
45
|
+
if (!(0, utils_1.isDefined)(data.body?.otp)) {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
error: "OTP is required for authentication"
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Verify the OTP
|
|
52
|
+
const otp = await this.cacheService_.get(`otp:${identifier}`);
|
|
53
|
+
if (otp !== data.body.otp) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: "Invalid OTP"
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// OTP is valid, retrieve the auth identity
|
|
60
|
+
const authIdentity = await authIdentityProviderService.retrieve({
|
|
61
|
+
entity_id: identifier,
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
success: true,
|
|
65
|
+
authIdentity
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
this.logger_.error(error);
|
|
70
|
+
return {
|
|
71
|
+
success: false,
|
|
72
|
+
error: "Authentication failed"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async register(data, authIdentityProviderService) {
|
|
77
|
+
if (!(0, utils_1.isDefined)(data.body?.identifier)) {
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
error: "Identifier is required"
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!(0, utils_1.isDefined)(data.body?.otp)) {
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
error: "OTP is required"
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const otp = await this.cacheService_.get(`otp:pre-register:${data.body.identifier}`);
|
|
90
|
+
if (otp !== data.body.otp) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
error: "Invalid OTP"
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
let authIdentity;
|
|
97
|
+
try {
|
|
98
|
+
authIdentity = await authIdentityProviderService.retrieve({
|
|
99
|
+
entity_id: data.body.identifier,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (!(error instanceof utils_1.MedusaError))
|
|
104
|
+
return { success: false, error: JSON.stringify(error) };
|
|
105
|
+
if (error.type !== utils_1.MedusaError.Types.NOT_FOUND)
|
|
106
|
+
return { success: false, error: error.message };
|
|
107
|
+
// If the identity is not found, we create it
|
|
108
|
+
authIdentity = await authIdentityProviderService.create({
|
|
109
|
+
entity_id: data.body.identifier
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (!authIdentity) {
|
|
113
|
+
return {
|
|
114
|
+
success: false,
|
|
115
|
+
error: "Failed to create identity"
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const REGISTER_TTL = 60; // seconds
|
|
119
|
+
// Mark this identifier as recently registered to allow direct one time authentication
|
|
120
|
+
await this.cacheService_.set(`${exports.RECENTLY_REGISTERED_KEY}:${data.body.identifier}:${otp}`, "true", REGISTER_TTL);
|
|
121
|
+
return {
|
|
122
|
+
success: true,
|
|
123
|
+
authIdentity
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.OtpAuthProviderService = OtpAuthProviderService;
|
|
128
|
+
OtpAuthProviderService.identifier = "otp";
|
|
129
|
+
exports.default = OtpAuthProviderService;
|
|
130
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9vdHAvc2VydmljZXMvb3RwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUFrSTtBQU9ySCxRQUFBLGNBQWMsR0FBRyxlQUFlLENBQUE7QUFDN0Msc0ZBQXNGO0FBQ3pFLFFBQUEsdUJBQXVCLEdBQUcscUJBQXFCLENBQUE7QUFFNUQsTUFBYSxzQkFBdUIsU0FBUSxrQ0FBMEI7SUFNcEUsWUFBWSxTQUErQjtRQUN6QyxLQUFLLEVBQUUsQ0FBQTtRQUNQLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDLGVBQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUM3QyxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUM1RCxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVksQ0FDaEIsSUFBeUIsRUFDekIsMkJBQXdEO1FBRXhELElBQUksQ0FBQyxJQUFBLGlCQUFTLEVBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsS0FBSyxFQUFFLHdCQUF3QjthQUNoQyxDQUFBO1FBQ0gsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFLLENBQUMsVUFBVSxDQUFBO1FBRXhDLElBQUksQ0FBQztZQUNILHNFQUFzRTtZQUN0RSxNQUFNLG9CQUFvQixHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRywrQkFBdUIsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLElBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFBO1lBRXZILElBQUksb0JBQW9CLEtBQUssTUFBTSxFQUFFLENBQUM7Z0JBQ3BDLGtFQUFrRTtnQkFDbEUsSUFBSSxDQUFDO29CQUNI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
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for the OTP authentication plugin.
|
|
3
|
+
*
|
|
4
|
+
* @property {number} digits - The number of digits the OTP should have. Default is 6.
|
|
5
|
+
*
|
|
6
|
+
* @property {number} ttl - The time-to-live of the OTP in seconds. Default is 300 (5 minutes).
|
|
7
|
+
*
|
|
8
|
+
* @property {Object} accessorsPerActor - Maps actor types (e.g., 'customer', 'user') to their identifier accessors.
|
|
9
|
+
* This configuration tells the OTP system how to find and identify different types of actors in your system.
|
|
10
|
+
* Only used when `mode` is `secondary`, as the `main` mode will create a new auth identity regardless of the identifier.
|
|
11
|
+
*
|
|
12
|
+
* For example, if you want customers to authenticate using their phone number instead of email:
|
|
13
|
+
* ```
|
|
14
|
+
* {
|
|
15
|
+
* customer: {
|
|
16
|
+
* accessor: 'phone', // Will look up customers by their phone field
|
|
17
|
+
* entityIdAccessor: 'email' // Will look up for an AuthIdentity with the customer's email as the `entity_id`
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* You can also use an array of accessors to look up an actor by multiple fields.
|
|
23
|
+
* For example, if you want to look up a customer by multiple fields:
|
|
24
|
+
* ```
|
|
25
|
+
* {
|
|
26
|
+
* customer: { accessor: ['phone', 'email'], entityIdAccessor: 'id' }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* The `accessor` defines which field to use when looking up an actor by the provided identifier.
|
|
31
|
+
* For example, with `accessor: 'phone'`, the system will check `customer.phone` to find matching customers.
|
|
32
|
+
*
|
|
33
|
+
* The `entityIdAccessor` defines which field to use as the entity ID when looking up
|
|
34
|
+
* an AuthIdentity.
|
|
35
|
+
*
|
|
36
|
+
* When using the `emailpass` auth provider for example, the `entityIdAccessor` will be the `email` field.
|
|
37
|
+
* This is because the `emailpass` auth provider uses the `email` field when creating an auth identity.
|
|
38
|
+
*
|
|
39
|
+
* Default is: { customer: { accessor: 'email', entityIdAccessor: 'id' }, user: { accessor: 'email', entityIdAccessor: 'id' } }
|
|
40
|
+
*/
|
|
41
|
+
export type OtpOptions = {
|
|
42
|
+
/** The number of digits the OTP should have. @default 6 */
|
|
43
|
+
digits: number;
|
|
44
|
+
/** The time to live of the OTP in seconds. @default 60 * 5 (5 minutes) */
|
|
45
|
+
ttl: number;
|
|
46
|
+
/**
|
|
47
|
+
* Maps actor types to their identifier accessors for authentication.
|
|
48
|
+
* This tells the system which fields to use when looking up actors and creating auth identities.
|
|
49
|
+
*
|
|
50
|
+
* Only used when `mode` is `secondary`, as the `main` mode will create a new auth identity
|
|
51
|
+
* regardless of the identifier value passed.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Allow customers to authenticate using phone numbers:
|
|
55
|
+
* {
|
|
56
|
+
* customer: {
|
|
57
|
+
* accessor: 'phone', // Will look up customers by their phone field
|
|
58
|
+
* entityIdAccessor: 'email' // Will look up for an AuthIdentity with the customer's email as the `entity_id`
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* @default { customer: { accessor: 'email', entityIdAccessor: 'id' }, user: { accessor: 'email', entityIdAccessor: 'id' } }
|
|
63
|
+
*/
|
|
64
|
+
accessorsPerActor?: {
|
|
65
|
+
[actorType: string]: {
|
|
66
|
+
/**
|
|
67
|
+
* The field name used to look up an actor by the provided identifier.
|
|
68
|
+
* For example, with `accessor: 'phone'`, the system will check `customer.phone` to find matching customers.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* accessor: 'phone' // Will use the `phone` column of the actor as the identifier
|
|
72
|
+
* accessor: ['phone', 'email'] // Will use the `phone` or `email` column of the actor as the identifier
|
|
73
|
+
*/
|
|
74
|
+
accessor: string | string[];
|
|
75
|
+
/**
|
|
76
|
+
* The field name used to get the entity ID when looking up an AuthIdentity.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* entityIdAccessor: 'email' // Will use the `email` column of the actor as the entity ID in AuthIdentity
|
|
80
|
+
*/
|
|
81
|
+
entityIdAccessor: string;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
http?: {
|
|
85
|
+
/**
|
|
86
|
+
* Controls how errors are handled in HTTP responses when generating OTPs.
|
|
87
|
+
*
|
|
88
|
+
* @property {boolean} alwaysReturnSuccess - When true, always returns a success response regardless of errors
|
|
89
|
+
* to prevent data leakage. When false, actual errors will be returned in the response.
|
|
90
|
+
* @default true
|
|
91
|
+
*
|
|
92
|
+
* @property {boolean} throwOnError - When true, throws errors that occur during OTP generation.
|
|
93
|
+
* When false, errors are caught and handled according to alwaysReturnSuccess.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
alwaysReturnSuccess?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* When true, logs a warning when an error occurs during OTP generation.
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
warnOnError?: boolean;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export declare enum Events {
|
|
105
|
+
OTP_GENERATED = "otp.generated",
|
|
106
|
+
PRE_REGISTER_OTP_GENERATED = "pre-register.otp.generated"
|
|
107
|
+
}
|
|
108
|
+
export type OtpGeneratedEvent = {
|
|
109
|
+
identifier: string;
|
|
110
|
+
otp: string;
|
|
111
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Events = void 0;
|
|
4
|
+
var Events;
|
|
5
|
+
(function (Events) {
|
|
6
|
+
Events["OTP_GENERATED"] = "otp.generated";
|
|
7
|
+
Events["PRE_REGISTER_OTP_GENERATED"] = "pre-register.otp.generated";
|
|
8
|
+
})(Events || (exports.Events = Events = {}));
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBMkdBLElBQVksTUFHWDtBQUhELFdBQVksTUFBTTtJQUNoQix5Q0FBK0IsQ0FBQTtJQUMvQixtRUFBeUQsQ0FBQTtBQUMzRCxDQUFDLEVBSFcsTUFBTSxzQkFBTixNQUFNLFFBR2pCIn0=
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ConfigModule } from "@medusajs/framework";
|
|
2
|
+
/**
|
|
3
|
+
* Get the options for the OTP plugin
|
|
4
|
+
* @param configModule The config module
|
|
5
|
+
* @returns The options for the OTP plugin based on the default options and the options from the plugin
|
|
6
|
+
*/
|
|
7
|
+
export default function getPluginOptions(configModule: ConfigModule): {
|
|
8
|
+
accessorsPerActor: {
|
|
9
|
+
[x: string]: {
|
|
10
|
+
accessor: string | string[];
|
|
11
|
+
entityIdAccessor: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
http: {
|
|
15
|
+
alwaysReturnSuccess?: boolean;
|
|
16
|
+
warnOnError?: boolean;
|
|
17
|
+
};
|
|
18
|
+
digits: number;
|
|
19
|
+
ttl: number;
|
|
20
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
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.default = getPluginOptions;
|
|
7
|
+
const otp_1 = __importDefault(require("./otp"));
|
|
8
|
+
/**
|
|
9
|
+
* Get the options for the OTP plugin
|
|
10
|
+
* @param configModule The config module
|
|
11
|
+
* @returns The options for the OTP plugin based on the default options and the options from the plugin
|
|
12
|
+
*/
|
|
13
|
+
function getPluginOptions(configModule) {
|
|
14
|
+
const isPluginWithOptions = (plugin) => {
|
|
15
|
+
return typeof plugin === 'object' && "resolve" in plugin && "options" in plugin;
|
|
16
|
+
};
|
|
17
|
+
const pluginOptions = configModule.plugins.filter(isPluginWithOptions).find((plugin) => plugin.resolve.includes('@perseidesjs/auth-otp'))?.options;
|
|
18
|
+
return {
|
|
19
|
+
...otp_1.default.DEFAULT_OPTIONS,
|
|
20
|
+
...pluginOptions,
|
|
21
|
+
accessorsPerActor: {
|
|
22
|
+
...otp_1.default.DEFAULT_OPTIONS.accessorsPerActor,
|
|
23
|
+
...pluginOptions?.accessorsPerActor
|
|
24
|
+
},
|
|
25
|
+
http: {
|
|
26
|
+
...otp_1.default.DEFAULT_OPTIONS.http,
|
|
27
|
+
...pluginOptions?.http
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXBsdWdpbi1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL2dldC1wbHVnaW4tb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVNBLG1DQW1CQztBQTFCRCxnREFBNkI7QUFFN0I7Ozs7R0FJRztBQUNILFNBQXdCLGdCQUFnQixDQUFDLFlBQTBCO0lBQ2pFLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxNQUFXLEVBQW1FLEVBQUU7UUFDM0csT0FBTyxPQUFPLE1BQU0sS0FBSyxRQUFRLElBQUksU0FBUyxJQUFJLE1BQU0sSUFBSSxTQUFTLElBQUksTUFBTSxDQUFBO0lBQ2pGLENBQUMsQ0FBQTtJQUVELE1BQU0sYUFBYSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLEVBQUUsT0FBaUMsQ0FBQTtJQUU1SyxPQUFPO1FBQ0wsR0FBRyxhQUFRLENBQUMsZUFBZTtRQUMzQixHQUFHLGFBQWE7UUFDaEIsaUJBQWlCLEVBQUU7WUFDakIsR0FBRyxhQUFRLENBQUMsZUFBZSxDQUFDLGlCQUFpQjtZQUM3QyxHQUFHLGFBQWEsRUFBRSxpQkFBaUI7U0FDcEM7UUFDRCxJQUFJLEVBQUU7WUFDSixHQUFHLGFBQVEsQ0FBQyxlQUFlLENBQUMsSUFBSTtZQUNoQyxHQUFHLGFBQWEsRUFBRSxJQUFJO1NBQ3ZCO0tBQ0YsQ0FBQTtBQUNILENBQUMifQ==
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OtpOptions } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Static utility class for OTP operations
|
|
4
|
+
*/
|
|
5
|
+
export declare class OtpUtils {
|
|
6
|
+
static DEFAULT_OPTIONS: OtpOptions;
|
|
7
|
+
/**
|
|
8
|
+
* Generate a random numeric OTP of specified length
|
|
9
|
+
* @param digits The number of digits the OTP should have
|
|
10
|
+
* @returns {string} The OTP
|
|
11
|
+
*/
|
|
12
|
+
static generateRandomOTP(digits: number): string;
|
|
13
|
+
}
|
|
14
|
+
export default OtpUtils;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OtpUtils = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
/**
|
|
6
|
+
* Static utility class for OTP operations
|
|
7
|
+
*/
|
|
8
|
+
class OtpUtils {
|
|
9
|
+
/**
|
|
10
|
+
* Generate a random numeric OTP of specified length
|
|
11
|
+
* @param digits The number of digits the OTP should have
|
|
12
|
+
* @returns {string} The OTP
|
|
13
|
+
*/
|
|
14
|
+
static generateRandomOTP(digits) {
|
|
15
|
+
const timeStep = 30;
|
|
16
|
+
const secret = (0, node_crypto_1.randomBytes)(32).toString('hex');
|
|
17
|
+
const time = Math.floor(Date.now() / 1000 / timeStep);
|
|
18
|
+
const hmac = (0, node_crypto_1.createHmac)('sha1', Buffer.from(secret, 'hex'));
|
|
19
|
+
hmac.update(Buffer.from(time.toString(), 'utf-8'));
|
|
20
|
+
const hmacResult = hmac.digest();
|
|
21
|
+
const offset = hmacResult[hmacResult.length - 1] & 0xf;
|
|
22
|
+
const binary = ((hmacResult[offset] & 0x7f) << 24) |
|
|
23
|
+
((hmacResult[offset + 1] & 0xff) << 16) |
|
|
24
|
+
((hmacResult[offset + 2] & 0xff) << 8) |
|
|
25
|
+
(hmacResult[offset + 3] & 0xff);
|
|
26
|
+
return (binary % Math.pow(10, digits)).toString().padStart(digits, '0');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.OtpUtils = OtpUtils;
|
|
30
|
+
OtpUtils.DEFAULT_OPTIONS = {
|
|
31
|
+
digits: 6, // 6 digits
|
|
32
|
+
ttl: 60 * 5, // 5 minutes
|
|
33
|
+
accessorsPerActor: {
|
|
34
|
+
customer: { accessor: 'email', entityIdAccessor: 'email' },
|
|
35
|
+
user: { accessor: 'email', entityIdAccessor: 'email' }
|
|
36
|
+
},
|
|
37
|
+
http: {
|
|
38
|
+
alwaysReturnSuccess: true, // Always return success to prevent data leakage
|
|
39
|
+
warnOnError: true // Warn when an error occurs during OTP generation
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.default = OtpUtils;
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL290cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBcUQ7QUFHckQ7O0dBRUc7QUFDSCxNQUFhLFFBQVE7SUFjbkI7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFjO1FBQ3JDLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQTtRQUNuQixNQUFNLE1BQU0sR0FBRyxJQUFBLHlCQUFXLEVBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQzlDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQTtRQUVyRCxNQUFNLElBQUksR0FBRyxJQUFBLHdCQUFVLEVBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDM0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO1FBQ2xELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQTtRQUVoQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUE7UUFDdEQsTUFBTSxNQUFNLEdBQ1YsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbkMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3ZDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUE7UUFFakMsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDekUsQ0FBQzs7QUFwQ0gsNEJBcUNDO0FBcENRLHdCQUFlLEdBQWU7SUFDbkMsTUFBTSxFQUFFLENBQUMsRUFBRSxXQUFXO0lBQ3RCLEdBQUcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLFlBQVk7SUFDekIsaUJBQWlCLEVBQUU7UUFDakIsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUU7UUFDMUQsSUFBSSxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUU7S0FDdkQ7SUFDRCxJQUFJLEVBQUU7UUFDSixtQkFBbUIsRUFBRSxJQUFJLEVBQUUsZ0RBQWdEO1FBQzNFLFdBQVcsRUFBRSxJQUFJLENBQUMsa0RBQWtEO0tBQ3JFO0NBQ0YsQ0FBQTtBQTJCSCxrQkFBZSxRQUFRLENBQUEifQ==
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OtpOptions } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates an OTP for a given identifier and actor type.
|
|
4
|
+
*
|
|
5
|
+
* @param input - The input for the workflow.
|
|
6
|
+
* @param input.identifier - The identifier of the actor to generate the OTP for.
|
|
7
|
+
* @param input.actorType - The type of actor to generate the OTP for.
|
|
8
|
+
* @param input.accessorsPerActor - The accessors per actor to use for the workflow.
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
declare const generateOtpWorkflow: import("@medusajs/framework/workflows-sdk").ReturnWorkflow<{
|
|
12
|
+
identifier: string;
|
|
13
|
+
actorType: string;
|
|
14
|
+
accessorsPerActor: Required<OtpOptions>["accessorsPerActor"][string];
|
|
15
|
+
}, "OK", []>;
|
|
16
|
+
export default generateOtpWorkflow;
|