UNPKG

angular-firebase-authorizator

Version:

Beta version of authorizator for angular linked to firebase, it creates a model in firestore to assign permissions to users an roles, and creates a view to update this permissions

907 lines (877 loc) 91.2 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('firebase'), require('@angular/router'), require('rxjs/operators'), require('@angular/material/dialog'), require('@angular/material/snack-bar'), require('@angular/material/grid-list'), require('@angular/material/slide-toggle'), require('@angular/material/button-toggle'), require('@angular/material/select'), require('@angular/material/icon'), require('@angular/material/tabs'), require('@angular/material/table'), require('@angular/material/button'), require('@angular/material/input'), require('@angular/material/progress-bar'), require('@angular/common'), require('@angular/cdk/table'), require('@angular/forms')) : typeof define === 'function' && define.amd ? define('angular-firebase-authorizator', ['exports', '@angular/core', 'rxjs', 'firebase', '@angular/router', 'rxjs/operators', '@angular/material/dialog', '@angular/material/snack-bar', '@angular/material/grid-list', '@angular/material/slide-toggle', '@angular/material/button-toggle', '@angular/material/select', '@angular/material/icon', '@angular/material/tabs', '@angular/material/table', '@angular/material/button', '@angular/material/input', '@angular/material/progress-bar', '@angular/common', '@angular/cdk/table', '@angular/forms'], factory) : (global = global || self, factory(global['angular-firebase-authorizator'] = {}, global.ng.core, global.rxjs, global.firebase, global.ng.router, global.rxjs.operators, global.ng.material.dialog, global.ng.material['snack-bar'], global.ng.material['grid-list'], global.ng.material['slide-toggle'], global.ng.material['button-toggle'], global.ng.material.select, global.ng.material.icon, global.ng.material.tabs, global.ng.material.table, global.ng.material.button, global.ng.material.input, global.ng.material['progress-bar'], global.ng.common, global.ng.cdk.table, global.ng.forms)); }(this, (function (exports, core, rxjs, firebase, router, operators, dialog, snackBar, gridList, slideToggle, buttonToggle, select, icon, tabs, table, button, input, progressBar, common, table$1, forms) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __exportStar(m, exports) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } function __values(o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result.default = mod; return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } (function (Operation) { Operation[Operation["Create"] = 0] = "Create"; Operation[Operation["Read"] = 1] = "Read"; Operation[Operation["Update"] = 2] = "Update"; Operation[Operation["Delete"] = 3] = "Delete"; Operation[Operation["Deny"] = 4] = "Deny"; })(exports.Operation || (exports.Operation = {})); var ProgressbarService = /** @class */ (function () { function ProgressbarService() { this.usersWaitBar = new rxjs.BehaviorSubject(null); this.rolesWaitBar = new rxjs.BehaviorSubject(null); } ProgressbarService.prototype.showUsersWaitBar = function (show) { this.usersWaitBar.next(show); }; ProgressbarService.prototype.showRolesWaitBar = function (show) { this.rolesWaitBar.next(show); }; ProgressbarService.ɵprov = core["ɵɵdefineInjectable"]({ factory: function ProgressbarService_Factory() { return new ProgressbarService(); }, token: ProgressbarService, providedIn: "root" }); ProgressbarService = __decorate([ core.Injectable({ providedIn: 'root' }), __metadata("design:paramtypes", []) ], ProgressbarService); return ProgressbarService; }()); var AUTHORIZATOR_CONFIG = new core.InjectionToken('AUTHORIZATOR_CONFIG'); var AuthGuard = /** @class */ (function () { function AuthGuard(router, authorizatorservice) { this.router = router; this.authorizatorservice = authorizatorservice; } AuthGuard.prototype.isAuthorized = function (rootFirebasePath, resource) { var _this = this; return new rxjs.Observable(function (observer) { firebase.auth().onAuthStateChanged(function (user) { if (user) { if (resource) { Promise.all([ _this.authorizatorservice.getUser(rootFirebasePath, user.email), _this.authorizatorservice.getRolesByUser(rootFirebasePath, user.email) ]).then(function (values) { var userDB = values[0]; var rolesDB = values[1] || []; var resourcePermissionsByUser = []; var resourcePermissionsByRoles = []; if (userDB && userDB.data.permissions) { userDB.data.permissions.filter(function (permission) { return permission.resource === resource || permission.resource === 'owner'; }).forEach(function (permission) { resourcePermissionsByUser.push(permission); }); } rolesDB.forEach(function (rolDB) { if (rolDB.data.permissions) { rolDB.data.permissions.filter(function (permission) { return permission.resource === resource; }).forEach(function (permission) { resourcePermissionsByRoles.push(permission); }); } }); if (resourcePermissionsByUser && resourcePermissionsByUser.length > 0 && resourcePermissionsByUser.findIndex(function (permission) { return permission.operations && permission.operations.findIndex(function (operation) { return operation === exports.Operation.Deny; }) > -1; }) === -1) { observer.next('authorized'); } else { if (resourcePermissionsByRoles && resourcePermissionsByRoles.length > 0 && resourcePermissionsByRoles.findIndex(function (permission) { return permission.operations.findIndex(function (operation) { return operation === exports.Operation.Deny; }) > -1; }) === -1) { observer.next('authorized'); } else { console.error('Unauthorized resource'); observer.next('unauthorized'); } } }).catch(function (error) { console.error('Error getting permissions from database'); console.error(error); observer.next('unauthorized'); }); } else { console.error('Resource not received'); observer.next('unauthorized'); } } else { console.error('Unauthenticated user'); observer.next('unauthenticated'); } }, function (err) { observer.error(err); }, function () { observer.complete(); }); }); }; AuthGuard.prototype.canActivate = function (route, state) { var _this = this; var rootFirebasePath = route.data.rootFirebasePath; var resource = route.data.resource; var anonymousRoute = route.data.anonymousRoute || '/'; var unauthorizedRoute = route.data.unauthorizedRoute || '/'; var findVariable = rootFirebasePath.indexOf(':'); if (findVariable > -1) { var variableEnd = rootFirebasePath.indexOf('/', findVariable); var variableFound_1; if (variableEnd > -1) { variableFound_1 = rootFirebasePath.substring(findVariable + 1, variableEnd); } else { variableFound_1 = rootFirebasePath.substring(findVariable + 1); } var existsVariable = Object.keys(route.params).findIndex(function (key) { return key === variableFound_1; }); if (existsVariable > -1) { rootFirebasePath = rootFirebasePath.replace(':' + variableFound_1, route.params[variableFound_1]); } } return this.isAuthorized(rootFirebasePath, resource).pipe(operators.take(1), operators.map(function (isAuth) { if (isAuth === 'unauthenticated') { _this.router.navigate([anonymousRoute], { queryParams: { returnUrl: state.url } }); return false; } if (isAuth === 'unauthorized') { _this.router.navigate([unauthorizedRoute], { queryParams: { returnUrl: state.url } }); return false; } if (isAuth === 'authorized') { return true; } return false; }), operators.catchError(function (err) { console.error('Error getting authenticated user'); console.error(err); // not resource sended so redirect to unauthorized page with the return url _this.router.navigate([anonymousRoute], { queryParams: { returnUrl: state.url } }); return rxjs.of(false); })); }; AuthGuard.ctorParameters = function () { return [ { type: router.Router }, { type: AuthorizatorService } ]; }; AuthGuard = __decorate([ core.Injectable(), __metadata("design:paramtypes", [router.Router, AuthorizatorService]) ], AuthGuard); return AuthGuard; }()); var AuthorizatorService = /** @class */ (function () { function AuthorizatorService() { } //#region Users AuthorizatorService.prototype.addUser = function (rootFirebasePath, user) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/users').replace('//', '/'); firestore$1.collection(path).doc(user.id).get().then(function (userDB) { if (userDB.exists) { reject({ key: 'exists', message: 'User already exists' }); } else { firestore$1.collection(path).doc(user.id).set(user.data).then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error adding user' }); }); } }); }); }; AuthorizatorService.prototype.removeUser = function (rootFirebasePath, userId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/users').replace('//', '/'); firestore$1.collection(path).doc(userId).delete().then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error removing user' }); }); }); }; AuthorizatorService.prototype.getUser = function (rootFirebasePath, userId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/users').replace('//', '/'); firestore$1.collection(path).doc(userId).get().then(function (userDB) { resolve({ id: userDB.id, data: userDB.data() }); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getUsers = function (rootFirebasePath) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); if (!rootFirebasePath) { rootFirebasePath = ''; } var path = (rootFirebasePath + '/users').replace('//', '/'); firestore$1.collection(path).get().then(function (usersDB) { if (usersDB.empty) { resolve(null); } else { resolve(usersDB.docs.map(function (userDB) { return { id: userDB.id, data: userDB.data() }; })); } }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.updateUserPermissions = function (rootFirebasePath, user) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/users').replace('//', '/'); firestore$1.collection(path).doc(user.id).get().then(function (userDB) { if (!userDB.exists) { reject({ key: 'notexists', message: 'User not exists' }); } else { firestore$1.collection(path).doc(user.id).update({ permissions: user.data.permissions }).then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error updating permissions' }); }); } }); }); }; //#endregion //#region Resources AuthorizatorService.prototype.addResource = function (rootFirebasePath, resource) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/resources').replace('//', '/'); firestore$1.collection(path).add(resource.data).then(function (resourceCreated) { resolve(resourceCreated.id); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.removeResource = function (rootFirebasePath, resourceId) { var _this = this; return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var resourcePath = (rootFirebasePath + '/resources').replace('//', '/'); var usersPath = (rootFirebasePath + '/users').replace('//', '/'); var rolesPath = (rootFirebasePath + '/roles').replace('//', '/'); var resourceRef = firestore$1.collection(resourcePath).doc(resourceId); Promise.all([ _this.getUsersByResource(rootFirebasePath, resourceId), _this.getRolesByResource(rootFirebasePath, resourceId) ]).then(function (values) { var batch = firestore$1.batch(); var usersToUpdate = values[0]; var rolesToUpdate = values[1]; usersToUpdate.forEach(function (userToUpdate) { userToUpdate.data.permissions.splice(userToUpdate.data.permissions.findIndex(function (permission) { return permission.resource === resourceId; }), 1); var userRef = firestore$1.collection(usersPath).doc(userToUpdate.id); batch.update(userRef, { data: userToUpdate.data }); }); rolesToUpdate.forEach(function (roleToUpdate) { roleToUpdate.data.permissions.splice(roleToUpdate.data.permissions.findIndex(function (permission) { return permission.resource === resourceId; }), 1); var roleRef = firestore$1.collection(rolesPath).doc(roleToUpdate.id); batch.update(roleRef, { data: roleToUpdate.data }); }); batch.delete(resourceRef); batch.commit().then(function () { resolve(); }).catch(function (error) { reject(error); }); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.updateResource = function (rootFirebasePath, resource) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/resources').replace('//', '/'); firestore$1.collection(path).doc(resource.id).set(resource.data).then(function () { resolve(); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getResource = function (rootFirebasePath, resourceId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/resources').replace('//', '/'); firestore$1.collection(path).doc(resourceId).get().then(function (resourceDB) { resolve({ id: resourceDB.id, data: resourceDB.data() }); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getResources = function (rootFirebasePath) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/resources').replace('//', '/'); firestore$1.collection(path).get().then(function (resourcesDB) { if (resourcesDB.empty) { resolve(null); } else { resolve(resourcesDB.docs.map(function (resourceDB) { return { id: resourceDB.id, data: resourceDB.data() }; })); } }).catch(function (error) { reject(error); }); }); }; // endregion //#region Roles AuthorizatorService.prototype.addRole = function (rootFirebasePath, role) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).where('name', '==', role.data.name).get().then(function (roleDB) { if (!roleDB.empty) { reject({ key: 'exists', message: 'Role already exists' }); } else { firestore$1.collection(path).add(role.data).then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error adding role' }); }); } }); }); }; AuthorizatorService.prototype.removeRole = function (rootFirebasePath, roleId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).doc(roleId).delete().then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error removing role' }); }); }); }; AuthorizatorService.prototype.updateRole = function (rootFirebasePath, role) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).doc(role.id).set(role.data).then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error updating role' }); }); }); }; AuthorizatorService.prototype.getRole = function (rootFirebasePath, roleId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).doc(roleId).get().then(function (roleDB) { resolve({ id: roleDB.id, data: roleDB.data() }); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getRoles = function (rootFirebasePath) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); if (!rootFirebasePath) { rootFirebasePath = ''; } var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).get().then(function (rolesDB) { if (rolesDB.empty) { resolve(null); } else { resolve(rolesDB.docs.map(function (roleDB) { return { id: roleDB.id, data: roleDB.data() }; })); } }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getRolesByResource = function (rootFirebasePath, resourceId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).where('data.resources', 'array-contains', resourceId).get().then(function (rolesDB) { if (rolesDB.empty) { resolve(null); } else { resolve(rolesDB.docs.map(function (roleDB) { return { id: roleDB.id, data: roleDB.data() }; })); } }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getRolesByUser = function (rootFirebasePath, userId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).where('users', 'array-contains', userId).get().then(function (rolesDB) { if (rolesDB.empty) { resolve(null); } else { resolve(rolesDB.docs.map(function (roleDB) { return { id: roleDB.id, data: roleDB.data() }; })); } }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.updateRolePermissions = function (rootFirebasePath, role) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); rootFirebasePath = rootFirebasePath || ''; var path = (rootFirebasePath + '/roles').replace('//', '/'); firestore$1.collection(path).doc(role.id).get().then(function (roleDB) { if (!roleDB.exists) { reject({ key: 'notexists', message: 'Role not exists' }); } else { firestore$1.collection(path).doc(role.id).update({ permissions: role.data.permissions }).then(function () { resolve(); }).catch(function (error) { console.error(error); reject({ key: 'defaulterror', message: 'Error updating permissions' }); }); } }); }); }; // endregion //#region Roles AuthorizatorService.prototype.removeUserFromRole = function (rootFirebasePath, userId) { var _this = this; return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var usersPath = (rootFirebasePath + '/users').replace('//', '/'); var rolesPath = (rootFirebasePath + '/roles').replace('//', '/'); _this.getRolesByUser(rootFirebasePath, userId).then(function (rolesDB) { var batch = firestore$1.batch(); var rolesToUpdate = rolesDB; rolesToUpdate.forEach(function (roleToUpdate) { roleToUpdate.data.users.splice(roleToUpdate.data.users.findIndex(function (user) { return user === userId; }), 1); var roleRef = firestore$1.collection(rolesPath).doc(roleToUpdate.id); batch.update(roleRef, { data: roleToUpdate.data }); }); var userRef = firestore$1.collection(usersPath).doc(userId); batch.delete(userRef); batch.commit().then(function () { resolve(); }).catch(function (error) { reject(error); }); }).catch(function (error) { reject(error); }); }); }; AuthorizatorService.prototype.getUsersByResource = function (rootFirebasePath, resourceId) { return new Promise(function (resolve, reject) { var firestore$1 = firebase.firestore(); var path = (rootFirebasePath + '/users').replace('//', '/'); firestore$1.collection(path).where('data.resources', 'array-contains', resourceId).get().then(function (usersDB) { if (usersDB.empty) { resolve(null); } else { resolve(usersDB.docs.map(function (userDB) { return { id: userDB.id, data: userDB.data() }; })); } }).catch(function (error) { reject(error); }); }); }; AuthorizatorService = __decorate([ core.Injectable(), __metadata("design:paramtypes", []) ], AuthorizatorService); return AuthorizatorService; }()); var AngularFirebaseAuthotizatorComponent = /** @class */ (function () { function AngularFirebaseAuthotizatorComponent(progressbarservice, cd, authorizatorConfig, authroizatorservice) { this.progressbarservice = progressbarservice; this.cd = cd; this.authorizatorConfig = authorizatorConfig; this.authroizatorservice = authroizatorservice; this.isUsersWaitBarShowing = false; this.isRolesWaitBarShowing = false; } AngularFirebaseAuthotizatorComponent.prototype.ngOnInit = function () { var _this = this; this.progressbarservice.usersWaitBar.subscribe(function (isShowing) { _this.isUsersWaitBarShowing = isShowing; _this.cd.detectChanges(); }); this.progressbarservice.rolesWaitBar.subscribe(function (isShowing) { _this.isRolesWaitBarShowing = isShowing; _this.cd.detectChanges(); }); }; AngularFirebaseAuthotizatorComponent.ctorParameters = function () { return [ { type: ProgressbarService }, { type: core.ChangeDetectorRef }, { type: undefined, decorators: [{ type: core.Inject, args: [AUTHORIZATOR_CONFIG,] }] }, { type: AuthorizatorService } ]; }; __decorate([ core.Input(), __metadata("design:type", String) ], AngularFirebaseAuthotizatorComponent.prototype, "rootFirebasePath", void 0); AngularFirebaseAuthotizatorComponent = __decorate([ core.Component({ selector: 'angular-firebase-authotizator', template: "<mat-tab-group>\n <mat-tab label=\"Users\">\n <mat-progress-bar color=\"accent\" mode=\"indeterminate\" *ngIf=\"isUsersWaitBarShowing\"></mat-progress-bar>\n <lib-users [rootFirebasePath]=\"rootFirebasePath\"></lib-users>\n </mat-tab>\n <mat-tab label=\"Roles\">\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isRolesWaitBarShowing\"></mat-progress-bar>\n <lib-roles [rootFirebasePath]=\"rootFirebasePath\"></lib-roles>\n </mat-tab>\n</mat-tab-group>", styles: ["table{width:100%}::ng-deep .success-bar{background-color:#c8e6c9!important;color:#1b5e20!important}::ng-deep .error-bar{background-color:#ffcdd2!important;color:#b71c1c!important}"] }), __param(2, core.Inject(AUTHORIZATOR_CONFIG)), __metadata("design:paramtypes", [ProgressbarService, core.ChangeDetectorRef, Object, AuthorizatorService]) ], AngularFirebaseAuthotizatorComponent); return AngularFirebaseAuthotizatorComponent; }()); var PermissionManagerComponent = /** @class */ (function () { function PermissionManagerComponent(authorizatorConfig, cd, data, authorizatorservice, snackbar) { this.authorizatorConfig = authorizatorConfig; this.cd = cd; this.data = data; this.authorizatorservice = authorizatorservice; this.snackbar = snackbar; this.AllowedOperation = exports.Operation; this.resourceCols = 5; this.permissionCols = 5; this.change = new core.EventEmitter(); this.user = data.user; this.role = data.role; } PermissionManagerComponent.prototype.ngOnInit = function () { var _this = this; if (this.authorizatorConfig && this.authorizatorConfig.permissions) { this.permissionsConfig = this.authorizatorConfig.permissions.map(function (permission) { return { resource: permission.resource, operations: permission.allowedOperations.map(function (operation) { return { id: operation, value: _this.user ? (_this.user.data.permissions ? (_this.user.data.permissions.find(function (perm) { return perm.resource === permission.resource.id; }) ? (_this.user.data.permissions.find(function (perm) { return perm.resource === permission.resource.id; }).operations.findIndex(function (oper) { return oper === operation; }) > -1) : false) : false) : _this.role ? (_this.role.data.permissions ? (_this.role.data.permissions.find(function (perm) { return perm.resource === permission.resource.id; }) ? (_this.role.data.permissions.find(function (perm) { return perm.resource === permission.resource.id; }).operations.findIndex(function (oper) { return oper === operation; }) > -1) : false) : false) : false }; }) }; }); } else { console.error("Configuration of module missing, please add the next code in the Module declaration:\n AngularFirebaseAuthorizatorModule.forRoot({\n permissions: [\n {\n resource: {\n id: 'someid',\n data: {\n description: 'Resource description'\n }\n },\n allowedOperations: [\n Operation.Create,\n Operation.Read,\n Operation.Update,\n Operation.Delete,\n Operation.Deny\n ]\n }\n ]\n })"); } }; PermissionManagerComponent.prototype.ngAfterViewInit = function () { if (this.permissionsConfig) { var permissionManagerWidth = document.getElementById('permission_manager_container').offsetWidth; if (permissionManagerWidth <= 400) { this.resourceCols = 5; this.permissionCols = 5; } else if (permissionManagerWidth > 400 && permissionManagerWidth <= 600) { this.resourceCols = 6; this.permissionCols = 4; } else if (permissionManagerWidth > 600 && permissionManagerWidth <= 800) { this.resourceCols = 7; this.permissionCols = 3; } else { this.resourceCols = 8; this.permissionCols = 2; } } this.cd.detectChanges(); }; PermissionManagerComponent.prototype.onPermissionChange = function (resource, operation, event) { var _this = this; var updatePermissionsMonitor = new rxjs.BehaviorSubject(null); var permissions = this.user ? this.user.data.permissions || [] : this.role ? this.role.data.permissions || [] : []; var permissionIndex = permissions.findIndex(function (permission) { return permission.resource === resource.id; }); if (event.checked) { if (permissionIndex > -1) { var operationIndex = permissions[permissionIndex].operations.findIndex(function (oper) { return oper === operation; }); if (operationIndex === -1) { permissions[permissionIndex].operations.push(operation); updatePermissionsMonitor.next(permissions); } } else { permissions.push({ resource: resource.id, operations: [operation] }); updatePermissionsMonitor.next(permissions); } } else { if (permissionIndex > -1) { var operationIndex = permissions[permissionIndex].operations.findIndex(function (oper) { return oper === operation; }); if (operationIndex > -1) { if (permissions[permissionIndex].operations.length > 1) { permissions[permissionIndex].operations.splice(operationIndex, 1); } else { permissions.splice(permissionIndex, 1); } updatePermissionsMonitor.next(permissions); } } } updatePermissionsMonitor.subscribe(function (permissionsToUpdate) { if (permissionsToUpdate) { if (_this.user) { var userToUpdate = _this.data.user; userToUpdate.data.permissions = permissionsToUpdate; var config_1 = new snackBar.MatSnackBarConfig(); config_1.duration = 2000; _this.authorizatorservice.updateUserPermissions(_this.data.rootFirebasePath, userToUpdate).then(function () { config_1.panelClass = ['success-bar']; _this.snackbar.open('Permissions updated', null, config_1); }).catch(function (error) { config_1.panelClass = ['error-bar']; _this.snackbar.open(error.message, null, config_1); }); } if (_this.role) { var roleToUpdate = _this.data.role; roleToUpdate.data.permissions = permissionsToUpdate; var config_2 = new snackBar.MatSnackBarConfig(); config_2.d