diff --git a/src/app/login/auth.controller.spec.ts b/src/app/login/auth.controller.spec.ts index b745f0e..8876b63 100644 --- a/src/app/login/auth.controller.spec.ts +++ b/src/app/login/auth.controller.spec.ts @@ -1,33 +1,56 @@ import {AuthController} from "./auth.controller"; import {AuthService} from "./auth.service"; +import * as helpers from "./../../spec/helpers"; describe("Controllers", () => { describe("AuthController", () => { - it("calls authenticate on AuthService when login called", () => { + let $modal: any; + let notificationService = helpers.mocks.notificationService; + notificationService.success = jasmine.createSpy('info'); + notificationService.error = jasmine.createSpy('error'); - // creating a Mock AuthService - let AuthServiceMock: AuthService = jasmine.createSpyObj("AuthService", ["login"]); + let authController: any; + let AuthServiceMock: AuthService; + let username: string; - // pass AuthServiceMock into the constructor - let authController = new AuthController(null, null, AuthServiceMock); + beforeEach(() => { + $modal = helpers.mocks.$modal; + AuthServiceMock = jasmine.createSpyObj("AuthService", ["login", +"forgotPassword"]); + authController = new AuthController(null, null, AuthServiceMock, $modal, notificationService); + }); - // setup of authController -> set the credentials instance property - let credentials = { username: "username", password: "password" }; + it("calls authenticate on AuthService when login called", () => { + let credentials = { username: "username", password: "password" }; authController.credentials = credentials; - - // calls the authController login method authController.login(); - - // checks if the method login of the injected AuthService has been called expect(AuthServiceMock.login).toHaveBeenCalledWith(credentials); - }); + it('should open forgot password on click', (done: Function) => { + spyOn($modal, "open"); + authController.openForgotPassword(); + expect($modal.open).toHaveBeenCalled(); + expect($modal.open).toHaveBeenCalledWith({ + templateUrl: 'app/login/forgot-password.html', + controller: AuthController, + controllerAs: 'vm', + bindToController: true + }); + done(); + }); + it("calls forgorPassword on AuthService when sendPasswdInfo called", done => { + authController.username = "john"; + AuthServiceMock.forgotPassword = jasmine.createSpy("forgotPassword").and.returnValue(Promise.resolve()); + authController.sendPasswdInfo(); + expect(AuthServiceMock.forgotPassword).toHaveBeenCalledWith("john"); + done(); + }); }); }); diff --git a/src/app/login/auth.controller.ts b/src/app/login/auth.controller.ts index ff9664c..a92e5c8 100644 --- a/src/app/login/auth.controller.ts +++ b/src/app/login/auth.controller.ts @@ -1,20 +1,43 @@ -import {AuthService} from "./auth.service"; +import { AuthService } from "./auth.service"; +import { NotificationService } from "./../shared/services/notification.service"; export class AuthController { - static $inject = ["$log", "$stateParams", "AuthService"]; + static $inject = ["$log", "$stateParams", "AuthService", "$uibModal", "NotificationService"]; + modalInstance: ng.ui.bootstrap.IModalServiceInstance; constructor( private $log: ng.ILogService, private $stateParams: any, - private AuthService: AuthService + private AuthService: AuthService, + private $uibModal: ng.ui.bootstrap.IModalService, + private notificationService: NotificationService ) { } credentials: noosfero.Credentials; + username: string; login() { this.AuthService.login(this.credentials); } + + openForgotPassword() { + this.modalInstance = this.$uibModal.open({ + templateUrl: 'app/login/forgot-password.html', + controller: AuthController, + controllerAs: 'vm', + bindToController: true, + }); + } + + sendPasswdInfo() { + this.AuthService.forgotPassword(this.username).then((response) => { + this.notificationService.info({ title: "forgotPasswd.email_sent.title.info", message: "forgotPasswd.email_sent.message.info" }); + }).catch((response) => { + this.notificationService.error({ title: "forgotPasswd.not_found.title.error", message: "forgotPasswd.not_found.message.error" }); + this.openForgotPassword(); + }); + } } diff --git a/src/app/login/auth.service.ts b/src/app/login/auth.service.ts index 42a55bf..4373358 100644 --- a/src/app/login/auth.service.ts +++ b/src/app/login/auth.service.ts @@ -2,11 +2,12 @@ import {Injectable, Inject, EventEmitter} from "ng-forward"; import {NoosferoRootScope, UserResponse} from "./../shared/models/interfaces"; import {SessionService} from "./session.service"; +import { RestangularService } from "./../../lib/ng-noosfero-api/http/restangular_service"; import {AuthEvents} from "./auth-events"; @Injectable() -@Inject("$http", SessionService, "$log") +@Inject("$http", SessionService, "$log", "Restangular") export class AuthService { public loginSuccess: EventEmitter = new EventEmitter(); @@ -15,7 +16,10 @@ export class AuthService { constructor(private $http: ng.IHttpService, private sessionService: SessionService, - private $log: ng.ILogService) { + private $log: ng.ILogService, + private Restangular: restangular.IService + ) { + this.Restangular = Restangular; } loginFromCookie() { @@ -76,4 +80,9 @@ export class AuthService { throw new Error(`The event: ${eventName} not exists`); } } + + forgotPassword(value: string): ng.IPromise> { + return this.Restangular.all("").customPOST("", "forgot_password", {value: value}); + } + } diff --git a/src/app/login/forgot-password.html b/src/app/login/forgot-password.html new file mode 100644 index 0000000..d18d6dc --- /dev/null +++ b/src/app/login/forgot-password.html @@ -0,0 +1,20 @@ + + diff --git a/src/app/login/login.html b/src/app/login/login.html index 51cced5..3b07242 100644 --- a/src/app/login/login.html +++ b/src/app/login/login.html @@ -18,6 +18,9 @@ {{"auth.form.keepLoggedIn" | translate}} + diff --git a/src/app/login/login.scss b/src/app/login/login.scss index c84e42c..befd448 100644 --- a/src/app/login/login.scss +++ b/src/app/login/login.scss @@ -10,6 +10,12 @@ margin-top: 20px; text-transform: uppercase; } + .form-inline { + display: inline; + div { + display: inline-block; + } + } } } diff --git a/src/app/shared/services/notification.service.ts b/src/app/shared/services/notification.service.ts index 438c416..a451970 100644 --- a/src/app/shared/services/notification.service.ts +++ b/src/app/shared/services/notification.service.ts @@ -14,6 +14,8 @@ export class NotificationService { public static DEFAULT_ERROR_TITLE = "notification.error.default.title"; public static DEFAULT_ERROR_MESSAGE = "notification.error.default.message"; public static DEFAULT_SUCCESS_TIMER = 1000; + public static DEFAULT_INFO_TITLE = "notification.info.default.title"; + public static DEFAULT_INFO_MESSAGE = "notification.info.default.message"; error({ message = NotificationService.DEFAULT_ERROR_MESSAGE, @@ -40,6 +42,14 @@ export class NotificationService { this.showMessage({ title: title, text: message, showCancelButton: showCancelButton, type: type, closeOnConfirm: false }, confirmationFunction); } + info({ + message = NotificationService.DEFAULT_INFO_MESSAGE, + title = NotificationService.DEFAULT_INFO_TITLE, + showConfirmButton = true + } = {}) { + this.showMessage({ title: title, text: message, showConfirmButton: showConfirmButton, type: "info" }); + } + private showMessage({title, text, type = "success", timer = null, showConfirmButton = true, showCancelButton = false, closeOnConfirm = true}, confirmationFunction: Function = null) { this.$log.debug("Notification message:", title, text, type, this.translatorService.currentLanguage()); this.SweetAlert.swal({ diff --git a/src/languages/en.json b/src/languages/en.json index fda5ff1..80dbc64 100644 --- a/src/languages/en.json +++ b/src/languages/en.json @@ -32,8 +32,15 @@ "auth.form.login": "Username or Email address", "auth.form.password": "Password", "auth.form.keepLoggedIn": "Keep me logged in", + "auth.form.forgot_passwd": "Forgot your password?", "auth.form.login_button": "Login", "auth.createAccount": "Create account", + "forgotPasswd.send_instructions_button": "Send instructions", + "forgotPasswd.info": "Upon clicking on the button above, you'll receive an email with instructions on how to create a new password.", + "forgotPasswd.email_sent.title.info": "Change your password", + "forgotPasswd.email_sent.message.info": "Follow the instructions sent by email to change your password", + "forgotPasswd.not_found.title.error": "User not found", + "forgotPasswd.not_found.message.error": "Could not send password recovery for the user", "navbar.content_viewer_actions.new_item": "New Item", "navbar.profile_actions.new_item": "New Item", "navbar.content_viewer_actions.new_post": "New Post", @@ -41,6 +48,8 @@ "navbar.profile_actions.new_discussion": "New Discussion", "notification.error.default.message": "Something went wrong!", "notification.error.default.title": "Oops...", + "notification.info.default.message": "", + "notification.info.default.title": "Information", "notification.profile.not_found": "Page not found", "notification.http_error.401.message": "Unauthorized", "notification.http_error.500.message": "Server error", diff --git a/src/languages/pt.json b/src/languages/pt.json index 1ee7d2a..f300326 100644 --- a/src/languages/pt.json +++ b/src/languages/pt.json @@ -32,8 +32,15 @@ "auth.form.login": "Nome de usuário ou Email", "auth.form.password": "Senha", "auth.form.keepLoggedIn": "Continuar logado", + "auth.form.forgot_passwd": "Esqueceu sua senha?", "auth.form.login_button": "Login", "auth.createAccount": "Criar conta", + "forgotPasswd.send_instructions_button": "Send instructions", + "forgotPasswd.info": "Ao clicar no botão acima, você receberá um email com instruções para criar uma nova senha.", + "forgotPasswd.email_sent.title.info": "Altere sua senha", + "forgotPasswd.email_sent.message.info": "Siga as instruções enviadas por e-mail para alterar sua senha", + "forgotPasswd.not_found.title.error": "Usuário não encontrado", + "forgotPasswd.not_found.message.error": "Não foi possível recuperar a senha deste usuário", "navbar.content_viewer_actions.new_item": "Novo Item", "navbar.profile_actions.new_item": "Novo Item", "navbar.content_viewer_actions.new_post": "Novo Post", @@ -41,6 +48,8 @@ "navbar.profile_actions.new_discussion": "Nova Discussão", "notification.error.default.message": "Algo deu errado!", "notification.error.default.title": "Oops...", + "notification.info.default.message": "", + "notification.info.default.title": "Informação", "notification.profile.not_found": "Página não encontrada", "notification.http_error.401.message": "Não autorizado", "notification.http_error.500.message": "Erro no servidor", -- libgit2 0.21.2