unserver-unify
Version:
543 lines (535 loc) • 20.1 kB
JavaScript
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;
};
});