diff --git a/back/methods/account/recover-password.js b/back/methods/account/recover-password.js
new file mode 100644
index 0000000000..ddea76829c
--- /dev/null
+++ b/back/methods/account/recover-password.js
@@ -0,0 +1,30 @@
+module.exports = Self => {
+    Self.remoteMethod('recoverPassword', {
+        description: 'Send email to the user',
+        accepts: [
+            {
+                arg: 'email',
+                type: 'string',
+                description: 'The email of user',
+                required: true
+            }
+        ],
+        http: {
+            path: `/recoverPassword`,
+            verb: 'POST'
+        }
+    });
+
+    Self.recoverPassword = async function(email) {
+        const models = Self.app.models;
+
+        try {
+            await models.user.resetPassword({email, emailTemplate: 'recover-password'});
+        } catch (err) {
+            if (err.code === 'EMAIL_NOT_FOUND')
+                return;
+            else
+                throw err;
+        }
+    };
+};
diff --git a/back/methods/account/specs/set-password.spec.js b/back/methods/account/specs/set-password.spec.js
index c76fd52b83..fe71873de2 100644
--- a/back/methods/account/specs/set-password.spec.js
+++ b/back/methods/account/specs/set-password.spec.js
@@ -1,6 +1,6 @@
 const app = require('vn-loopback/server/server');
 
