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
JavaScript
(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