UNPKG

unserver-unify

Version:

543 lines (535 loc) 20.1 kB
angular.module('bamboo.common').provider('loginService', function() { var userToken = sessionStorage.getItem('userToken'), errorState = 'errstate', logoutState = 'index.home'; this.$get = function($rootScope, $http, $q, $location, $state, ApiService, AppConfig, LocalConfig, PermRoleStore, PermPermissionStore, CommonService, $translate, toastrHelper, $filter, deviceDetector, $localStorage) { /** * Low-level, private functions. */ var setToken = function(token) { if (!token) { sessionStorage.removeItem('userToken'); } else { sessionStorage.setItem('userToken', token); } }; var getLoginData = function(oldDoamin) { userToken = oldDoamin || userToken; var subDomain = null; if (LocalConfig.SUBDOMAIN && LocalConfig.SUBDOMAIN.length > 1) { subDomain = LocalConfig.SUBDOMAIN; }else if(LocalConfig.SubDomainMapping){ var hstr = $location.host(); for(var key in LocalConfig.SubDomainMapping){ if(hstr.indexOf(key)>-1){ subDomain=LocalConfig.SubDomainMapping[key]; break; } } } if(!subDomain) { var hstr = $location.host().split("."); if (hstr.length > 2) { var index = hstr.length - 3; if (isNaN(parseInt(hstr[index]))) { subDomain = hstr[index]; } } } if (subDomain) { wrappedService.loggedDomain = true; wrappedService.subDomain = subDomain; } else if (userToken) { wrappedService.loggedDomain = false; wrappedService.subDomain = userToken; } else { wrappedService.loggedDomain = false; // wrappedService.userRole = userRoles.public; wrappedService.isLogged = false; wrappedService.doneLoading = true; } }; var managePermissions = function() { // Register routing function. /** * Gets triggered when a resolve isn't fulfilled * NOTE: when the user doesn't have required permissions for a state, this event * it's not triggered. * * In order to redirect to the desired state, the $http status code gets parsed. * If it's an HTTP code (ex: 403), could be prefixed with a string (ex: resolvename403), * to handle same status codes for different resolve(s). * This is defined inside $state.redirectMap. */ $rootScope.$on('$stateChangeError', function(event, to, toParams, from, fromParams, error) { /** * This is a very clever way to implement failure redirection. * You can use the value of redirectMap, based on the value of the rejection * So you can setup DIFFERENT redirections based on different promise errors. */ var errorObj, redirectObj; // in case the promise given to resolve function is an $http request // the error is a object containing the error and additional informations error = error && (typeof error === 'object') && error.status ? error.status.toString() : error; // in case of a random 4xx/5xx status code from server, user gets loggedout // otherwise it *might* forever loop (look call diagram) if (/^[45]\d{2}$/.test(error)) { wrappedService.logoutUser(); } /** * Generic redirect handling. * If a state transition has been prevented and it's not one of the 2 above errors, means it's a * custom error in your application. * * redirectMap should be defined in the $state(s) that can generate transition errors. */ if (angular.isDefined(to.redirectMap) && angular.isDefined(to.redirectMap[error])) { if (typeof to.redirectMap[error] === 'string') { return $state.go(to.redirectMap[error], { error: error }, { location: false, inherit: false }); } else if (typeof to.redirectMap[error] === 'object') { redirectObj = to.redirectMap[error]; return $state.go(redirectObj.state, { error: redirectObj.prefix + error }, { location: false, inherit: false }); } } return $state.go(errorState, { error: error }, { location: false, inherit: false }); }); }; /** * High level, public methods */ var wrappedService = { getMyProfile: function(force) { var deferred = $q.defer(); var self = this; if (!this.user) { deferred.reject(null); } else if (this.profile && !force) { deferred.resolve(this.profile); } else { ApiService.get('/profile/').then(function(result) { if (result.data.success) { self.profile = result.data.data; deferred.resolve(self.profile); } else { deferred.reject(null); } }); } return deferred.promise; }, getLoginInfo: function(force) { var self = this; if (this.school) { force = force || false; if (!force && this.user) { return $q.when(this.user); } else { return ApiService.getLoginStatus().then(function(user) { if (user) { self.user = user; if(self.school.disableAdminStudy){ if(!user.grole||user.grole=='user'){ self.school.disableAdminStudy=false; } } } else { self.user = null; } return $q.when(self.user); }); } } else { return ApiService.getSchoolInfo(this.subDomain).then(function(school) { self.school = school; $rootScope.currentSchool = school; $rootScope.initLang(); return ApiService.getLoginStatus().then(function(user) { if (user) { self.user = user; if(self.school.disableAdminStudy){ if(!user.grole||user.grole=='user'){ self.school.disableAdminStudy=false; } } } else { self.user = null; } return $q.when(self.user); }); }, function(err) { console.log(" School Service Retry counter : " + $rootScope.apiRetry); if (!$rootScope.apiRetry) { $rootScope.apiRetry = 1; $state.go('index.home'); } else if ($rootScope.apiRetry < 4) { $rootScope.apiRetry++; $state.go('index.home'); } else { $state.go('errstate'); } }); } }, login: function(loginInfo) { var self = this; ApiService.resetLogin(); var deferred = $q.defer(); return ApiService.post('/login', loginInfo).then(function(result) { console.log(result); if (result.data.success) { console.log(result.data.data); var lastLogin = result.data.data.lastLogin && $filter('date')(result.data.data.lastLogin, 'medium'); var failedLogin = result.data.data.failedLogin; var successInfo = "Last login time: " + lastLogin if (failedLogin) { successInfo += (" , " + " Failed login times: " + failedLogin); } var loginCounter = result.data.data.loginCounter; return self.getLoginInfo(true).then(function(user) { if (user) { user.loginCounter = loginCounter; toastrHelper.showToastrSuccess(successInfo, 10000); return self.loginHandler(user); } else { return null; } }); } else { self.user = null; //return null; console.log(result.data.error); console.log(result.data); $rootScope.MOBILE_LOGIN_ERROR = result.data.error; if(result.data.error&&deviceDetector.isDesktop()){ if(result.data.error.indexOf('School expired!')>-1){ CommonService.showError($translate.instant("Your school has expired, please contact your system administrator.")); }else if(result.data.error.indexOf('School is Locked')>-1){ CommonService.showError($translate.instant("The website has been locked. Please send email to info@bamboosys.com to contact Bamboo System Technology.")); } else if(result.data.error.indexOf('Wrong password')>-1){ CommonService.showError($translate.instant("Wrong Password")); } else if(result.data.error.indexOf('The account is not actived')>-1){ CommonService.showError($translate.instant("The account is not actived, please check email" + result.data.email)); }else{ CommonService.showError($translate.instant(result.data.error)); } }else if(result.data.error){ CommonService.showError($translate.instant(result.data.error)); } deferred.reject(result); return deferred.promise; } }); }, ldapLogin: function(loginInfo) { var self = this; ApiService.resetLogin(); var deferred = $q.defer(); var info={ username:loginInfo.name, password:loginInfo.pass, }; console.log(info); return ApiService.post('/oauth/ldaplogin', info).then(function(result) { console.log(result); if (result.data.success) { console.log(result.data.data); return self.getLoginInfo(true).then(function(user) { if (user) { return self.loginHandler(user); } else { return null; } }); } else { self.user = null; //return null; console.log(result.data.error); console.log(result.data); CommonService.showError($translate.instant(result.data.error)); deferred.reject(result); return deferred.promise; } }); }, logout: function(done) { var self = this; ApiService.submitActivityRecord(function() { return ApiService.post('/logout').then(function() { self.user = null; self.profile = null; ApiService.resetLogin(); return self.logoutUser(done); }); }); }, loginHandler: function(user) { /** * Custom logic to manually set userRole goes here * * Commented example shows an userObj coming with a 'completed' * property defining if the user has completed his registration process, * validating his/her email or not. * * EXAMPLE: * if (user.hasValidatedEmail) { * wrappedService.userRole = userRoles.registered; * } else { * wrappedService.userRole = userRoles.invalidEmail; * $state.go('app.nagscreen'); * } */ // setup token setToken(this.subDomain); // update user if (!wrappedService.user) { wrappedService.user = {}; } angular.extend(wrappedService.user, user); // flag true on isLogged wrappedService.isLogged = true; // update userRole wrappedService.controlPermissions(); return user; }, loginUser: function(user) { this.loginHandler(user); }, // exactly copy from admin code checkRole: function(RoleName) { console.log(RoleName); var self = this; var deferred = $q.defer(); this.getLoginInfo().then(function(user) { if (user) { if (user.roles && user.roles.indexOf(RoleName) > -1) { console.log('true 1'); deferred.resolve(true); } else if (user.is_admin) { console.log('true 2'); deferred.resolve(true); } else if (self.userRoles && self.userRoles.length && self.userRoles.indexOf(RoleName) > -1) { console.log('true 3'); deferred.resolve(true); } else { self.checkPermission(RoleName, function() { if (self.userRoles && self.userRoles.length && self.userRoles.indexOf(RoleName) > -1) { console.log('true 4'); deferred.resolve(true); } else { // deferred.resolve(false); deferred.reject(false); } }) } } else { deferred.reject(false); } }); return deferred.promise; }, controlPermissions: function() { var self = this; function checkRole(RoleName) { return self.checkRole(RoleName); } PermRoleStore.defineManyRoles({ Teacher: function(Session) { return checkRole('Teacher'); }, NewsAdmin: function(Session) { return checkRole('NewsAdmin'); }, BlogAdmin: function(Session) { return checkRole('BlogAdmin'); }, BbsAdmin: function(Session) { return checkRole('BlogAdmin'); }, EventAdmin: function(Session) { return checkRole('EventAdmin'); }, DepAdmin: function(Session) { return checkRole('DepAdmin'); }, ComAdmin: function(Session) { return checkRole('ComAdmin'); }, AssetAdmin: function(Session) { return checkRole('AssetAdmin'); }, Admin: function(Session) { return checkRole('Admin'); }, Super: function(Session) { return checkRole('Super'); }, SysManager: function(Session) { return checkRole('SysManager'); }, SiteAdmin: function(Session) { return checkRole('SiteAdmin'); }, }); // Define user permission calling back-end PermPermissionStore.definePermission('login', function() { var deferred = $q.defer(); self.getLoginInfo().then(function(user) { if (user) { deferred.resolve(true); } else { deferred.reject(false); } }); return deferred.promise; }); PermPermissionStore.defineManyPermissions(AppConfig.Permissions, function(permissionName) { var deferred = $q.defer(); self.checkPermission(permissionName, function(result) { // console.log(permissionName); if (result) { // console.log(result); deferred.resolve(true); } else { deferred.reject(false); } }) return deferred.promise; }) }, checkPermission: function(perName, callback) { var self = this; if (self.userPermissions) { return callback(self.userPermissions[perName]); } else { buildPermission().then(function(result) { if (result) { return callback(self.userPermissions[perName]); } else { return callback(false); } }) }; function buildPermission() { if (!self.permissionDefer) { self.permissionDefer = $q.defer(); self.getLoginInfo().then(function(user) { if (user) { // build roles var userRoles = []; if (user.is_admin) { userRoles.push('Super'); } else if (user.grole && AppConfig.RoleTranslate[user.grole]) { userRoles.push(AppConfig.RoleTranslate[user.grole]); } if (user.roles && user.roles.length) { userRoles = userRoles.concat(user.roles); } self.userRoles = userRoles; // build permissions var temp = {}; for (var i = 0; i < AppConfig.Permissions.length; i++) { var permission = AppConfig.Permissions[i]; // console.log(permission); if (user.permissions && user.permissions.indexOf(permission) > -1) { temp[permission] = true; } else { for (var x = 0; x < self.userRoles.length; x++) { var role = self.userRoles[x]; if (AppConfig.RoleInfos[role]) { var _default = AppConfig.RoleInfos[role].default; if (_default.indexOf(permission) > -1) { temp[permission] = true; break; } } if (self.school.rolesPermission && self.school.rolesPermission[role]) { var _default = self.school.rolesPermission[role].permissions; if (_default.indexOf(permission) > -1) { temp[permission] = true; break; } } } } } self.userPermissions = temp; self.permissionDefer.resolve(temp); } else { self.userPermissions = null; self.userRoles = null; self.permissionDefer.resolve(null); } }); } return self.permissionDefer.promise; //return deferred.promise; }; }, logoutUser: function(done) { /** * De-registers the userToken remotely * then clears the loginService as it was on startup */ ApiService.resetLogin(); setToken(null); this.user = null; var oldDomain = this.subDomain; this.subDomain = null; this.school = null; $rootScope.currentSchool = null; this.isLogged = false; this.loggedDomain = false; if (done) { done(); //callback function } getLoginData(oldDomain); if (!done) { $localStorage.$reset(); $state.go(logoutState, {}, { reload: true }); } }, setCurrentDomain: function(school) { this.school = school; this.subDomain = school.key; ApiService.setGid(school._id); }, clearCurrentDomain: function(school) { this.school = null; this.subDomain = null; ApiService.setGid(null); }, /** * Public properties */ userRole: null, user: null, isLogged: null, pendingStateChange: null, doneLoading: null, subDomain: null, school: null, loggedDomain: false }; getLoginData(); managePermissions(); return wrappedService; }; });