"use strict"; angular.module('app.service') .factory('user', ['$rootScope', '$http', '$q', '$window', 'take', 'apiUrl', 'cfg', 'AbstractBridge', 'indicator', 'translate', function ($rootScope, $http, $q, $window, take, apiUrl, cfg, AbstractBridge, indicator, translate) { /** * @param {?Object} options * @param {?Object} userInfo * @constructor */ var User = function (options, userInfo) { AbstractBridge.call(this, options); this.controller = 'session'; this.authenticated = null; this.authPromise = null; this.init(userInfo); if (userInfo) { this.authenticated = true; } }; User.prototype = _.create(AbstractBridge.prototype); User.prototype.constructor = User; User.prototype.init = function (info) { if (null == info) { this.id = undefined; this.name = undefined; this.login = undefined; this.roleId = undefined; return this; } this.prepareData(info); take(info, 'id').it('String', 'Number').set(this, 'id'); take(info, 'name').it('String').set(this, 'name'); take(info, 'login').it('String').set(this, 'login'); take(info, 'phone').it('String', 'Null').set(this, 'phone'); take(info, 'roleId').it('String').set(this, 'roleId'); return this; }; User.prototype.prepareData = function (data) { data.birthDate = null == data.birthDate ? null : new Date(data.birthDate); return data; }; /** * Authenticates user using server API * @param {{login: String, password: String: rememberMe: Boolean}} [data] * @return {promise} */ User.prototype.authenticate = function (data) { var self = this; if (this.authenticated) { var defer = $q.defer(); defer.resolve(this); return defer.promise; } if (this.authPromise) { return this.authPromise; } indicator.start('user.login'); var promise = data ? this.post('login', data) : this.post('info'); this.authPromise = promise.then(function (response) { indicator.stop('user.login'); self.authPromise = null; self.authenticated = true; self.init(response.data); $rootScope.$emit('user.authenticate'); return this; }, function (response) { indicator.stop('user.login'); self.authPromise = null; if (null === self.authenticated) self.authenticated = false; if (data) $rootScope.$emit('user.authenticate.error', response.errors); return $q.reject(response); }); return this.authPromise; }; /** * Return promise that will be resolved on auth done or auth fail * (user.authenticate promise is rejected on auth fail, that's why it can't be used with ui-router state.resolve) * @param {?String} roleId * @return {promise} */ User.prototype.authResolve = function (roleId) { var self = this; return this.authenticate().then(function (data) { if (roleId && roleId !== self.roleId) { return $q.reject(data); } return data; }, function (response) { return $q.reject(response); }); }; /** * Registers user account using server API * @param {{login: String, password: String, repassword: String, name: String, email: String, phone: String}} [data] */ User.prototype.register = function (data) { var self = this; var deferred = $q.defer(); if (this.authenticated || null == data) { deferred.reject({message: translate(this.authenticated ? 'User are logged in' : 'Empty data')}); return deferred.promise; } indicator.start('user.register'); $http.post(apiUrl + '/user/register', data) .then(angular.bind(this, this.onDone, deferred), angular.bind(this, this.onFail, deferred)); return deferred.promise.then(function (response) { indicator.stop('user.register'); self.authenticated = true; self.init(response.data); $rootScope.$emit('user.authenticate'); return response; }, function (response) { indicator.stop('user.register'); return $q.reject(response); }); }; User.prototype.logout = function () { var self = this; indicator.start('user.logout'); return this.post('logout').then(function (response) { indicator.stop('user.logout'); self.authenticated = false; self.init(null); $rootScope.$emit('user.logout'); return response; }, function (response) { indicator.stop('user.logout'); $rootScope.$emit('user.logout.error'); return $q.reject(response); }); }; /** * Updates user profile using server API * @param {{login: String, password: String, repassword: String, name: String, email: String}} [data] */ User.prototype.update = function (data) { var self = this; if (this.authenticated && angular.isObject(data)) { return this.post('update', data).then(function (response) { self.init(response.data); return response; }); } var deferred = $q.defer(); deferred.reject({message: translate('User should be logged in')}); return deferred.promise; }; User.prototype.read = function () { var self = this; if (this.authenticated) { return this.post('fullinfo').then(function (response) { self.init(response.data); return response; }); } var deferred = $q.defer(); deferred.reject({message: translate('User should be logged in')}); return deferred.promise; }; User.prototype.switchLanguage = function (language) { var defer = $q.defer(); $window.document.cookie = 'language=' + encodeURIComponent(language) + ';path=/'; defer.resolve(); return defer.promise; }; return new User(undefined, cfg.userInfo); }]);