UNPKG

ngx-firebase-cms

Version:

Angular Content Management System using Google Firebase (Authentication, Storage & Firestore)

270 lines 19.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable, Inject } from '@angular/core'; import { AngularFireAuth } from '@angular/fire/auth'; import { AngularFirestore } from '@angular/fire/firestore'; import { of } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; import { Router } from '@angular/router'; import * as firebase from 'firebase/app'; import { NzMessageService } from 'ng-zorro-antd'; import * as i0 from "@angular/core"; import * as i1 from "@angular/fire/auth"; import * as i2 from "ng-zorro-antd"; import * as i3 from "@angular/router"; import * as i4 from "@angular/fire/firestore"; export class AuthService { /** * @param {?} config * @param {?} afAuth * @param {?} message * @param {?} router * @param {?} afs */ constructor(config, afAuth, message, router, afs) { this.config = config; this.afAuth = afAuth; this.message = message; this.router = router; this.afs = afs; this.user$ = this.afAuth.authState.pipe(tap((/** * @param {?} res * @return {?} */ res => { if (res) { this.uid = res["uid"]; this.email = res["email"]; this.emailVerified = res["emailVerified"]; this.lastLogin = new Date(res["metadata"]["lastSignInTime"]); } })), switchMap((/** * @param {?} user * @return {?} */ user => { if (user) { return this.afs.doc(`users/${user.uid}`).valueChanges(); } else { return of(null); } })), tap((/** * @param {?} user * @return {?} */ user => { if (user) { this.displayName = user["displayName"]; this.profileURL = user["profileURL"]; this.role = user["roles"]; } }))); } /** * @param {?} username * @param {?} password * @return {?} */ login(username, password) { /** @type {?} */ let adminURL = this.config.adminURL || 'admin'; this.afAuth.auth.signInWithEmailAndPassword(username, password) .then((/** * @param {?} res * @return {?} */ res => { this.router.navigate([`${adminURL}/dashboard`]); })).catch((/** * @param {?} err * @return {?} */ err => { this.message.error(err); })); } /** * @param {?} username * @param {?} password * @return {?} */ signup(username, password) { /** @type {?} */ let adminURL = this.config.adminURL || 'admin'; this.afAuth.auth.createUserWithEmailAndPassword(username, password).then((/** * @param {?} res * @return {?} */ res => { /** @type {?} */ let data = { uid: res['user']['uid'], email: res['user']['email'], displayName: res['user']['email'], emailVerified: false, createdTime: firebase.firestore.FieldValue.serverTimestamp(), updatedTime: firebase.firestore.FieldValue.serverTimestamp(), lastLoginTime: firebase.firestore.FieldValue.serverTimestamp(), roles: ["Contributor"] }; if (res['user']['uid']) { this.afs.collection("users").doc(res['user']['uid']).set(data) .then((/** * @param {?} res * @return {?} */ res => { this.router.navigate([`${adminURL}/dashboard`]); })) .catch((/** * @param {?} err * @return {?} */ err => { this.message.error(err); })); } })); } /** * @return {?} */ signOut() { return this.afAuth.auth.signOut(); } /** * @private * @param {?} user * @return {?} */ updateUserData(user) { /** @type {?} */ const userRef = this.afs.doc(`users/${user.uid}`); /** @type {?} */ const data = { uid: user.uid, email: user.email, roles: ["Contributor"] }; return userRef.set(data, { merge: true }); } ///// Role-based Authorization ////// /** * @param {?} user * @return {?} */ canRead(user) { /** @type {?} */ const allowed = ['Administrator', 'Editor', 'Author', 'Contributor']; return this.checkAuthorization(user, allowed); } /** * @param {?} user * @return {?} */ canEdit(user) { /** @type {?} */ const allowed = ['Administrator', 'Editor']; return this.checkAuthorization(user, allowed); } /** * @param {?} user * @return {?} */ canDelete(user) { /** @type {?} */ const allowed = ['Administrator']; return this.checkAuthorization(user, allowed); } // determines if user has matching role /** * @private * @param {?} user * @param {?} allowedRoles * @return {?} */ checkAuthorization(user, allowedRoles) { if (!user) return false; for (const role of allowedRoles) { if (user.roles[role]) { return true; } } return false; } /** * @param {?} description * @return {?} */ log(description) { if (this.uid) { this.afs.collection('log').add({ "description": description, "uid": this.uid, "createdTime": firebase.firestore.FieldValue.serverTimestamp() }); } } } AuthService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ AuthService.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: ['env',] }] }, { type: AngularFireAuth }, { type: NzMessageService }, { type: Router }, { type: AngularFirestore } ]; /** @nocollapse */ AuthService.ngInjectableDef = i0.defineInjectable({ factory: function AuthService_Factory() { return new AuthService(i0.inject("env"), i0.inject(i1.AngularFireAuth), i0.inject(i2.NzMessageService), i0.inject(i3.Router), i0.inject(i4.AngularFirestore)); }, token: AuthService, providedIn: "root" }); if (false) { /** @type {?} */ AuthService.prototype.user$; /** @type {?} */ AuthService.prototype.uid; /** @type {?} */ AuthService.prototype.displayName; /** @type {?} */ AuthService.prototype.email; /** @type {?} */ AuthService.prototype.profileURL; /** @type {?} */ AuthService.prototype.emailVerified; /** @type {?} */ AuthService.prototype.lastLogin; /** @type {?} */ AuthService.prototype.role; /** * @type {?} * @private */ AuthService.prototype.config; /** * @type {?} * @private */ AuthService.prototype.afAuth; /** * @type {?} * @private */ AuthService.prototype.message; /** * @type {?} * @private */ AuthService.prototype.router; /** * @type {?} * @private */ AuthService.prototype.afs; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWZpcmViYXNlLWNtcy8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlL2F1dGguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxnQkFBZ0IsRUFBNEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRixPQUFPLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXpDLE9BQU8sS0FBSyxRQUFRLE1BQU0sY0FBYyxDQUFDO0FBR3pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7O0FBTWpELE1BQU0sT0FBTyxXQUFXOzs7Ozs7OztJQVd0QixZQUN5QixNQUFpQixFQUNoQyxNQUF1QixFQUN2QixPQUF5QixFQUN6QixNQUFjLEVBQ2QsR0FBcUI7UUFKTixXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ2hDLFdBQU0sR0FBTixNQUFNLENBQWlCO1FBQ3ZCLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBQ3pCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxRQUFHLEdBQUgsR0FBRyxDQUFrQjtRQUU3QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FDckMsR0FBRzs7OztRQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ1IsSUFBSSxHQUFHLEVBQUU7Z0JBQ1AsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7Z0JBQ3JC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Ozs7SUFHRiw2QkFBd0M7Ozs7O0lBQ3hDLDZCQUErQjs7Ozs7SUFDL0IsOEJBQWlDOzs7OztJQUNqQyw2QkFBc0I7Ozs7O0lBQ3RCLDBCQUE2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVBdXRoIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9hdXRoJztcbmltcG9ydCB7IEFuZ3VsYXJGaXJlc3RvcmUsIEFuZ3VsYXJGaXJlc3RvcmVEb2N1bWVudCB9IGZyb20gJ0Bhbmd1bGFyL2ZpcmUvZmlyZXN0b3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vaW50ZXJmYWNlL3VzZXInO1xuaW1wb3J0ICogYXMgZmlyZWJhc2UgZnJvbSAnZmlyZWJhc2UvYXBwJztcbmltcG9ydCB7IEZpcmViYXNlQXBwIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZSc7XG5pbXBvcnQgeyBFbnZDb25maWcgfSBmcm9tICcuLi9pbnRlcmZhY2UvZW52LWNvbmZpZyc7XG5pbXBvcnQgeyBOek1lc3NhZ2VTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZCc7XG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuLi9pbnRlcmZhY2UvbG9nJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2Uge1xuXG4gIHVzZXIkOiBPYnNlcnZhYmxlPFVzZXI+O1xuICB1aWQ6IHN0cmluZztcbiAgZGlzcGxheU5hbWU6IHN0cmluZztcbiAgZW1haWw6IHN0cmluZztcbiAgcHJvZmlsZVVSTDogc3RyaW5nO1xuICBlbWFpbFZlcmlmaWVkIDogYm9vbGVhbjtcbiAgbGFzdExvZ2luOiBEYXRlO1xuICByb2xlXG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdCgnZW52JykgcHJpdmF0ZSBjb25maWc6IEVudkNvbmZpZyxcbiAgICBwcml2YXRlIGFmQXV0aDogQW5ndWxhckZpcmVBdXRoLFxuICAgIHByaXZhdGUgbWVzc2FnZTogTnpNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgYWZzOiBBbmd1bGFyRmlyZXN0b3JlXG4gICkge1xuICAgIHRoaXMudXNlciQgPSB0aGlzLmFmQXV0aC5hdXRoU3RhdGUucGlwZShcbiAgICAgIHRhcChyZXMgPT4ge1xuICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgdGhpcy51aWQgPSByZXNbXCJ1aWRcIl1cbiAgICAgICAgICB0aGlzLmVtYWlsID0gcmVzW1wiZW1haWxcIl1cbiAgICAgICAgICB0aGlzLmVtYWlsVmVyaWZpZWQgPSByZXNbXCJlbWFpbFZlcmlmaWVkXCJdXG4gICAgICAgICAgdGhpcy5sYXN0TG9naW4gPSBuZXcgRGF0ZShyZXNbXCJtZXRhZGF0YVwiXVtcImxhc3RTaWduSW5UaW1lXCJdKVxuICAgICAgICB9XG4gICAgICB9KSxcbiAgICAgIHN3aXRjaE1hcCh1c2VyID0+IHtcbiAgICAgICAgaWYgKHVzZXIpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5hZnMuZG9jPFVzZXI+KGB1c2Vycy8ke3VzZXIudWlkfWApLnZhbHVlQ2hhbmdlcygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG9mKG51bGwpXG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgdGFwKHVzZXIgPT4ge1xuICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgIHRoaXMuZGlzcGxheU5hbWUgPSB1c2VyW1wiZGlzcGxheU5hbWVcIl1cbiAgICAgICAgICB0aGlzLnByb2ZpbGVVUkwgPSB1c2VyW1wicHJvZmlsZVVSTFwiXVxuICAgICAgICAgIHRoaXMucm9sZSA9IHVzZXJbXCJyb2xlc1wiXVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBsb2dpbih1c2VybmFtZSwgcGFzc3dvcmQpIHtcbiAgICBsZXQgYWRtaW5VUkwgPSB0aGlzLmNvbmZpZy5hZG1pblVSTCB8fCAnYWRtaW4nXG4gICAgdGhpcy5hZkF1dGguYXV0aC5zaWduSW5XaXRoRW1haWxBbmRQYXNzd29yZCh1c2VybmFtZSwgcGFzc3dvcmQpXG4gICAgLnRoZW4ocmVzID0+IHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtgJHthZG1pblVSTH0vZGFzaGJvYXJkYF0pXG4gICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgIHRoaXMubWVzc2FnZS5lcnJvcihlcnIpXG4gICAgfSlcbiAgfVxuXG4gIHB1YmxpYyBzaWdudXAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gICAgbGV0IGFkbWluVVJMID0gdGhpcy5jb25maWcuYWRtaW5VUkwgfHwgJ2FkbWluJ1xuICAgIHRoaXMuYWZBdXRoLmF1dGguY3JlYXRlVXNlcldpdGhFbWFpbEFuZFBhc3N3b3JkKHVzZXJuYW1lLCBwYXNzd29yZCkudGhlbihyZXMgPT4ge1xuICAgICAgbGV0IGRhdGEgPSB7XG4gICAgICAgIHVpZDogcmVzWyd1c2VyJ11bJ3VpZCddLFxuICAgICAgICBlbWFpbDogcmVzWyd1c2VyJ11bJ2VtYWlsJ10sXG4gICAgICAgIGRpc3BsYXlOYW1lOiByZXNbJ3VzZXInXVsnZW1haWwnXSxcbiAgICAgICAgZW1haWxWZXJpZmllZDogZmFsc2UsXG4gICAgICAgIGNyZWF0ZWRUaW1lOiBmaXJlYmFzZS5maXJlc3RvcmUuRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKSxcbiAgICAgICAgdXBkYXRlZFRpbWU6IGZpcmViYXNlLmZpcmVzdG9yZS5GaWVsZFZhbHVlLnNlcnZlclRpbWVzdGFtcCgpLFxuICAgICAgICBsYXN0TG9naW5UaW1lOiBmaXJlYmFzZS5maXJlc3RvcmUuRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKSxcbiAgICAgICAgcm9sZXM6IFtcIkNvbnRyaWJ1dG9yXCJdXG4gICAgICB9XG4gICAgICBpZiAocmVzWyd1c2VyJ11bJ3VpZCddKSB7XG4gICAgICAgIHRoaXMuYWZzLmNvbGxlY3Rpb24oXCJ1c2Vyc1wiKS5kb2MocmVzWyd1c2VyJ11bJ3VpZCddKS5zZXQoZGF0YSlcbiAgICAgICAgLnRoZW4ocmVzID0+IHtcbiAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbYCR7YWRtaW5VUkx9L2Rhc2hib2FyZGBdKVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2UuZXJyb3IoZXJyKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBzaWduT3V0KCkge1xuICAgIHJldHVybiB0aGlzLmFmQXV0aC5hdXRoLnNpZ25PdXQoKVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVVc2VyRGF0YSh1c2VyKSB7XG4gICAgY29uc3QgdXNlclJlZjogQW5ndWxhckZpcmVzdG9yZURvY3VtZW50PGFueT4gPSB0aGlzLmFmcy5kb2MoYHVzZXJzLyR7dXNlci51aWR9YCk7XG4gICAgY29uc3QgZGF0YTogVXNlciA9IHtcbiAgICAgIHVpZDogdXNlci51aWQsXG4gICAgICBlbWFpbDogdXNlci5lbWFpbCxcbiAgICAgIHJvbGVzOiBbXCJDb250cmlidXRvclwiXSBcbiAgICB9XG4gICAgcmV0dXJuIHVzZXJSZWYuc2V0KGRhdGEsIHsgbWVyZ2U6IHRydWUgfSlcbiAgfVxuXG5cbiAgLy8vLy8gUm9sZS1iYXNlZCBBdXRob3JpemF0aW9uIC8vLy8vL1xuICBjYW5SZWFkKHVzZXI6IFVzZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBhbGxvd2VkID0gWydBZG1pbmlzdHJhdG9yJywgJ0VkaXRvcicsICdBdXRob3InLCAnQ29udHJpYnV0b3InXVxuICAgIHJldHVybiB0aGlzLmNoZWNrQXV0aG9yaXphdGlvbih1c2VyLCBhbGxvd2VkKVxuICB9XG5cbiAgY2FuRWRpdCh1c2VyOiBVc2VyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWxsb3dlZCA9IFsnQWRtaW5pc3RyYXRvcicsICdFZGl0b3InXVxuICAgIHJldHVybiB0aGlzLmNoZWNrQXV0aG9yaXphdGlvbih1c2VyLCBhbGxvd2VkKVxuICB9XG5cbiAgY2FuRGVsZXRlKHVzZXI6IFVzZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBhbGxvd2VkID0gWydBZG1pbmlzdHJhdG9yJ11cbiAgICByZXR1cm4gdGhpcy5jaGVja0F1dGhvcml6YXRpb24odXNlciwgYWxsb3dlZClcbiAgfVxuXG4gIC8vIGRldGVybWluZXMgaWYgdXNlciBoYXMgbWF0Y2hpbmcgcm9sZVxuICBwcml2YXRlIGNoZWNrQXV0aG9yaXphdGlvbih1c2VyOiBVc2VyLCBhbGxvd2VkUm9sZXM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgaWYgKCF1c2VyKSByZXR1cm4gZmFsc2VcbiAgICBmb3IgKGNvbnN0IHJvbGUgb2YgYWxsb3dlZFJvbGVzKSB7XG4gICAgICBpZiAodXNlci5yb2xlc1tyb2xlXSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGxvZyAoZGVzY3JpcHRpb246IHN0cmluZykge1xuICAgIGlmICh0aGlzLnVpZCkge1xuICAgICAgdGhpcy5hZnMuY29sbGVjdGlvbjxMb2c+KCdsb2cnKS5hZGQoe1xuICAgICAgICBcImRlc2NyaXB0aW9uXCI6IGRlc2NyaXB0aW9uLFxuICAgICAgICBcInVpZFwiOiB0aGlzLnVpZCxcbiAgICAgICAgXCJjcmVhdGVkVGltZVwiOiBmaXJlYmFzZS5maXJlc3RvcmUuRmllbGRWYWx1ZS5zZXJ2ZXJUaW1lc3RhbXAoKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==