UNPKG

medusa-email-confirmation-plugin

Version:

medusa-email-confirmation-plugin is a Medusa plugin that adds obligatory requirement for customers to confirm their email used for sign up to Medusa ecommerce stores.

252 lines (251 loc) 13.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const medusa_1 = require("@medusajs/medusa"); const awilix_1 = require("awilix"); const moment_1 = __importDefault(require("moment")); const index_1 = require("../api/index"); class EmailConfirmationService extends medusa_1.TransactionBaseService { constructor(container, options) { super(container); this.customerRepository = container.customerRepository; try { this.eventBusService = container === null || container === void 0 ? void 0 : container.eventBusService; } catch (e) { this.eventBusService = undefined; } let op = options; this.logger = container.logger; this.options_ = op; } options() { return this.options_; } randomString(length) { const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; var result = ''; for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; return result; } async generateToken(customer) { let updateMetadata = customer.metadata; const token = this.randomString(64); const generatedAt = new Date(); updateMetadata.email_confirmation_token = token; updateMetadata.email_confirmation_token_generated_at = generatedAt.toISOString(); if (!customer.metadata.email_confirmation_requested_at) { updateMetadata.email_confirmation_requested_at = new Date().toISOString(); } const projectedExpirationDate = (0, moment_1.default)(generatedAt).add(this.options_.token_max_lifetime_days, 'days'); updateMetadata.email_confirmation_token_expires_at = projectedExpirationDate.startOf('day').toISOString(); await this.customerRepository.update({ id: customer.id }, { metadata: updateMetadata }); return await this.customerRepository.findOneBy({ id: customer.id }); } async confirmEmail(customer) { let updateMetadata = customer.metadata; updateMetadata.email_confirmation_confirmed_at = new Date().toISOString(); await this.customerRepository.update({ id: customer.id }, { metadata: updateMetadata }); return await this.customerRepository.findOneBy({ id: customer.id }); } async tokenRequest(email, autogenerate = false) { const customer = await this.customerRepository.findOneBy({ email }); const response = new index_1.APIResponse(); if (!customer) { response.success = false; response.code = 'email_not_found'; response.error = `Registered customer with email - ${email} not found.`; return response; } else { if (!customer.has_account) { response.success = false; response.code = 'email_not_found'; response.error = `Registered customer with email - ${email} not found. Customer with email ${email} - not registered, but exists.`; return response; } } if (autogenerate && !this.options_.autoinit_on_register) { response.success = false; response.code = 'token_not_created'; response.error = `Autoinitialization - forbidden.`; return response; } if (customer.metadata.email_confirmation_confirmed_at) { if ((0, moment_1.default)(`${customer.metadata.email_confirmation_confirmed_at}`, moment_1.default.ISO_8601, true).isValid()) { response.success = false; response.code = 'email_already_confirmed'; response.error = `Registered customer with email - ${email} already confirmed his email at: ${(0, moment_1.default)(`${customer.metadata.email_confirmation_confirmed_at}`).toLocaleString()}.`; return response; } } if (customer.metadata.email_confirmation_token) { if (this.options_.token_max_lifetime_days) { if (customer.metadata.email_confirmation_token_expires_at) { if ((0, moment_1.default)(`${customer.metadata.email_confirmation_token_expires_at}`, moment_1.default.ISO_8601, true).isValid()) { const tokenExpires = (0, moment_1.default)(`${customer.metadata.email_confirmation_token_expires_at}`, moment_1.default.ISO_8601, true); //const projectedExpirationDate = moment(new Date()).add(this.options_.token_max_lifetime_days, 'days') if (tokenExpires <= (0, moment_1.default)(new Date())) { const updated = await this.generateToken(customer); if (updated) { this.eventBusService.emit('customer.email_confirm', { customer, token: updated.metadata.email_confirmation_token, canExpire: this.options_.token_max_lifetime_days ? true : false, expires: updated.metadata.email_confirmation_token_expires_at }); response.success = true; return response; } } } } } else { this.eventBusService.emit('customer.email_confirm', { customer, token: customer.metadata.email_confirmation_token, canExpire: this.options_.token_max_lifetime_days ? true : false, expires: customer.metadata.email_confirmation_token_expires_at }); response.success = true; return response; } } else { const updated = await this.generateToken(customer); if (updated) { this.eventBusService.emit('customer.email_confirm', { customer, token: updated.metadata.email_confirmation_token, canExpire: this.options_.token_max_lifetime_days ? true : false, expires: updated.metadata.email_confirmation_token_expires_at }); response.success = true; return response; } } } async status(email) { const customer = await this.customerRepository.findOneBy({ email }); const response = new index_1.APIResponse(); if (!customer) { response.success = false; response.code = 'email_not_found'; response.error = `Registered customer with email - ${email} not found.`; return response; } if (customer.metadata.email_confirmation_confirmed_at) { if ((0, moment_1.default)(`${customer.metadata.email_confirmation_confirmed_at}`, moment_1.default.ISO_8601, true).isValid()) { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'confirmed'; return response; } } else { if (customer.metadata.email_confirmation_token) { if (this.options_.token_max_lifetime_days) { if (customer.metadata.email_confirmation_token_expires_at) { if ((0, moment_1.default)(`${customer.metadata.email_confirmation_token_expires_at}`, moment_1.default.ISO_8601, true).isValid()) { const tokenExpires = (0, moment_1.default)(`${customer.metadata.email_confirmation_token_expires_at}`, moment_1.default.ISO_8601, true); //const projectedExpirationDate = moment(new Date()).add(this.options_.token_max_lifetime_days, 'days') if (tokenExpires <= (0, moment_1.default)(new Date())) { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'expired'; return response; } else { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'awaiting'; return response; } } else { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'uninitialized'; return response; } } else { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'uninitialized'; return response; } } else { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'uninitialized'; return response; } } else { response.success = true; response.data = new index_1.StatusResponseViewModel(); response.data.status = 'uninitialized'; return response; } } } async confirm(email, token) { const customer = await this.customerRepository.findOneBy({ email }); const response = new index_1.APIResponse(); if (!token || token.length <= 0) { response.success = false; response.code = 'empty_token'; response.error = `Provided confirmation token - is empty!`; return response; } if (!customer) { response.success = false; response.code = 'email_not_found'; response.error = `Registered customer with email - ${email} not found.`; return response; } if (customer.metadata.email_confirmation_confirmed_at) { if ((0, moment_1.default)(`${customer.metadata.email_confirmation_confirmed_at}`, moment_1.default.ISO_8601, true).isValid()) { response.success = false; response.code = 'email_already_confirmed'; response.error = `Registered customer with email - ${email} already confirmed his email at: ${(0, moment_1.default)(`${customer.metadata.email_confirmation_confirmed_at}`).toLocaleString()}.`; return response; } } if (customer.metadata.email_confirmation_token) { if (this.options_.token_max_lifetime_days) { if (customer.metadata.email_confirmation_token_expires_at) { if ((0, moment_1.default)(`${customer.metadata.email_confirmation_token_expires_at}`, moment_1.default.ISO_8601, true).isValid()) { const tokenExpires = (0, moment_1.default)(`${customer.metadata.email_confirmation_token_expires_at}`, moment_1.default.ISO_8601, true); //const projectedExpirationDate = moment(new Date()).add(this.options_.token_max_lifetime_days, 'days') if (tokenExpires <= (0, moment_1.default)(new Date())) { response.success = false; response.code = 'token_expired'; response.error = `Token associated with email ${email} - expired! Try regenerating token.`; return response; } else { if (customer.metadata.email_confirmation_token === token) { const updated = await this.confirmEmail(customer); if (updated) { response.success = true; return response; } } else { response.success = false; response.code = 'token_not_found'; response.error = `Token associated with email ${email} - not matches the provided token! Confirmation aborted.`; return response; } } } } } else { this.eventBusService.emit('customer.email_confirm', { customer, token: customer.metadata.email_confirmation_token, canExpire: this.options_.token_max_lifetime_days ? true : false, expires: customer.metadata.email_confirmation_token_expires_at }); response.success = true; return response; } } else { response.success = false; response.code = 'token_not_created'; response.error = `Token associated with email ${email} - not found. Perhaps, email confirmation process wasn't initialized!`; return response; } } } EmailConfirmationService.LIFE_TIME = awilix_1.Lifetime.SCOPED; exports.default = EmailConfirmationService;