-describe('account changePassword()', () => {
+describe('account setPassword()', () => {
     it('should throw an error when password does not meet requirements', async() => {
         let req = app.models.Account.setPassword(1, 'insecurePass');
 
diff --git a/back/models/account.js b/back/models/account.js
index f74052b5c9..c2502380a1 100644
--- a/back/models/account.js
+++ b/back/models/account.js
@@ -1,4 +1,7 @@
+/* eslint max-len: ["error", { "code": 150 }]*/
 const md5 = require('md5');
+const LoopBackContext = require('loopback-context');
+const {Email} = require('vn-print');
 
 module.exports = Self => {
     require('../methods/account/login')(Self);
@@ -6,6 +9,7 @@ module.exports = Self => {
     require('../methods/account/acl')(Self);
     require('../methods/account/change-password')(Self);
     require('../methods/account/set-password')(Self);
+    require('../methods/account/recover-password')(Self);
     require('../methods/account/validate-token')(Self);
     require('../methods/account/privileges')(Self);
 
@@ -27,17 +31,62 @@ module.exports = Self => {
             ctx.data.password = md5(ctx.data.password);
     });
 
+    Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => {
+        if (!ctx.args || !ctx.args.data.email) return;
+        const models = Self.app.models;
+
+        const loopBackContext = LoopBackContext.getCurrentContext();
+        const httpCtx = {req: loopBackContext.active};
+        const httpRequest = httpCtx.req.http.req;
+        const headers = httpRequest.headers;
+        const origin = headers.origin;
+        const url = origin.split(':');
+
+        const userId = ctx.instance.id;
+        const user = await models.user.findById(userId);
+
+        class Mailer {
+            async send(verifyOptions, cb) {
+                const params = {
+                    url: verifyOptions.verifyHref,
+                    recipient: verifyOptions.to,
+                    lang: ctx.req.getLocale()
+                };
+
+                const email = new Email('email-verify', params);
+                email.send();
+
+                cb(null, verifyOptions.to);
+            }
+        }
+
+        const options = {
+            type: 'email',
+            to: instance.email,
+            from: {},
+            redirect: `${origin}/#!/account/${instance.id}/basic-data?emailConfirmed`,
+            template: false,
+            mailer: new Mailer,
+            host: url[1].split('/')[2],
+            port: url[2],
+            protocol: url[0],
+            user: Self
+        };
+
+        await user.verify(options);
+    });
+
     Self.remoteMethod('getCurrentUserData', {
         description: 'Gets the current user data',
         accepts: [
             {
                 arg: 'ctx',
-                type: 'Object',
+                type: 'object',
                 http: {source: 'context'}
             }
         ],
         returns: {
-            type: 'Object',
+            type: 'object',
             root: true
         },
         http: {
@@ -58,7 +107,7 @@ module.exports = Self => {
      *
      * @param {Integer} userId The user id
      * @param {String} name The role name
-     * @param {Object} options Options
+     * @param {object} options Options
      * @return {Boolean} %true if user has the role, %false otherwise
      */
     Self.hasRole = async function(userId, name, options) {
@@ -70,8 +119,8 @@ module.exports = Self => {
      * Get all user roles.
      *
      * @param {Integer} userId The user id
-     * @param {Object} options Options
-     * @return {Object} User role list
+     * @param {object} options Options
+     * @return {object} User role list
      */
     Self.getRoles = async(userId, options) => {
         let result = await Self.rawSql(
diff --git a/back/models/account.json b/back/models/account.json
index d0c17e70f6..5e35c711a7 100644
--- a/back/models/account.json
+++ b/back/models/account.json
@@ -40,6 +40,9 @@
 		"email": {
 			"type": "string"
 		},
+        "emailVerified": {
+			"type": "boolean"
+		},
 		"created": {
 			"type": "date"
 		},
@@ -88,16 +91,23 @@
 			"principalType": "ROLE",
 			"principalId": "$everyone",
 			"permission": "ALLOW"
-		},
+        },
+        {
+            "property": "recoverPassword",
+            "accessType": "EXECUTE",
+            "principalType": "ROLE",
+            "principalId": "$everyone",
+            "permission": "ALLOW"
+        },
 		{
-			"property": "logout",
+            "property": "logout",
 			"accessType": "EXECUTE",
 			"principalType": "ROLE",
 			"principalId": "$authenticated",
 			"permission": "ALLOW"
 		},
 		{
-			"property": "validateToken",
+            "property": "validateToken",
 			"accessType": "EXECUTE",
 			"principalType": "ROLE",
 			"principalId": "$authenticated",
diff --git a/back/models/specs/account.spec.js b/back/models/specs/account.spec.js
index c52bc43782..f31c81b75e 100644
--- a/back/models/specs/account.spec.js
+++ b/back/models/specs/account.spec.js
@@ -1,14 +1,14 @@
-const app = require('vn-loopback/server/server');
+const models = require('vn-loopback/server/server').models;
 
 describe('loopback model Account', () => {
     it('should return true if the user has the given role', async() => {
-        let result = await app.models.Account.hasRole(1, 'employee');
+        let result = await models.Account.hasRole(1, 'employee');
 
         expect(result).toBeTruthy();
     });
 
     it('should return false if the user doesnt have the given role', async() => {
-        let result = await app.models.Account.hasRole(1, 'administrator');
+        let result = await models.Account.hasRole(1, 'administrator');
 
         expect(result).toBeFalsy();
     });
diff --git a/back/models/specs/user.spec.js b/back/models/specs/user.spec.js
new file mode 100644
index 0000000000..124afdc0cc
--- /dev/null
+++ b/back/models/specs/user.spec.js
@@ -0,0 +1,32 @@
+const models = require('vn-loopback/server/server').models;
+const LoopBackContext = require('loopback-context');
+
+describe('account recoverPassword()', () => {
+    const userId = 1107;
+
+    const activeCtx = {
+        accessToken: {userId: userId},
+        http: {
+            req: {
+                headers: {origin: 'http://localhost'}
+            }
+        }
+    };
+
+    beforeEach(() => {
+        spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
+            active: activeCtx
+        });
+    });
+
+    it('should send email with token', async() => {
+        const userId = 1107;
+        const user = await models.Account.findById(userId);
+
+        await models.Account.recoverPassword(user.email);
+
+        const result = await models.AccessToken.findOne({where: {userId: userId}});
+
+        expect(result).toBeDefined();
+    });
+});
diff --git a/back/models/user.js b/back/models/user.js
new file mode 100644
index 0000000000..b24d702b32
--- /dev/null
+++ b/back/models/user.js
@@ -0,0 +1,27 @@
+const LoopBackContext = require('loopback-context');
+const {Email} = require('vn-print');
+
+module.exports = function(Self) {
+    Self.on('resetPasswordRequest', async function(info) {
+        const loopBackContext = LoopBackContext.getCurrentContext();
+        const httpCtx = {req: loopBackContext.active};
+        const httpRequest = httpCtx.req.http.req;
+        const headers = httpRequest.headers;
+        const origin = headers.origin;
+
+        const user = await Self.app.models.Account.findById(info.user.id);
+        const params = {
+            recipient: info.email,
+            lang: user.lang,
+            url: `${origin}/#!/reset-password?access_token=${info.accessToken.id}`
+        };
+
+        const options = Object.assign({}, info.options);
+        for (const param in options)
+            params[param] = options[param];
+
+        const email = new Email(options.emailTemplate, params);
+
+        return email.send();
+    });
+};
diff --git a/db/changes/10502-november/00-aclUserPassword.sql b/db/changes/10502-november/00-aclUserPassword.sql
new file mode 100644
index 0000000000..b92b54c283
--- /dev/null
+++ b/db/changes/10502-november/00-aclUserPassword.sql
@@ -0,0 +1,2 @@
+DELETE FROM `salix`.`ACL`
+    WHERE model = 'UserPassword';
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 06fabe3e61..f550e3a9da 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -29,6 +29,11 @@ export default {
         firstModulePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="push_pin"]',
         firstModuleRemovePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="remove_circle"]'
     },
+    recoverPassword: {
+        recoverPasswordButton: 'vn-login a[ui-sref="recoverPassword"]',
+        email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]',
+        sendEmailButton: 'vn-recover-password vn-submit',
+    },
     accountIndex: {
         addAccount: 'vn-user-index button vn-icon[icon="add"]',
         newName: 'vn-user-create vn-textfield[ng-model="$ctrl.user.name"]',
diff --git a/e2e/paths/01-salix/04_recoverPassword.spec.js b/e2e/paths/01-salix/04_recoverPassword.spec.js
new file mode 100644
index 0000000000..80ef32cb51
--- /dev/null
+++ b/e2e/paths/01-salix/04_recoverPassword.spec.js
@@ -0,0 +1,40 @@
+import selectors from '../../helpers/selectors';
+import getBrowser from '../../helpers/puppeteer';
+
+describe('Login path', async() => {
+    let browser;
+    let page;
+
+    beforeAll(async() => {
+        browser = await getBrowser();
+        page = browser.page;
+
+        await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
+        await page.waitForState('recoverPassword');
+    });
+
+    afterAll(async() => {
+        await browser.close();
+    });
+
+    it('should not throw error if not exist user', async() => {
+        await page.write(selectors.recoverPassword.email, 'fakeEmail@mydomain.com');
+        await page.waitToClick(selectors.recoverPassword.sendEmailButton);
+
+        const message = await page.waitForSnackbar();
+
+        expect(message.text).toContain('Notification sent!');
+    });
+
+    it('should send email', async() => {
+        await page.waitForState('login');
+        await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
+
+        await page.write(selectors.recoverPassword.email, 'BruceWayne@mydomain.com');
+        await page.waitToClick(selectors.recoverPassword.sendEmailButton);
+        const message = await page.waitForSnackbar();
+        await page.waitForState('login');
+
+        expect(message.text).toContain('Notification sent!');
+    });
+});
diff --git a/e2e/paths/05-ticket/20_future.spec.js b/e2e/paths/05-ticket/20_future.spec.js
index 4fee9523bd..6db2bf4f00 100644
--- a/e2e/paths/05-ticket/20_future.spec.js
+++ b/e2e/paths/05-ticket/20_future.spec.js
@@ -5,80 +5,78 @@ describe('Ticket Future path', () => {
     let browser;
     let page;
 
-    beforeAll(async () => {
+    beforeAll(async() => {
         browser = await getBrowser();
         page = browser.page;
         await page.loginAndModule('employee', 'ticket');
         await page.accessToSection('ticket.future');
     });
 
-    afterAll(async () => {
+    afterAll(async() => {
         await browser.close();
     });
 
     const now = new Date();
     const tomorrow = new Date(now.getDate() + 1);
-    const ticket = {
-        originDated: now,
-        futureDated: now,
-        linesMax: '9999',
-        litersMax: '9999',
-        warehouseFk: 'Warehouse One'
-    };
 
-    it('should show errors snackbar because of the required data', async () => {
+    it('should show errors snackbar because of the required data', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.clearInput(selectors.ticketFuture.warehouseFk);
         await page.waitToClick(selectors.ticketFuture.submit);
         let message = await page.waitForSnackbar();
+
         expect(message.text).toContain('warehouseFk is a required argument');
 
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.clearInput(selectors.ticketFuture.litersMax);
         await page.waitToClick(selectors.ticketFuture.submit);
         message = await page.waitForSnackbar();
+
         expect(message.text).toContain('litersMax is a required argument');
 
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.clearInput(selectors.ticketFuture.linesMax);
         await page.waitToClick(selectors.ticketFuture.submit);
         message = await page.waitForSnackbar();
+
         expect(message.text).toContain('linesMax is a required argument');
 
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.clearInput(selectors.ticketFuture.futureDated);
         await page.waitToClick(selectors.ticketFuture.submit);
         message = await page.waitForSnackbar();
+
         expect(message.text).toContain('futureDated is a required argument');
 
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.clearInput(selectors.ticketFuture.originDated);
         await page.waitToClick(selectors.ticketFuture.submit);
         message = await page.waitForSnackbar();
+
         expect(message.text).toContain('originDated is a required argument');
     });
 
-    it('should search with the required data', async () => {
+    it('should search with the required data', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.waitToClick(selectors.ticketFuture.submit);
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search with the origin shipped today', async () => {
+    it('should search with the origin shipped today', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.pickDate(selectors.ticketFuture.shipped, now);
         await page.waitToClick(selectors.ticketFuture.submit);
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search with the origin shipped tomorrow', async () => {
+    it('should search with the origin shipped tomorrow', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.pickDate(selectors.ticketFuture.shipped, tomorrow);
         await page.waitToClick(selectors.ticketFuture.submit);
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
     });
 
-    it('should search with the destination shipped today', async () => {
+    it('should search with the destination shipped today', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.clearInput(selectors.ticketFuture.shipped);
         await page.pickDate(selectors.ticketFuture.tfShipped, now);
@@ -86,14 +84,14 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search with the destination shipped tomorrow', async () => {
+    it('should search with the destination shipped tomorrow', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
         await page.pickDate(selectors.ticketFuture.tfShipped, tomorrow);
         await page.waitToClick(selectors.ticketFuture.submit);
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
     });
 
-    it('should search with the origin IPT', async () => {
+    it('should search with the origin IPT', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
 
         await page.clearInput(selectors.ticketFuture.shipped);
@@ -108,7 +106,7 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
     });
 
-    it('should search with the destination IPT', async () => {
+    it('should search with the destination IPT', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
 
         await page.clearInput(selectors.ticketFuture.shipped);
@@ -123,7 +121,7 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 0);
     });
 
-    it('should search with the origin grouped state', async () => {
+    it('should search with the origin grouped state', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
 
         await page.clearInput(selectors.ticketFuture.shipped);
@@ -138,7 +136,7 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 3);
     });
 
-    it('should search with the destination grouped state', async () => {
+    it('should search with the destination grouped state', async() => {
         await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
 
         await page.clearInput(selectors.ticketFuture.shipped);
@@ -164,10 +162,10 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search in smart-table with an ID Origin', async () => {
+    it('should search in smart-table with an ID Origin', async() => {
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
-        await page.write(selectors.ticketFuture.tableId, "13");
-        await page.keyboard.press("Enter");
+        await page.write(selectors.ticketFuture.tableId, '13');
+        await page.keyboard.press('Enter');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 2);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -176,10 +174,10 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search in smart-table with an ID Destination', async () => {
+    it('should search in smart-table with an ID Destination', async() => {
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
-        await page.write(selectors.ticketFuture.tableTfId, "12");
-        await page.keyboard.press("Enter");
+        await page.write(selectors.ticketFuture.tableTfId, '12');
+        await page.keyboard.press('Enter');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -188,7 +186,7 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search in smart-table with an IPT Origin', async () => {
+    it('should search in smart-table with an IPT Origin', async() => {
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
         await page.autocompleteSearch(selectors.ticketFuture.tableIpt, 'Vertical');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
@@ -199,7 +197,7 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search in smart-table with an IPT Destination', async () => {
+    it('should search in smart-table with an IPT Destination', async() => {
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
         await page.autocompleteSearch(selectors.ticketFuture.tableTfIpt, 'Vertical');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
@@ -210,10 +208,10 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search in smart-table with especified Lines', async () => {
+    it('should search in smart-table with especified Lines', async() => {
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
-        await page.write(selectors.ticketFuture.tableLines, "0");
-        await page.keyboard.press("Enter");
+        await page.write(selectors.ticketFuture.tableLines, '0');
+        await page.keyboard.press('Enter');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -222,8 +220,8 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
-        await page.write(selectors.ticketFuture.tableLines, "1");
-        await page.keyboard.press("Enter");
+        await page.write(selectors.ticketFuture.tableLines, '1');
+        await page.keyboard.press('Enter');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -232,10 +230,10 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should search in smart-table with especified Liters', async () => {
+    it('should search in smart-table with especified Liters', async() => {
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
-        await page.write(selectors.ticketFuture.tableLiters, "0");
-        await page.keyboard.press("Enter");
+        await page.write(selectors.ticketFuture.tableLiters, '0');
+        await page.keyboard.press('Enter');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 1);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -244,8 +242,8 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
-        await page.write(selectors.ticketFuture.tableLiters, "28");
-        await page.keyboard.press("Enter");
+        await page.write(selectors.ticketFuture.tableLiters, '28');
+        await page.keyboard.press('Enter');
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 5);
 
         await page.waitToClick(selectors.ticketFuture.tableButtonSearch);
@@ -254,13 +252,13 @@ describe('Ticket Future path', () => {
         await page.waitForNumberOfElements(selectors.ticketFuture.table, 4);
     });
 
-    it('should check the three last tickets and move to the future', async () => {
+    it('should check the three last tickets and move to the future', async() => {
         await page.waitToClick(selectors.ticketFuture.multiCheck);
         await page.waitToClick(selectors.ticketFuture.firstCheck);
         await page.waitToClick(selectors.ticketFuture.moveButton);
         await page.waitToClick(selectors.ticketFuture.acceptButton);
         const message = await page.waitForSnackbar();
+
         expect(message.text).toContain('Tickets moved successfully!');
     });
-
 });
diff --git a/front/core/lib/component.js b/front/core/lib/component.js
index f17db68a2a..5695d9449c 100644
--- a/front/core/lib/component.js
+++ b/front/core/lib/component.js
@@ -12,9 +12,10 @@ export default class Component extends EventEmitter {
      * @param {HTMLElement} $element The main component element
      * @param {$rootScope.Scope} $scope The element scope
      * @param {Function} $transclude The transclusion function
+     * @param {Function} $location The location function
      */
-    constructor($element, $scope, $transclude) {
-        super();
+    constructor($element, $scope, $transclude, $location) {
+        super($element, $scope, $transclude, $location);
         this.$ = $scope;
 
         if (!$element) return;
@@ -164,7 +165,7 @@ export default class Component extends EventEmitter {
             $transclude.$$boundTransclude.$$slots[slot];
     }
 }
-Component.$inject = ['$element', '$scope'];
+Component.$inject = ['$element', '$scope', '$location', '$state'];
 
 /*
  * Automatically adds the most used services to the prototype, so they are
diff --git a/front/core/services/auth.js b/front/core/services/auth.js
index a1dcfa3953..04520cd0b5 100644
--- a/front/core/services/auth.js
+++ b/front/core/services/auth.js
@@ -23,7 +23,10 @@ export default class Auth {
 
     initialize() {
         let criteria = {
-            to: state => state.name != 'login'
+            to: state => {
+                const outLayout = ['login', 'recoverPassword', 'resetPassword'];
+                return !outLayout.some(ol => ol == state.name);
+            }
         };
         this.$transitions.onStart(criteria, transition => {
             if (this.loggedIn)
diff --git a/front/salix/components/app/app.html b/front/salix/components/app/app.html
index d32c9f68bc..f14fab2dd3 100644
--- a/front/salix/components/app/app.html
+++ b/front/salix/components/app/app.html
@@ -1,9 +1,8 @@
 <vn-layout
     ng-if="$ctrl.showLayout">
 </vn-layout>
-<ui-view
-    name="login"
+<vn-out-layout
     ng-if="!$ctrl.showLayout">
-</ui-view>
+</vn-out-layout>
 <vn-snackbar vn-id="snackbar"></vn-snackbar>
 <vn-debug-info></vn-debug-info>
diff --git a/front/salix/components/app/app.js b/front/salix/components/app/app.js
index 1f8cdb46e7..20f0ad969b 100644
--- a/front/salix/components/app/app.js
+++ b/front/salix/components/app/app.js
@@ -9,13 +9,20 @@ import Component from 'core/lib/component';
  * @property {SideMenu} rightMenu The left menu, if it's present
  */
 export default class App extends Component {
+    constructor($element, $, $location, $state) {
+        super($element, $, $location, $state);
+        this.$location = $location;
+        this.$state = $state;
+    }
+
     $postLink() {
         this.vnApp.logger = this;
     }
 
     get showLayout() {
-        let state = this.$state.current.name;
-        return state && state != 'login';
+        const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.');
+        const outLayout = ['login', 'recoverPassword', 'resetPassword'];
+        return state && !outLayout.some(ol => ol == state);
     }
 
     $onDestroy() {
diff --git a/front/salix/components/index.js b/front/salix/components/index.js
index ce4ad585aa..dbe9fe81ae 100644
--- a/front/salix/components/index.js
+++ b/front/salix/components/index.js
@@ -5,7 +5,10 @@ import './descriptor-popover';
 import './home/home';
 import './layout';
 import './left-menu/left-menu';
+import './login/index';
 import './login/login';
+import './login/recover-password';
+import './login/reset-password';
 import './module-card';
 import './module-main';
 import './side-menu/side-menu';
diff --git a/front/salix/components/login/index.html b/front/salix/components/login/index.html
new file mode 100644
index 0000000000..186979f8ce
--- /dev/null
+++ b/front/salix/components/login/index.html
@@ -0,0 +1,6 @@
+<div class="box">
+	<img src="./logo.svg"/>
+	<form name="form">
+        <ui-view></ui-view>
+    </form>
+</div>
diff --git a/front/salix/components/login/index.js b/front/salix/components/login/index.js
new file mode 100644
index 0000000000..f0e21fa299
--- /dev/null
+++ b/front/salix/components/login/index.js
@@ -0,0 +1,16 @@
+import ngModule from '../../module';
+import Component from 'core/lib/component';
+import './style.scss';
+
+export default class OutLayout extends Component {
+    constructor($element, $scope) {
+        super($element, $scope);
+    }
+}
+
+OutLayout.$inject = ['$element', '$scope'];
+
+ngModule.vnComponent('vnOutLayout', {
+    template: require('./index.html'),
+    controller: OutLayout
+});
diff --git a/front/salix/components/login/locale/en.yml b/front/salix/components/login/locale/en.yml
index c59a6dd8e6..1ddd454b70 100644
--- a/front/salix/components/login/locale/en.yml
+++ b/front/salix/components/login/locale/en.yml
@@ -1,4 +1,8 @@
 User: User
 Password: Password
 Do not close session: Do not close session
-Enter: Enter
\ No newline at end of file
+Enter: Enter
+Password requirements: >
+    The password must have at least {{ length }} length characters,
+    {{nAlpha}} alphabetic characters, {{nUpper}} capital letters, {{nDigits}}
+    digits and {{nPunct}} symbols (Ex: $%&.)
diff --git a/front/salix/components/login/locale/es.yml b/front/salix/components/login/locale/es.yml
index 9c9ba59058..e3a5815c1c 100644
--- a/front/salix/components/login/locale/es.yml
+++ b/front/salix/components/login/locale/es.yml
@@ -1,4 +1,16 @@
 User: Usuario
 Password: Contraseña
+Email: Correo electrónico
 Do not close session: No cerrar sesión
-Enter: Entrar
\ No newline at end of file
+Enter: Entrar
+I do not remember my password: No recuerdo mi contraseña
+Recover password: Recuperar contraseña
+We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
+Notification sent!: ¡Notificación enviada!
+Reset password: Restrablecer contraseña
+New password: Nueva contraseña
+Repeat password: Repetir contraseña
+Password requirements: >
+    La contraseña debe tener al menos {{ length }} caracteres de longitud,
+    {{nAlpha}} caracteres alfabéticos, {{nUpper}} letras mayúsculas, {{nDigits}}
+    dígitos y {{nPunct}} símbolos (Ej: $%&.)
diff --git a/front/salix/components/login/login.html b/front/salix/components/login/login.html
index b15714a232..a078fa0af0 100644
--- a/front/salix/components/login/login.html
+++ b/front/salix/components/login/login.html
@@ -1,27 +1,27 @@
-<div class="box">
-	<img src="./logo.svg"/>
-	<form name="form" ng-submit="$ctrl.submit()">
-		<vn-textfield
-			label="User"
-			ng-model="$ctrl.user"
-			vn-id="userField"
-			vn-focus>
-		</vn-textfield>
-		<vn-textfield
-			label="Password"
-			ng-model="$ctrl.password"
-			type="password">
-		</vn-textfield>
-		<vn-check
-			label="Do not close session"
-			ng-model="$ctrl.remember"
-			name="remember">
-		</vn-check>
-		<div class="footer">
-			<vn-submit label="Enter"></vn-submit>
-			<div class="spinner-wrapper">
-				<vn-spinner enable="$ctrl.loading"></vn-spinner>
-			</div>
-		</div>
-	</form>
+<vn-textfield
+    label="User"
+    ng-model="$ctrl.user"
+    vn-id="userField"
+    vn-focus>
+</vn-textfield>
+<vn-textfield
+    label="Password"
+    ng-model="$ctrl.password"
+    type="password">
+</vn-textfield>
+<vn-check
+    label="Do not close session"
+    ng-model="$ctrl.remember"
+    name="remember">
+</vn-check>
+<div class="footer">
+    <vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit>
+    <div class="spinner-wrapper">
+        <vn-spinner enable="$ctrl.loading"></vn-spinner>
+    </div>
+    <div class="vn-pt-lg">
+        <a ui-sref="recoverPassword" translate>
+            I do not remember my password
+        </a>
+    </div>
 </div>
diff --git a/front/salix/components/login/recover-password.html b/front/salix/components/login/recover-password.html
new file mode 100644
index 0000000000..73f5401d9e
--- /dev/null
+++ b/front/salix/components/login/recover-password.html
@@ -0,0 +1,17 @@
+<h5 class="vn-mb-md vn-mt-lg" translate>Recover password</h5>
+<vn-textfield
+    label="Email"
+    ng-model="$ctrl.email"
+    vn-focus>
+</vn-textfield>
+<div
+    class="text-secondary"
+    translate>
+    We will sent you an email to recover your password
+</div>
+<div class="footer">
+    <vn-submit label="Recover password" ng-click="$ctrl.submit()"></vn-submit>
+    <div class="spinner-wrapper">
+        <vn-spinner enable="$ctrl.loading"></vn-spinner>
+    </div>
+</div>
diff --git a/front/salix/components/login/recover-password.js b/front/salix/components/login/recover-password.js
new file mode 100644
index 0000000000..fa9bfc4599
--- /dev/null
+++ b/front/salix/components/login/recover-password.js
@@ -0,0 +1,37 @@
+import ngModule from '../../module';
+import './style.scss';
+
+export default class Controller {
+    constructor($scope, $element, $http, vnApp, $translate, $state) {
+        Object.assign(this, {
+            $scope,
+            $element,
+            $http,
+            vnApp,
+            $translate,
+            $state
+        });
+    }
+
+    goToLogin() {
+        this.vnApp.showSuccess(this.$translate.instant('Notification sent!'));
+        this.$state.go('login');
+    }
+
+    submit() {
+        const params = {
+            email: this.email
+        };
+
+        this.$http.post('Accounts/recoverPassword', params)
+            .then(() => {
+                this.goToLogin();
+            });
+    }
+}
+Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state'];
+
+ngModule.vnComponent('vnRecoverPassword', {
+    template: require('./recover-password.html'),
+    controller: Controller
+});
diff --git a/front/salix/components/login/reset-password.html b/front/salix/components/login/reset-password.html
new file mode 100644
index 0000000000..bdbdc113ed
--- /dev/null
+++ b/front/salix/components/login/reset-password.html
@@ -0,0 +1,19 @@
+<h5 class="vn-mb-md vn-mt-lg" translate>Reset password</h5>
+<vn-textfield
+    label="New password"
+    ng-model="$ctrl.newPassword"
+    type="password"
+    info="{{'Password requirements' | translate:$ctrl.passRequirements}}"
+    vn-focus>
+</vn-textfield>
+<vn-textfield
+    label="Repeat password"
+    ng-model="$ctrl.repeatPassword"
+    type="password">
+</vn-textfield>
+<div class="footer">
+    <vn-submit label="Reset password" ng-click="$ctrl.submit()"></vn-submit>
+    <div class="spinner-wrapper">
+        <vn-spinner enable="$ctrl.loading"></vn-spinner>
+    </div>
+</div>
diff --git a/front/salix/components/login/reset-password.js b/front/salix/components/login/reset-password.js
new file mode 100644
index 0000000000..9ee1fdb620
--- /dev/null
+++ b/front/salix/components/login/reset-password.js
@@ -0,0 +1,48 @@
+import ngModule from '../../module';
+import './style.scss';
+
+export default class Controller {
+    constructor($scope, $element, $http, vnApp, $translate, $state, $location) {
+        Object.assign(this, {
+            $scope,
+            $element,
+            $http,
+            vnApp,
+            $translate,
+            $state,
+            $location
+        });
+    }
+
+    $onInit() {
+        this.$http.get('UserPasswords/findOne')
+            .then(res => {
+                this.passRequirements = res.data;
+            });
+    }
+
+    submit() {
+        if (!this.newPassword)
+            throw new UserError(`You must enter a new password`);
+        if (this.newPassword != this.repeatPassword)
+            throw new UserError(`Passwords don't match`);
+
+        const headers = {
+            Authorization: this.$location.$$search.access_token
+        };
+
+        const newPassword = this.newPassword;
+
+        this.$http.post('users/reset-password', {newPassword}, {headers})
+            .then(() => {
+                this.vnApp.showSuccess(this.$translate.instant('Password changed!'));
+                this.$state.go('login');
+            });
+    }
+}
+Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location'];
+
+ngModule.vnComponent('vnResetPassword', {
+    template: require('./reset-password.html'),
+    controller: Controller
+});
diff --git a/front/salix/components/login/style.scss b/front/salix/components/login/style.scss
index 8ebf2a68c5..8985893f2a 100644
--- a/front/salix/components/login/style.scss
+++ b/front/salix/components/login/style.scss
@@ -1,6 +1,31 @@
 @import "variables";
 
-vn-login {
+vn-login,
+vn-reset-password,
+vn-recover-password{
+    .footer {
+        margin-top: 32px;
+        text-align: center;
+        position: relative;
+        & > .vn-submit {
+            display: block;
+
+            & > input {
+                display: block;
+                width: 100%;
+            }
+        }
+        & > .spinner-wrapper {
+            position: absolute;
+            width: 0;
+            top: 3px;
+            right: -8px;
+            overflow: visible;
+        }
+    }
+}
+
+vn-out-layout{
 	position: absolute;
 	height: 100%;
 	width: 100%;
@@ -39,28 +64,17 @@ vn-login {
 					white-space: inherit;
 				}
 			}
-			& > .footer {
-				margin-top: 32px;
-				text-align: center;
-				position: relative;
-
-				& > vn-submit {
-					display: block;
-
-					& > input {
-						display: block;
-						width: 100%;
-					}
-				}
-				& > .spinner-wrapper {
-					position: absolute;
-					width: 0;
-					top: 3px;
-					right: -8px;
-					overflow: visible;
-				}
-			}
 		}
+
+        h5{
+            color: $color-primary;
+        }
+
+        .text-secondary{
+            text-align: center;
+            padding-bottom: 16px;
+        }
+
 	}
 
 	@media screen and (max-width: 600px) {
@@ -71,4 +85,8 @@ vn-login {
 			box-shadow: none;
 		}
 	}
+
+    a{
+        color: $color-primary;
+    }
 }
diff --git a/front/salix/module.js b/front/salix/module.js
index a8de61ae07..01df01a672 100644
--- a/front/salix/module.js
+++ b/front/salix/module.js
@@ -112,7 +112,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
 
             switch (exception.status) {
             case 401:
-                if ($state.current.name != 'login') {
+                if (!$state.current.name.includes('login')) {
                     messageT = 'Session has expired';
                     let params = {continue: $window.location.hash};
                     $state.go('login', params);
diff --git a/front/salix/routes.js b/front/salix/routes.js
index 600907ff1e..be893800f9 100644
--- a/front/salix/routes.js
+++ b/front/salix/routes.js
@@ -9,9 +9,17 @@ function config($stateProvider, $urlRouterProvider) {
         .state('login', {
             url: '/login?continue',
             description: 'Login',
-            views: {
-                login: {template: '<vn-login></vn-login>'}
-            }
+            template: '<vn-login></vn-login>'
+        })
+        .state('recoverPassword', {
+            url: '/recover-password',
+            description: 'Recover-password',
+            template: '<vn-recover-password>asd</vn-recover-password>'
+        })
+        .state('resetPassword', {
+            url: '/reset-password',
+            description: 'Reset-password',
+            template: '<vn-reset-password></vn-reset-password>'
         })
         .state('home', {
             url: '/',
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index ad110ec98c..24a3a40a8d 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -131,12 +131,15 @@
 	"Fichadas impares": "Odd signs",
 	"Descanso diario 9h.": "Daily rest 9h.",
 	"Descanso semanal 36h. / 72h.": "Weekly rest 36h. / 72h.",
+	"Verify email": "Verify email",
+	"Click on the following link to verify this email. If you haven't requested this email, just ignore it": "Click on the following link to verify this email. If you haven't requested this email, just ignore it",
 	"Password does not meet requirements": "Password does not meet requirements",
 	"You don't have privileges to change the zone": "You don't have privileges to change the zone or for these parameters there are more than one shipping options, talk to agencies",
 	"Not enough privileges to edit a client": "Not enough privileges to edit a client",
     "Claim pickup order sent": "Claim pickup order sent [({{claimId}})]({{{claimUrl}}}) to client *{{clientName}}*",
 	"You don't have grant privilege": "You don't have grant privilege",
 	"You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user",
+    "Email verify": "Email verify",
 	"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) merged with [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
     "Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production",
     "Receipt's bank was not found": "Receipt's bank was not found",
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index ecaae31b92..932dfe98f8 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -245,6 +245,8 @@
 	"Already has this status": "Ya tiene este estado",
 	"There aren't records for this week": "No existen registros para esta semana",
 	"Empty data source": "Origen de datos vacio",
+	"Email verify": "Correo de verificación",
+	"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
     "Receipt's bank was not found": "No se encontró el banco del recibo",
     "This receipt was not compensated": "Este recibo no ha sido compensado",
     "Client's email was not found": "No se encontró el email del cliente"
diff --git a/loopback/server/datasources.json b/loopback/server/datasources.json
index 4db642058f..00f6bf624e 100644
--- a/loopback/server/datasources.json
+++ b/loopback/server/datasources.json
@@ -113,4 +113,4 @@
             "application/x-7z-compressed"
         ]
     }
-}
\ No newline at end of file
+}
diff --git a/modules/account/back/models/user-password.json b/modules/account/back/models/user-password.json
index 1b7e49edd7..53909ad1fa 100644
--- a/modules/account/back/models/user-password.json
+++ b/modules/account/back/models/user-password.json
@@ -30,5 +30,13 @@
 			"type": "number",
 			"required": true
 		}
-	}
+	},
+    "acls": [
+      {
+        "accessType": "READ",
+        "principalType": "ROLE",
+        "principalId": "$everyone",
+        "permission": "ALLOW"
+      }
+    ]
 }
diff --git a/modules/account/front/basic-data/index.js b/modules/account/front/basic-data/index.js
index 342297e458..77d3eab26c 100644
--- a/modules/account/front/basic-data/index.js
+++ b/modules/account/front/basic-data/index.js
@@ -2,6 +2,11 @@ import ngModule from '../module';
 import Section from 'salix/components/section';
 
 export default class Controller extends Section {
+    $onInit() {
+        if (this.$params.emailConfirmed)
+            this.vnApp.showSuccess(this.$t('Email verified successfully!'));
+    }
+
     onSubmit() {
         this.$.watcher.submit()
             .then(() => this.card.reload());
diff --git a/modules/account/front/basic-data/locale/es.yml b/modules/account/front/basic-data/locale/es.yml
new file mode 100644
index 0000000000..2ca7bf6987
--- /dev/null
+++ b/modules/account/front/basic-data/locale/es.yml
@@ -0,0 +1 @@
+Email verified successfully!: Correo verificado correctamente!
diff --git a/modules/account/front/routes.json b/modules/account/front/routes.json
index b96c931c95..a6f2f5d3f5 100644
--- a/modules/account/front/routes.json
+++ b/modules/account/front/routes.json
@@ -74,7 +74,7 @@
             }
         },
         {
-            "url": "/basic-data",
+            "url": "/basic-data?emailConfirmed",
             "state": "account.card.basicData",
             "component": "vn-user-basic-data",
             "description": "Basic data",
diff --git a/print/core/smtp.js b/print/core/smtp.js
index a55ba448dd..61b115b5af 100644
--- a/print/core/smtp.js
+++ b/print/core/smtp.js
@@ -8,10 +8,12 @@ module.exports = {
             this.transporter = nodemailer.createTransport(config.smtp);
     },
 
-    send(options) {
+    async send(options) {
         options.from = `${config.app.senderName} <${config.app.senderEmail}>`;
 
         if (process.env.NODE_ENV !== 'production') {
+            const notProductionError = {message: 'This not production, this email not sended'};
+            await this.mailLog(options, notProductionError);
             if (!config.smtp.auth.user)
                 return Promise.resolve(true);
 
@@ -24,29 +26,35 @@ module.exports = {
 
             throw err;
         }).finally(async() => {
-            const attachments = [];
-            if (options.attachments) {
-                for (let attachment of options.attachments) {
-                    const fileName = attachment.filename;
-                    const filePath = attachment.path;
-                    if (fileName.includes('.png')) continue;
-
-                    if (fileName || filePath)
-                        attachments.push(filePath ? filePath : fileName);
-                }
-            }
-
-            const fileNames = attachments.join(',\n');
-            await db.rawSql(`
-                INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, attachment, status)
-                    VALUES (?, ?, 1, ?, ?, ?, ?)`, [
-                options.to,
-                options.replyTo,
-                options.subject,
-                options.text || options.html,
-                fileNames,
-                error && error.message || 'Sent'
-            ]);
+            await this.mailLog(options, error);
         });
+    },
+
+    async mailLog(options, error) {
+        const attachments = [];
+        if (options.attachments) {
+            for (let attachment of options.attachments) {
+                const fileName = attachment.filename;
+                const filePath = attachment.path;
+                if (fileName.includes('.png')) continue;
+
+                if (fileName || filePath)
+                    attachments.push(filePath ? filePath : fileName);
+            }
+        }
+
+        const fileNames = attachments.join(',\n');
+
+        await db.rawSql(`
+            INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, attachment, status)
+                VALUES (?, ?, 1, ?, ?, ?, ?)`, [
+            options.to,
+            options.replyTo,
+            options.subject,
+            options.text || options.html,
+            fileNames,
+            error && error.message || 'Sent'
+        ]);
     }
+
 };
diff --git a/print/templates/email/email-verify/assets/css/import.js b/print/templates/email/email-verify/assets/css/import.js
new file mode 100644
index 0000000000..7360587f7b
--- /dev/null
+++ b/print/templates/email/email-verify/assets/css/import.js
@@ -0,0 +1,13 @@
+const Stylesheet = require(`vn-print/core/stylesheet`);
+
+const path = require('path');
+const vnPrintPath = path.resolve('print');
+
+module.exports = new Stylesheet([
+    `${vnPrintPath}/common/css/spacing.css`,
+    `${vnPrintPath}/common/css/misc.css`,
+    `${vnPrintPath}/common/css/layout.css`,
+    `${vnPrintPath}/common/css/email.css`,
+    `${__dirname}/style.css`])
+    .mergeStyles();
+
diff --git a/print/templates/email/email-verify/assets/css/style.css b/print/templates/email/email-verify/assets/css/style.css
new file mode 100644
index 0000000000..5db85befa4
--- /dev/null
+++ b/print/templates/email/email-verify/assets/css/style.css
@@ -0,0 +1,5 @@
+.external-link {
+    border: 2px dashed #8dba25;
+    border-radius: 3px;
+    text-align: center
+}
\ No newline at end of file
diff --git a/print/templates/email/email-verify/email-verify.html b/print/templates/email/email-verify/email-verify.html
new file mode 100644
index 0000000000..b8a6e263c9
--- /dev/null
+++ b/print/templates/email/email-verify/email-verify.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html v-bind:lang="$i18n.locale">
+    <head>
+        <meta name="viewport" content="width=device-width">
+        <meta name="format-detection" content="telephone=no">
+        <title>{{ $t('subject') }}</title>
+    </head>
+    <body>
+        <table class="grid">
+            <tbody>
+                <tr>
+                    <td>
+                        <!-- Empty block -->
+                        <div class="grid-row">
+                            <div class="grid-block empty"></div>
+                        </div>
+                        <!-- Header block -->
+                        <div class="grid-row">
+                            <div class="grid-block">
+                                <email-header></email-header>
+                            </div>
+                        </div>
+                        <!-- Block -->
+                        <div class="grid-row">
+                            <div class="grid-block vn-pa-ml">
+                                <p>
+                                    {{ $t(`click`) }}
+                                    <a :href="url">{{ $t('subject') }}</a>
+                                </p>
+                            </div>
+                        </div>
+
+                        <!-- Footer block -->
+                        <div class="grid-row">
+                            <div class="grid-block">
+                                <email-footer></email-footer>
+                            </div>
+                        </div>
+                        <!-- Empty block -->
+                        <div class="grid-row">
+                            <div class="grid-block empty"></div>
+                        </div>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </body>
+</html>
diff --git a/print/templates/email/email-verify/email-verify.js b/print/templates/email/email-verify/email-verify.js
new file mode 100755
index 0000000000..7f0b80a13c
--- /dev/null
+++ b/print/templates/email/email-verify/email-verify.js
@@ -0,0 +1,17 @@
+const Component = require(`vn-print/core/component`);
+const emailHeader = new Component('email-header');
+const emailFooter = new Component('email-footer');
+
+module.exports = {
+    name: 'email-verify',
+    components: {
+        'email-header': emailHeader.build(),
+        'email-footer': emailFooter.build()
+    },
+    props: {
+        url: {
+            type: [String],
+            required: true
+        }
+    }
+};
diff --git a/print/templates/email/email-verify/locale/en.yml b/print/templates/email/email-verify/locale/en.yml
new file mode 100644
index 0000000000..0298f53b4b
--- /dev/null
+++ b/print/templates/email/email-verify/locale/en.yml
@@ -0,0 +1,3 @@
+subject: Email Verify
+title: Email Verify
+click: Click on the following link to verify this email. If you haven't requested this email, just ignore it
diff --git a/print/templates/email/email-verify/locale/es.yml b/print/templates/email/email-verify/locale/es.yml
new file mode 100644
index 0000000000..37bd6ef273
--- /dev/null
+++ b/print/templates/email/email-verify/locale/es.yml
@@ -0,0 +1,3 @@
+subject: Verificar correo
+title: Verificar correo
+click: Pulsa en el siguiente link para verificar este correo. Si no has pedido este correo, simplemente ignóralo
diff --git a/print/templates/email/recover-password/assets/css/import.js b/print/templates/email/recover-password/assets/css/import.js
new file mode 100644
index 0000000000..7360587f7b
--- /dev/null
+++ b/print/templates/email/recover-password/assets/css/import.js
@@ -0,0 +1,13 @@
+const Stylesheet = require(`vn-print/core/stylesheet`);
+
+const path = require('path');
+const vnPrintPath = path.resolve('print');
+
+module.exports = new Stylesheet([
+    `${vnPrintPath}/common/css/spacing.css`,
+    `${vnPrintPath}/common/css/misc.css`,
+    `${vnPrintPath}/common/css/layout.css`,
+    `${vnPrintPath}/common/css/email.css`,
+    `${__dirname}/style.css`])
+    .mergeStyles();
+
diff --git a/print/templates/email/recover-password/assets/css/style.css b/print/templates/email/recover-password/assets/css/style.css
new file mode 100644
index 0000000000..5db85befa4
--- /dev/null
+++ b/print/templates/email/recover-password/assets/css/style.css
@@ -0,0 +1,5 @@
+.external-link {
+    border: 2px dashed #8dba25;
+    border-radius: 3px;
+    text-align: center
+}
\ No newline at end of file
diff --git a/print/templates/email/recover-password/locale/es.yml b/print/templates/email/recover-password/locale/es.yml
new file mode 100644
index 0000000000..c72b108ee9
--- /dev/null
+++ b/print/templates/email/recover-password/locale/es.yml
@@ -0,0 +1,3 @@
+subject: Recuperar contraseña
+title: Recuperar contraseña
+Click on the following link to change your password.: Pulsa en el siguiente link para cambiar tu contraseña.
diff --git a/print/templates/email/recover-password/recover-password.html b/print/templates/email/recover-password/recover-password.html
new file mode 100644
index 0000000000..a654b3d5f0
--- /dev/null
+++ b/print/templates/email/recover-password/recover-password.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html v-bind:lang="$i18n.locale">
+    <head>
+        <meta name="viewport" content="width=device-width">
+        <meta name="format-detection" content="telephone=no">
+        <title>{{ $t('subject') }}</title>
+    </head>
+    <body>
+        <table class="grid">
+            <tbody>
+                <tr>
+                    <td>
+                        <!-- Empty block -->
+                        <div class="grid-row">
+                            <div class="grid-block empty"></div>
+                        </div>
+                        <!-- Header block -->
+                        <div class="grid-row">
+                            <div class="grid-block">
+                                <email-header></email-header>
+                            </div>
+                        </div>
+                        <!-- Block -->
+                        <div class="grid-row">
+                            <div class="grid-block vn-pa-ml">
+                                <p>
+                                    {{ $t('Click on the following link to change your password.') }}
+                                    <a :href="url">{{ $t('subject') }}</a>
+                                </p>
+                            </div>
+                        </div>
+
+                        <!-- Footer block -->
+                        <div class="grid-row">
+                            <div class="grid-block">
+                                <email-footer></email-footer>
+                            </div>
+                        </div>
+                        <!-- Empty block -->
+                        <div class="grid-row">
+                            <div class="grid-block empty"></div>
+                        </div>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </body>
+</html>
diff --git a/print/templates/email/recover-password/recover-password.js b/print/templates/email/recover-password/recover-password.js
new file mode 100755
index 0000000000..b589411a9a
--- /dev/null
+++ b/print/templates/email/recover-password/recover-password.js
@@ -0,0 +1,17 @@
+const Component = require(`vn-print/core/component`);
+const emailHeader = new Component('email-header');
+const emailFooter = new Component('email-footer');
+
+module.exports = {
+    name: 'recover-password',
+    components: {
+        'email-header': emailHeader.build(),
+        'email-footer': emailFooter.build()
+    },
+    props: {
+        url: {
+            type: [String],
+            required: true
+        }
+    }
+};