Browse Source

fix(admin-ui): Do not load pending search index updates if permissions are insufficient (#2460)

Fixes #2456
Jonas Osburg 2 years ago
parent
commit
08ad982c6e

+ 2 - 0
packages/admin-ui/src/lib/core/src/core.module.ts

@@ -30,6 +30,7 @@ import { LocalStorageService } from './providers/local-storage/local-storage.ser
 import { NotificationService } from './providers/notification/notification.service';
 import { registerDefaultFormInputs } from './shared/dynamic-form-inputs/default-form-inputs';
 import { SharedModule } from './shared/shared.module';
+import { Permission } from './public_api';
 
 @NgModule({
     imports: [
@@ -107,6 +108,7 @@ export class CoreModule {
     private initAlerts() {
         this.alertsService.configureAlert({
             id: 'pending-search-index-updates',
+            requiredPermissions: [Permission.ReadCatalog, Permission.ReadProduct],
             check: () =>
                 this.dataService.product
                     .getPendingSearchIndexUpdates()

+ 34 - 5
packages/admin-ui/src/lib/core/src/providers/alerts/alerts.service.ts

@@ -1,7 +1,17 @@
 import { Injectable } from '@angular/core';
 import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
-import { BehaviorSubject, combineLatest, interval, isObservable, Observable, Subject, switchMap } from 'rxjs';
-import { map, mapTo, startWith, take } from 'rxjs/operators';
+import {
+    BehaviorSubject,
+    combineLatest,
+    interval,
+    isObservable,
+    Observable,
+    of,
+    Subject,
+    switchMap,
+} from 'rxjs';
+import { filter, first, map, mapTo, startWith, take } from 'rxjs/operators';
+import { DataService, Permission } from '../../public_api';
 
 export interface AlertConfig<T = any> {
     id: string;
@@ -10,6 +20,7 @@ export interface AlertConfig<T = any> {
     isAlert: (value: T) => boolean;
     action: (data: T) => void;
     label: (data: T) => { text: string; translationVars?: { [key: string]: string | number } };
+    requiredPermissions?: Permission[];
 }
 
 export interface ActiveAlert {
@@ -74,7 +85,7 @@ export class AlertsService {
     private alertsMap = new Map<string, Alert<any>>();
     private configUpdated = new Subject<void>();
 
-    constructor() {
+    constructor(private dataService: DataService) {
         const alerts$ = this.configUpdated.pipe(
             mapTo([...this.alertsMap.values()]),
             startWith([...this.alertsMap.values()]),
@@ -91,8 +102,26 @@ export class AlertsService {
     }
 
     configureAlert<T>(config: AlertConfig<T>) {
-        this.alertsMap.set(config.id, new Alert(config));
-        this.configUpdated.next();
+        this.hasSufficientPermissions(config.requiredPermissions)
+            .pipe(first())
+            .subscribe(hasSufficientPermissions => {
+                if (hasSufficientPermissions) {
+                    this.alertsMap.set(config.id, new Alert(config));
+                    this.configUpdated.next();
+                }
+            });
+    }
+
+    hasSufficientPermissions(permissions?: Permission[]) {
+        if (!permissions || permissions.length === 0) {
+            return of(true);
+        }
+        return this.dataService.client.userStatus().stream$.pipe(
+            filter(({ userStatus }) => userStatus.isLoggedIn),
+            map(({ userStatus }) =>
+                permissions.some(permission => userStatus.permissions.includes(permission)),
+            ),
+        );
     }
 
     refresh(id?: string) {