Forráskód Böngészése

Implementación de restricciones según el perfil del usuario pt.2

Jose Brito 2 éve
szülő
commit
631019236a

+ 6 - 1
sistema-mantenimiento-front/src/app/components/template/menu-item/submodule-functions/submodule-functions.component.html

@@ -1,8 +1,13 @@
 <h1 mat-dialog-title>Selecciona una función</h1>
 <div mat-dialog-content>
+  <div class="w-100" *ngIf="functions.length > 0">
     <button mat-button style="width: 100%;" *ngFor="let func of functions" [mat-dialog-close]="func">
-        <mat-icon>{{ func.ICONOFUNCION }}</mat-icon> {{ func.NOMBREFUNCION }}
+      <mat-icon>{{ func.ICONOFUNCION }}</mat-icon> {{ func.NOMBREFUNCION }}
     </button>
+  </div>
+  <div class="animated fadeIn" *ngIf="functions.length == 0">
+    <h3 class="ml-20"><b>Su perfil no cuenta con los permisos necesarios para utilizar las funciones de este submódulo.</b></h3>
+  </div>
 </div>
 <mat-dialog-actions align="end">
   <button mat-button mat-dialog-close cdkFocusInitial>Cancel</button>

+ 4 - 1
sistema-mantenimiento-front/src/app/components/users-profiles/profiles-admin/new-profile/new-profile.component.html

@@ -117,7 +117,10 @@
             </div>
         </mat-card-content>
         <mat-card-actions align="end" *ngIf="!isLoading && !hasError">
-            <button mat-button (click)="save()" *ngIf="action != 'detalles'">Guardar perfil</button>
+            <div matTooltip="Su perfil no cuenta con los permisos suficientes para ejecutar esta acción." 
+            [matTooltipDisabled]="realTimeUpdateEnabled" *ngIf="action != 'detalles'">
+                <button mat-button (click)="save()" [disabled]="!realTimeUpdateEnabled">Guardar perfil</button>
+            </div>
         </mat-card-actions>
     </mat-card>
 </div>

+ 80 - 23
sistema-mantenimiento-front/src/app/components/users-profiles/profiles-admin/new-profile/new-profile.component.ts

@@ -4,7 +4,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
 import { ErrorStateMatcher } from '@angular/material/core';
 import { UsersProfilesService } from './../../../../services/users-profiles.service';
 import { MenusInterface } from './../../../../interfaces/menus.interface';
-import { PermissionsResponseInterface, PermissionsInterface } from './../../../../interfaces/permissions.interface';
+import { PermissionsResponseInterface, PermissionsInterface, Permissions } from './../../../../interfaces/permissions.interface';
 import { EncService } from './../../../../services/enc/enc.service';
 import { SubmodulesResponse } from './../../../../interfaces/submodules.interface';
 import { lastValueFrom } from 'rxjs';
@@ -14,6 +14,7 @@ import { FormGroup, FormControl, Validators, AbstractControl, FormGroupDirective
 import { Router, ActivatedRoute } from '@angular/router';
 import { Location } from '@angular/common';
 import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
+import { UserConsultResponse } from 'src/app/interfaces/user.interface';
 
 @Component({
   selector: 'app-new-profile',
@@ -33,8 +34,10 @@ export class NewProfileComponent implements OnInit {
   errorMatcher = new MatchErrors();
   profileName = new FormControl('', [Validators.required, Validators.maxLength(50), Validators.minLength(8)])
 
+  realTimeUpdateEnabled: boolean;
+
   constructor(
-    private router: Router,
+    private _router: Router,
     private _usersProfilesService: UsersProfilesService,
     private _el: ElementRef,
     private _snackBar: MatSnackBar,
@@ -47,21 +50,47 @@ export class NewProfileComponent implements OnInit {
     this.action = "";
     
     this.permissions = [];
+    this.realTimeUpdateEnabled = true;
   }
 
   ngOnInit(): void {
-    let current = this.router.url;
+    let current = this._router.url;
     let arrRoute = current.split("/");
     this.action = arrRoute[arrRoute.length - 1];
     this.action = this.action.split("?")[0];
     
     this.tituloCard = `${this.capitalize(arrRoute[arrRoute.length - 1].split("?")[0])} perfil`;
+    this.init();
+  }
+
+  capitalize(str: string){
+    let arr = str.split("");
+    arr[0] = arr[0].toUpperCase();
+    let capitalized = "";
+    arr.forEach(l => capitalized += l);
+    return capitalized;
+  }
+
+  back(){
+    this._location.back();
+  }
+
+  async init(){
+    let permissionsEnc = localStorage.getItem('permisos');
+    let permissionsDec = await this._encService.desencriptar(permissionsEnc!);
+    let permissionsArr: Permissions = JSON.parse(permissionsDec);
+
+    let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+    let subPerm = modPerm.children.filter(item => item.id == 'S002V01S02GEPE')[0];
+
+    this.realTimeUpdateEnabled = subPerm.children.filter(item => item.id == 'S002V01F02APTR')[0].access > 0;
+    
     this._activatedRoute.queryParams.subscribe(params => {
       if(this.action != 'crear'){
         let info = params['info'];
         
         if(info == undefined){
-          this.openSnackbar('No se encontró información del perfil en la ruta.');
+          this.openSnackBar('No se encontró información del perfil en la ruta.');
           this.back();
         }else{
           this._encService.desencriptar(info).then((infoDec) => {
@@ -79,18 +108,41 @@ export class NewProfileComponent implements OnInit {
         this.getPermissions()
       }
     });
-  }
+    
+    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
+      let shortID = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('idusuario')!));
+      let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(shortID.response.encrypted, shortID.response.encrypted, 1));
+      let currentProfile = await this._encService.desencriptar(localStorage.getItem('perfil')!);
 
-  capitalize(str: string){
-    let arr = str.split("");
-    arr[0] = arr[0].toUpperCase();
-    let capitalized = "";
-    arr.forEach(l => capitalized += l);
-    return capitalized;
-  }
+      if(parseInt(currentProfile) != usrInfo.response.PERFIL){
+        this._router.navigate(['/sam/home']);
+      }
 
-  back(){
-    this._location.back();
+      let profileUpdated = await this._encService.desencriptar(`${profUpdEnc}`);
+      if(profileUpdated == currentProfile){
+        try{
+          let shortProf = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('perfil')!));
+          let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile(
+            shortProf.response.encrypted,
+            shortID.response.encrypted,
+            1
+          ));
+
+          let modPerm = profInfo.response.PERMISOS.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+          let subPerm = modPerm.children.filter(item => item.id == 'S002V01S02GEPE')[0];
+      
+          this.realTimeUpdateEnabled = subPerm.children.filter(item => item.id == 'S002V01F02APTR')[0].access > 0;
+        }catch(error: any){
+          if(error.error == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else if(error.error.msg == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else{
+            this.openSnackBar(error.error.msg);
+          }
+        }
+      }
+    });
   }
 
   async getPermissions(){
@@ -100,10 +152,14 @@ export class NewProfileComponent implements OnInit {
       
       let permissions: PermissionsResponseInterface = await lastValueFrom(this._usersProfilesService.getInitialPermissions(idShort.response.encrypted, 1));
       
-      this.permissions = permissions.response.permissions;
-      this.isLoading = false;
       this.hasError = permissions.error;
       this.errorStr = permissions.msg;
+
+      if(!this.hasError){
+        this.permissions = permissions.response.permissions;
+      }
+
+      this.isLoading = false;
     }catch(error: any){
       this.hasError = true;
       this.isLoading = false;
@@ -131,7 +187,6 @@ export class NewProfileComponent implements OnInit {
         1
       ));
 
-      this.isLoading = false;
       this.hasError = profile.error;
       this.errorStr = profile.msg;
 
@@ -141,6 +196,8 @@ export class NewProfileComponent implements OnInit {
         this.profileName.setValue(profile.response.NOMBREPERFIL);
         this.profileID = profile.response.IDPERFIL;
       }
+
+      this.isLoading = false;
     }catch(error: any){
       this.isLoading = false;
       this.hasError = true;
@@ -346,7 +403,7 @@ export class NewProfileComponent implements OnInit {
       });
   
       let newFunctionAccess = 0;
-      if(screensEnabled == module.children.length){
+      if(screensEnabled == func.children.length){
         newFunctionAccess = 2;
       }else if(screensEnabled > 0 || screensPartialEnabled > 0){
         newFunctionAccess = 1;
@@ -411,7 +468,7 @@ export class NewProfileComponent implements OnInit {
     }
   }
 
-  openSnackbar(msg: string){
+  openSnackBar(msg: string){
     this._snackBar.open(msg, 'Cerrar', {
       duration: 5000
     });
@@ -419,7 +476,7 @@ export class NewProfileComponent implements OnInit {
 
   async save(){
     if(!this.profileName.valid){
-      this.openSnackbar('Ingresa los campos requeridos para continuar.');
+      this.openSnackBar('Ingresa los campos requeridos para continuar.');
       this.profileName.markAllAsTouched();
     }else{
       let profileName = this.profileName.value;
@@ -437,7 +494,7 @@ export class NewProfileComponent implements OnInit {
             id_user: localStorage.getItem('idusuario'),
             linea: 1
           }));
-          this.openSnackbar('Perfil insertado correctamente.');
+          this.openSnackBar('Perfil insertado correctamente.');
         }else if(this.action == 'editar'){
           let perfEnc = await this._encService.encriptar(`${this.profileID!}`);
           
@@ -449,7 +506,7 @@ export class NewProfileComponent implements OnInit {
             linea: 1
           }));
 
-          this.openSnackbar('Perfil actualizado correctamente.');
+          this.openSnackBar('Perfil actualizado correctamente.');
           this._socketService.profileUpdated(perfEnc);
         }
         this._location.back();
@@ -463,7 +520,7 @@ export class NewProfileComponent implements OnInit {
           msg = error.error.msg;
         }
 
-        this.openSnackbar(msg);
+        this.openSnackBar(msg);
       }
     }
   }

+ 13 - 6
sistema-mantenimiento-front/src/app/components/users-profiles/profiles-admin/profiles-admin.component.html

@@ -21,11 +21,12 @@
               (click)="applyFilter('', 'EST')" matSuffix>close</mat-icon>
           </mat-form-field>
           <div class="override-buttons">
-            <button mat-raised-button color="primary" class="override-no-shadow mr-10 animated fadeIn" (click)="openPermissions(0, '', 'crear')" *ngIf="!btnSmall">
+            <button mat-raised-button color="primary" class="override-no-shadow mr-10 animated fadeIn" (click)="openPermissions(0, '', 'crear')" *ngIf="!btnSmall" 
+            [disabled]="!regEditProfileEnabled">
               <mat-icon>add</mat-icon> Crear nuevo perfil
             </button>
             <button mat-mini-fab color="primary" class="override-no-shadow mr-10 animated fadeIn" matTooltip="Crear nuevo perfil" (click)="openPermissions(0, '', 'crear')" 
-            *ngIf="btnSmall">
+            *ngIf="btnSmall" [disabled]="!regEditProfileEnabled">
               <mat-icon>add</mat-icon>
             </button>
             <button mat-mini-fab color="info" class="mr-10 override-no-shadow" matTooltip="Actualizar Datos" (click)="getData()">
@@ -42,8 +43,13 @@
         </div>
       </div>
 
+      <div class="animated fadeIn" *ngIf="!profilesHistoryEnabled">
+        <h3 class="ml-20"><b>Su perfil no cuenta con los permisos necesarios para visualizar la información de esta sección.</b></h3>
+      </div>
+
       <div class="override-table">
-        <table mat-table [dataSource]="dataSource!" matSort class="animated fadeIn" [style.display]="isLoading ? 'none' : 'revert'">
+        <table mat-table [dataSource]="dataSource!" matSort class="animated fadeIn" 
+        [style.display]="!isLoading && profilesHistoryEnabled ? 'revert' : 'none'">
           <ng-container matColumnDef="ID">
             <th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
             <td mat-cell *matCellDef="let row">{{ row.ID }}</td>
@@ -68,11 +74,12 @@
             <th mat-header-cell *matHeaderCellDef>Acciones</th>
             <td mat-cell *matCellDef="let row">
               <button mat-mini-fab color="primary" #tooltip="matTooltip" matTooltip="Editar permisos" class="no-shadow"
-              (click)="openPermissions(row.ID, row.NOMBRE, 'editar')" [disabled]="row.ESTADO != 'Activo'">
+              (click)="openPermissions(row.ID, row.NOMBRE, 'editar')" [disabled]="row.ESTADO != 'Activo'" [disabled]="!regEditProfileEnabled">
                 <mat-icon>edit</mat-icon>
               </button>
-              <button mat-mini-fab #tooltip="matTooltip" matTooltip="Ver permisos" class="no-shadow ml-4" [disabled]="row.ESTADO != 'Activo'"
-              [ngClass]="{ green_primary_background: row.ESTADO === 'Activo', white_font: row.ESTADO === 'Activo' }"(click)="openPermissions(row.ID, row.NOMBRE, 'detalles')">
+              <button mat-mini-fab #tooltip="matTooltip" matTooltip="Ver permisos" class="no-shadow ml-4" [disabled]="row.ESTADO != 'Activo' || !viewPermissionsEnabled"
+              [ngClass]="{ green_primary_background: row.ESTADO === 'Activo' && viewPermissionsEnabled, white_font: row.ESTADO === 'Activo' && viewPermissionsEnabled }" 
+              (click)="openPermissions(row.ID, row.NOMBRE, 'detalles')">
                 <mat-icon>visibility</mat-icon>
               </button>
               <button mat-mini-fab #tooltip="matTooltip" matTooltip="Eliminar perfil" class="no-shadow ml-4" [disabled]="row.ESTADO != 'Activo'"

+ 86 - 24
sistema-mantenimiento-front/src/app/components/users-profiles/profiles-admin/profiles-admin.component.ts

@@ -11,6 +11,10 @@ import { Component, OnInit, ViewChild } from '@angular/core';
 import { MatTableDataSource } from '@angular/material/table';
 import { MatPaginator } from '@angular/material/paginator';
 import { MatSort } from '@angular/material/sort';
+import { Permissions } from 'src/app/interfaces/permissions.interface';
+import { SocketService } from 'src/app/services/socket.service';
+import { UserConsultResponse } from 'src/app/interfaces/user.interface';
+import { ProfileInterface } from 'src/app/interfaces/profile.interface';
 
 interface TableInfo{
   ID: number,
@@ -40,13 +44,18 @@ export class ProfilesAdminComponent implements OnInit {
   @ViewChild(MatPaginator) paginator?: MatPaginator;
   @ViewChild(MatSort) sort?: MatSort;
 
+  profilesHistoryEnabled: boolean;
+  regEditProfileEnabled: boolean;
+  viewPermissionsEnabled: boolean;
+
   constructor(
-    private usersProfilesService: UsersProfilesService, 
-    private router: Router, 
-    private encService: EncService,
-    private dialg: MatDialog,
+    private _usersProfilesService: UsersProfilesService, 
+    private _router: Router, 
+    private _encService: EncService,
+    private _dialg: MatDialog,
     private _snackBar: MatSnackBar,
-    private _functionsService: FunctionsService
+    private _functionsService: FunctionsService,
+    private _socketService: SocketService,
   ) { 
     this.isLoading = true;
     this.hasError = false;
@@ -55,10 +64,50 @@ export class ProfilesAdminComponent implements OnInit {
     this.searching = false;
     this.btnSmall = window.innerWidth <= 1405;
     this.txtBuscador = '';
+    this.profilesHistoryEnabled = true;
+    this.regEditProfileEnabled = true;
+    this.viewPermissionsEnabled = true;
   }
 
   ngOnInit(): void {
     this.getData();
+    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
+      let shortID = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('idusuario')!));
+      let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(shortID.response.encrypted, shortID.response.encrypted, 1));
+      let currentProfile = await this._encService.desencriptar(localStorage.getItem('perfil')!);
+
+      if(parseInt(currentProfile) != usrInfo.response.PERFIL){
+        this._router.navigate(['/sam/home']);
+      }
+
+      let profileUpdated = await this._encService.desencriptar(`${profUpdEnc}`);
+      if(profileUpdated == currentProfile){
+        try{
+          let shortProf = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('perfil')!));
+          let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile(
+            shortProf.response.encrypted,
+            shortID.response.encrypted,
+            1
+          ));
+
+          let modPerm = profInfo.response.PERMISOS.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+          let subPerm = modPerm.children.filter(item => item.id == 'S002V01S02GEPE')[0];
+          let funPerm = subPerm.children.filter(item => item.id == 'S002V01F01ADPE')[0];
+
+          this.profilesHistoryEnabled = funPerm.children.filter(item => item.id == 'S002V01P01COPE')[0].access > 0;
+          this.regEditProfileEnabled = funPerm.children.filter(item => item.id == 'S002V01P02REPE')[0].access > 0;
+          this.viewPermissionsEnabled = funPerm.children.filter(item => item.id == 'S002V01P03VEPE')[0].access > 0;
+        }catch(error: any){
+          if(error.error == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else if(error.error.msg == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else{
+            this.openSnackBar(error.error.msg);
+          }
+        }
+      }
+    });
   }
 
   async getData(){
@@ -69,16 +118,14 @@ export class ProfilesAdminComponent implements OnInit {
     
     try{
       let idEnc = localStorage.getItem('idusuario');
-      let idShort = await lastValueFrom(this.encService.shortEncrypt(idEnc!));
+      let idShort = await lastValueFrom(this._encService.shortEncrypt(idEnc!));
       
-      let data: ProfilesResponse = await lastValueFrom(this.usersProfilesService.getProfiles(idShort.response.encrypted, 1));
+      let data: ProfilesResponse = await lastValueFrom(this._usersProfilesService.getProfiles(idShort.response.encrypted, 1));
       
-      if(data.error){
-        this.isLoading = false;
-        this.hasError = true;
-        this.errorStr = data.msg;
-      }else{
-        this.isLoading = false;
+      this.hasError = data.error;
+      this.errorStr = data.msg;
+
+      if(!this.hasError){
         data.response.forEach((item: ProfileResponse) => {
           let lastDate = item.FECHAMODIFICACION == null || item.FECHAMODIFICACION == undefined ? item.FECHACREACION : item.FECHAMODIFICACION;
           let formattedDate = this._functionsService.orderDate(lastDate);
@@ -92,10 +139,25 @@ export class ProfilesAdminComponent implements OnInit {
           
           this.profiles.push(profile)
         });
+
         this.dataSource = new MatTableDataSource(this.profiles);
         this.dataSource.paginator = this.paginator!;
         this.dataSource.sort = this.sort!;
+
+        let permissionsEnc = localStorage.getItem('permisos');
+        let permissionsDec = await this._encService.desencriptar(permissionsEnc!);
+        let permissionsArr: Permissions = JSON.parse(permissionsDec);
+
+        let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+        let subPerm = modPerm.children.filter(item => item.id == 'S002V01S02GEPE')[0];
+        let funPerm = subPerm.children.filter(item => item.id == 'S002V01F01ADPE')[0];
+
+        this.profilesHistoryEnabled = funPerm.children.filter(item => item.id == 'S002V01P01COPE')[0].access > 0;
+        this.regEditProfileEnabled = funPerm.children.filter(item => item.id == 'S002V01P02REPE')[0].access > 0;
+        this.viewPermissionsEnabled = funPerm.children.filter(item => item.id == 'S002V01P03VEPE')[0].access > 0;
       }
+
+      this.isLoading = false;
     }catch(error: any){
       this.isLoading = false;
       this.hasError = true;
@@ -112,8 +174,8 @@ export class ProfilesAdminComponent implements OnInit {
 
     let dataStr = JSON.stringify(dataobj);
     
-    this.encService.encriptar(dataStr).then((dataEnc) =>{
-      this.router.navigate([`sam/USPE/GEPE/ADPE/${action}`], action != 'crear' ? {
+    this._encService.encriptar(dataStr).then((dataEnc) =>{
+      this._router.navigate([`sam/USPE/GEPE/ADPE/${action}`], action != 'crear' ? {
         queryParams: {
           info: dataEnc
         }
@@ -137,7 +199,7 @@ export class ProfilesAdminComponent implements OnInit {
   }
 
   openDialog(name: string, id: number){
-    let dialog = this.dialg.open(AlertComponent, {
+    let dialog = this._dialg.open(AlertComponent, {
       width: '300px',
       data: {
         icon: "warning",
@@ -158,23 +220,23 @@ export class ProfilesAdminComponent implements OnInit {
     });
   }
 
-  openSnackbar(msg: string){
-    this._snackBar.open(msg, 'Cerrar', {
-      duration: 5000
-    })
+  openSnackBar(message: string){
+    this._snackBar.open(message, "Cerrar", {
+      duration: 1500
+    });
   }
 
   async deleteProfile(id: number){
     try{
-      let perfEnc = await this.encService.encriptar(`${id}`);
+      let perfEnc = await this._encService.encriptar(`${id}`);
       
-      await lastValueFrom(this.usersProfilesService.deleteProfile({
+      await lastValueFrom(this._usersProfilesService.deleteProfile({
         id: perfEnc,
         id_user: localStorage.getItem('idusuario'),
         linea: 1
       }));
 
-      this.openSnackbar('El perfil se eliminó correctamente');
+      this.openSnackBar('El perfil se eliminó correctamente');
     }catch(error: any){
       let msg = "";
 
@@ -186,7 +248,7 @@ export class ProfilesAdminComponent implements OnInit {
         msg = error.error.msg;
       }
 
-      this.openSnackbar(msg);
+      this.openSnackBar(msg);
     }
     this.getData();
   }

+ 17 - 10
sistema-mantenimiento-front/src/app/components/users-profiles/users-admin/users-admin.component.html

@@ -21,11 +21,12 @@
               (click)="applyFilter('', 'EST')" matSuffix>close</mat-icon>
           </mat-form-field>
           <div class="override-buttons">
-            <button mat-raised-button color="primary" class="override-no-shadow mr-10 animated fadeIn" (click)="openUser('insert', '')" *ngIf="!btnSmall">
+            <button mat-raised-button color="primary" class="override-no-shadow mr-10 animated fadeIn" (click)="openUser('insert', '')" *ngIf="!btnSmall" 
+            [disabled]="!regEditUserEnabled">
               <mat-icon>add</mat-icon> Crear nueva cuenta
             </button>
             <button mat-mini-fab color="primary" class="override-no-shadow mr-10 animated fadeIn" matTooltip="Crear nueva cuenta" (click)="openUser('insert', '')"
-            *ngIf="btnSmall">
+            *ngIf="btnSmall" [disabled]="!regEditUserEnabled">
               <mat-icon>add</mat-icon>
             </button>
             <button mat-mini-fab color="info" class="mr-10 override-no-shadow" matTooltip="Actualizar Datos" (click)="getData()">
@@ -42,8 +43,13 @@
         </div>
       </div>
 
+      <div class="animated fadeIn" *ngIf="!usersConsultEnabled">
+        <h3 class="ml-20"><b>Su perfil no cuenta con los permisos necesarios para visualizar la información de esta sección.</b></h3>
+      </div>
+
       <div class="override-table">
-        <table mat-table [dataSource]="dataSource!" matSort class="animated fadeIn" [style.display]="isLoading ? 'none' : 'revert'">
+        <table mat-table [dataSource]="dataSource!" matSort class="animated fadeIn" 
+        [style.display]="!isLoading && usersConsultEnabled ? 'revert' : 'none'">
           <ng-container matColumnDef="ID">
             <th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
             <td mat-cell *matCellDef="let row">{{ row.IDUSUARIO }}</td>
@@ -83,17 +89,18 @@
             <th mat-header-cell *matHeaderCellDef>Acciones</th>
             <td mat-cell *matCellDef="let row">
               <button mat-mini-fab color="primary" #tooltip="matTooltip" matTooltip="Editar registro" (click)="openUser('edit', row.IDUSUARIO)"
-              class="no-shadow animated fadeIn" *ngIf="!btnSmall">
+              class="no-shadow animated fadeIn" *ngIf="!btnSmall" [disabled]="!regEditUserEnabled">
                 <mat-icon>edit</mat-icon>
               </button>
-              <button mat-mini-fab #tooltip="matTooltip" matTooltip="{{ row.ESTATUS == 'Activo' ? 'Bloquear acceso' : 'Permitir acceso' }}"
-              (click)="blockUser(row.IDUSUARIO)" [disabled]="row.ESTATUS == 'Eliminado'" class="no-shadow ml-4 animated fadeIn"
-              [ngClass]="{ amber_primary_background: row.ESTATUS != 'Eliminado', white_font: row.ESTATUS != 'Eliminado' }" *ngIf="!btnSmall">
+              <button mat-mini-fab #tooltip="matTooltip" matTooltip="{{ row.ESTATUS == 'Activo' ? 'Bloquear acceso' : 'Permitir acceso' }}" *ngIf="!btnSmall" 
+              (click)="blockUser(row.IDUSUARIO)" [disabled]="row.ESTATUS == 'Eliminado' || !blockUnblockEnabled" class="no-shadow ml-4 animated fadeIn"
+              [ngClass]="{ amber_primary_background: row.ESTATUS != 'Eliminado' && blockUnblockEnabled, white_font: row.ESTATUS != 'Eliminado' && blockUnblockEnabled }">
                 <mat-icon *ngIf="row.ESTATUS == 'Activo' || row.ESTATUS == 'Eliminado'">block</mat-icon>
                 <mat-icon *ngIf="row.ESTATUS == 'Inactivo'">check_circle</mat-icon>
               </button>
-              <button mat-mini-fab #tooltip="matTooltip" matTooltip="Reasignar contraseña" class="no-shadow ml-4 animated fadeIn" [disabled]="row.ESTATUS == 'Eliminado'"
-              [ngClass]="{ blue_dark_background: row.ESTATUS != 'Eliminado', white_font: row.ESTATUS != 'Eliminado' }" (click)="openDialog(row.IDUSUARIO)" *ngIf="!btnSmall">
+              <button mat-mini-fab #tooltip="matTooltip" matTooltip="Reasignar contraseña" class="no-shadow ml-4 animated fadeIn" 
+              [disabled]="row.ESTATUS == 'Eliminado' || !changePasswordEnabled" (click)="openDialog(row.IDUSUARIO)" *ngIf="!btnSmall"
+              [ngClass]="{ blue_dark_background: row.ESTATUS != 'Eliminado' && changePasswordEnabled, white_font: row.ESTATUS != 'Eliminado' && changePasswordEnabled }" >
                 <mat-icon>lock</mat-icon>
               </button>
               <button mat-mini-fab #tooltip="matTooltip" matTooltip="Eliminar usuario" class="no-shadow ml-4 animated fadeIn" [disabled]="row.ESTATUS == 'Eliminado'"
@@ -104,7 +111,7 @@
                 <mat-icon>settings</mat-icon>
               </button>
               <mat-menu #menu="matMenu">
-                <button mat-menu-item (click)="openUser('edit', row.IDUSUARIO)">
+                <button mat-menu-item (click)="openUser('edit', row.IDUSUARIO)" [disabled]="!regEditUserEnabled">
                   <mat-icon>edit</mat-icon>
                   <span>Editar registro</span>
                 </button>

+ 82 - 18
sistema-mantenimiento-front/src/app/components/users-profiles/users-admin/users-admin.component.ts

@@ -1,3 +1,4 @@
+import { Permissions } from 'src/app/interfaces/permissions.interface';
 import { EncService } from './../../../services/enc/enc.service';
 import { MatPaginator } from '@angular/material/paginator';
 import { DeleteAlertComponent } from './delete-alert/delete-alert.component';
@@ -5,13 +6,16 @@ import { NewPasswordComponent } from './new-password/new-password.component';
 import { MatSnackBar } from '@angular/material/snack-bar';
 import { UsersResponse, UserResponse } from './../../../interfaces/users.interface';
 import { UsersProfilesService } from './../../../services/users-profiles.service';
-import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
 import { MatDialog } from '@angular/material/dialog';
 import { lastValueFrom } from 'rxjs';
 import { MatTableDataSource } from '@angular/material/table';
 import { MatSort } from '@angular/material/sort';
 import { Location } from '@angular/common';
+import { SocketService } from 'src/app/services/socket.service';
+import { UserConsultResponse } from 'src/app/interfaces/user.interface';
+import { ProfileInterface } from 'src/app/interfaces/profile.interface';
 
 @Component({
   selector: 'app-users-admin',
@@ -39,14 +43,18 @@ export class UsersAdminComponent implements OnInit {
   @ViewChild(MatPaginator) paginator?: MatPaginator;
   @ViewChild(MatSort) sort?: MatSort;
 
+  usersConsultEnabled: boolean;
+  regEditUserEnabled: boolean;
+  blockUnblockEnabled: boolean;
+  changePasswordEnabled: boolean;
+
   constructor(
-    private usersProfilesService: UsersProfilesService, 
+    private _usersProfilesService: UsersProfilesService, 
     private _snackBar: MatSnackBar, 
-    private router: Router,
-    private dialog: MatDialog,
+    private _router: Router,
+    private _dialog: MatDialog,
     private _encService: EncService,
-    private _location: Location,
-    private _activeRoute: ActivatedRoute,
+    private _socketService: SocketService,
   ) { 
     this.users = [];
     this.isLoading = true;
@@ -60,10 +68,53 @@ export class UsersAdminComponent implements OnInit {
 
     this.usersFinded = [];
     this.btnSmall = window.innerWidth <= 1405;
+    this.usersConsultEnabled = true;
+    this.regEditUserEnabled = true;
+    this.blockUnblockEnabled = true;
+    this.changePasswordEnabled = true;
   }
 
   ngOnInit(): void {
     this.getData();
+    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
+      let shortID = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('idusuario')!));
+      let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(shortID.response.encrypted, shortID.response.encrypted, 1));
+      let currentProfile = await this._encService.desencriptar(localStorage.getItem('perfil')!);
+
+      if(parseInt(currentProfile) != usrInfo.response.PERFIL){
+        this._router.navigate(['/sam/home']);
+      }
+
+      let profileUpdated = await this._encService.desencriptar(`${profUpdEnc}`);
+      if(profileUpdated == currentProfile){
+        try{
+          let shortProf = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('perfil')!));
+          let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile(
+            shortProf.response.encrypted,
+            shortID.response.encrypted,
+            1
+          ));
+
+          let modPerm = profInfo.response.PERMISOS.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+          let subPerm = modPerm.children.filter(item => item.id == 'S002V01S01GEUS')[0];
+          let funPerm = subPerm.children.filter(item => item.id == 'S002V01F01ADUS')[0];
+  
+          this.usersConsultEnabled = funPerm.children.filter(item => item.id == 'S002V01P01COUS')[0].access > 0;
+          this.regEditUserEnabled = funPerm.children.filter(item => item.id == 'S002V01P02RAUS')[0].access > 0;
+  
+          this.blockUnblockEnabled = subPerm.children.filter(item => item.id == 'S002V01F02BDAC')[0].access > 0;
+          this.changePasswordEnabled = subPerm.children.filter(item => item.id == 'S002V01F03RECO')[0].access > 0;
+        }catch(error: any){
+          if(error.error == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else if(error.error.msg == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else{
+            this.openSnackBar(error.error.msg);
+          }
+        }
+      }
+    });
   }
 
   async getData(){
@@ -76,14 +127,13 @@ export class UsersAdminComponent implements OnInit {
       let idEnc = localStorage.getItem('idusuario');
       let idShort = await lastValueFrom(this._encService.shortEncrypt(idEnc!));
       
-      let data: UsersResponse = await lastValueFrom(this.usersProfilesService.getUsers(idShort.response.encrypted, 1));
+      let data: UsersResponse = await lastValueFrom(this._usersProfilesService.getUsers(idShort.response.encrypted, 1));
       let idDec = await this._encService.desencriptar(idEnc!);
+
+      this.hasError = data.error;
+      this.errorStr = data.msg;
     
-      if(data.error){
-        this.isLoading = false;
-        this.hasError = true;
-        this.errorStr = data.msg;
-      }else{
+      if(!this.hasError){
         data.response.forEach((item: UserResponse) => {
           let usr: UserResponse = {
             IDUSUARIO: item.IDUSUARIO,
@@ -102,8 +152,22 @@ export class UsersAdminComponent implements OnInit {
         this.dataSource.paginator = this.paginator!;
         this.dataSource.sort = this.sort!;
 
-        this.isLoading = false;
+        let permissionsEnc = localStorage.getItem('permisos');
+        let permissionsDec = await this._encService.desencriptar(permissionsEnc!);
+        let permissionsArr: Permissions = JSON.parse(permissionsDec);
+
+        let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+        let subPerm = modPerm.children.filter(item => item.id == 'S002V01S01GEUS')[0];
+        let funPerm = subPerm.children.filter(item => item.id == 'S002V01F01ADUS')[0];
+
+        this.usersConsultEnabled = funPerm.children.filter(item => item.id == 'S002V01P01COUS')[0].access > 0;
+        this.regEditUserEnabled = funPerm.children.filter(item => item.id == 'S002V01P02RAUS')[0].access > 0;
+  
+        this.blockUnblockEnabled = subPerm.children.filter(item => item.id == 'S002V01F02BDAC')[0].access > 0;
+        this.changePasswordEnabled = subPerm.children.filter(item => item.id == 'S002V01F03RECO')[0].access > 0;
       }
+
+      this.isLoading = false;
     }catch(error:any){
       this.isLoading = false;
       this.hasError = true;
@@ -112,7 +176,7 @@ export class UsersAdminComponent implements OnInit {
   }
 
   openDialog(usr: string){
-    const dialogRef = this.dialog.open(NewPasswordComponent, {
+    const dialogRef = this._dialog.open(NewPasswordComponent, {
       data: {
         id: usr
       }
@@ -153,7 +217,7 @@ export class UsersAdminComponent implements OnInit {
   }
 
   openAlert(usr: string){
-    const dialogRef = this.dialog.open(DeleteAlertComponent, {
+    const dialogRef = this._dialog.open(DeleteAlertComponent, {
       data: {
         id: usr
       }
@@ -166,7 +230,7 @@ export class UsersAdminComponent implements OnInit {
             let idEnc = await this._encService.encriptar(usr);
             let idUser = localStorage.getItem('idusuario');
             
-            await lastValueFrom(this.usersProfilesService.deleteUser({
+            await lastValueFrom(this._usersProfilesService.deleteUser({
               id: idEnc,
               id_user: idUser,
               linea: 1
@@ -197,7 +261,7 @@ export class UsersAdminComponent implements OnInit {
     let newStatus = lastStatus == 'Activo' ? 'Inactivo' : 'Activo';
 
     try{
-      await lastValueFrom(this.usersProfilesService.blockUser({
+      await lastValueFrom(this._usersProfilesService.blockUser({
         id: idUser,
         estatus: newStatus,
         id_user: idEnc,
@@ -225,7 +289,7 @@ export class UsersAdminComponent implements OnInit {
     let paramsStr = JSON.stringify(params);
     let paramsEnc = await this._encService.encriptar(paramsStr);
     
-    this.router.navigate(['sam/USPE/GEUS/ADUS/crear'], {
+    this._router.navigate(['sam/USPE/GEUS/ADUS/crear'], {
       queryParams: {
         info: paramsEnc,
       }

+ 89 - 8
sistema-mantenimiento-front/src/app/components/users-profiles/users-profiles.component.ts

@@ -1,4 +1,5 @@
-import { SubmoduleFunctionsResponse } from './../../interfaces/submodule-functions.interface';
+import { Permissions } from 'src/app/interfaces/permissions.interface';
+import { SubmoduleFunctions, SubmoduleFunctionsResponse } from './../../interfaces/submodule-functions.interface';
 import { MatSnackBar } from '@angular/material/snack-bar';
 import { SubmoduleFunctionsComponent } from './../template/menu-item/submodule-functions/submodule-functions.component';
 import { MatDialog } from '@angular/material/dialog';
@@ -7,7 +8,11 @@ import { Submodules, SubmodulesResponse } from './../../interfaces/submodules.in
 import { EncService } from './../../services/enc/enc.service';
 import { lastValueFrom } from 'rxjs';
 import { ModulesService } from './../../services/modules.service';
-import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
+import { SocketService } from 'src/app/services/socket.service';
+import { UserConsultResponse } from 'src/app/interfaces/user.interface';
+import { UsersProfilesService } from 'src/app/services/users-profiles.service';
+import { ProfileInterface } from 'src/app/interfaces/profile.interface';
 
 @Component({
   selector: 'app-users-profiles',
@@ -19,44 +24,104 @@ export class UsersProfilesComponent implements OnInit {
   hasError: boolean;
   errorStr: string;
   submodules: Submodules[];
+  submodulesAux: Submodules[];
 
   constructor(
     private _modulesService: ModulesService,
     private _encService: EncService,
-    private router: Router,
+    private _router: Router,
     private _dialog: MatDialog,
     private _snackBar: MatSnackBar,
+    private _socketService: SocketService,
+    private _profilesService: UsersProfilesService,
   ) { 
     this.isLoading = true;
     this.hasError = false;
     this.errorStr = "";
     this.submodules = [];
+    this.submodulesAux = [];
   }
 
   ngOnInit(): void {
     this.getSubmodules();
+    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
+      let shortID = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('idusuario')!));
+      let usrInfo: UserConsultResponse = await lastValueFrom(this._profilesService.getUser(shortID.response.encrypted, shortID.response.encrypted, 1));
+      let currentProfile = await this._encService.desencriptar(localStorage.getItem('perfil')!);
+
+      if(parseInt(currentProfile) != usrInfo.response.PERFIL){
+        this._router.navigate(['/sam/home']);
+      }
+
+      let profileUpdated = await this._encService.desencriptar(`${profUpdEnc}`);
+      if(profileUpdated == currentProfile){
+        try{
+          let shortProf = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('perfil')!));
+          let profInfo: ProfileInterface = await lastValueFrom(this._profilesService.getProfile(
+            shortProf.response.encrypted,
+            shortID.response.encrypted,
+            1
+          ));
+
+          let newSubmod: Submodules[] = [];
+          let subPerm = profInfo.response.PERMISOS.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+          this.submodulesAux.forEach(item => {
+            let idSub = item.IDSUBMODULO;
+            let sub = subPerm.children.filter(item2 => item2.id == idSub)[0];
+            if(sub.access > 0){
+              newSubmod.push(item);
+            }
+          });
+          
+          this.submodules = newSubmod;
+        }catch(error: any){
+          if(error.error == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else if(error.error.msg == undefined){
+            this.openSnackBar('Ocurrió un error al actualizar su perfil');
+          }else{
+            this.openSnackBar(error.error.msg);
+          }
+        }
+      }
+    })
   }
 
   async getSubmodules(){
     try{
+      let permissionsEnc = localStorage.getItem('permisos');
+      let permissionsDec = await this._encService.desencriptar(permissionsEnc!);
+      let permissionsArr: Permissions = JSON.parse(permissionsDec);
+      let permFun = permissionsArr.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+
       let moduleEnc = await this._encService.encriptar('S002V01M02USPE');
       let modShort = await lastValueFrom(this._encService.shortEncrypt(moduleEnc));
       
       let idEnc = localStorage.getItem('idusuario');
       let idShort = await lastValueFrom(this._encService.shortEncrypt(idEnc!));
+
       let submodules: SubmodulesResponse = await lastValueFrom(this._modulesService.getSubmodules(
         modShort.response.encrypted,
         idShort.response.encrypted, 
         1
       ));
 
-      this.isLoading = false;
       this.hasError = submodules.error;
       this.errorStr = submodules.msg;
 
       if(!this.hasError){
-        this.submodules = submodules.response;
+        submodules.response.forEach(item => {
+          let idSub = item.IDSUBMODULO;
+          let subm = permFun.children.filter(item2 => idSub == item2.id)[0];
+          if(subm.access > 0){
+            this.submodules.push(item);
+          }
+        });
+
+        this.submodulesAux = submodules.response;
       }
+
+      this.isLoading = false;
     }catch(error: any){
       this.isLoading = false;
       this.hasError = true;
@@ -75,7 +140,7 @@ export class UsersProfilesComponent implements OnInit {
   openSubmodule(idSub: string){
     let submodule = idSub.replace("S002V01S", "");
     submodule = submodule.substring(2, submodule.length);
-    this.router.navigate(["sam/USUPER/", submodule]);
+    this._router.navigate(["sam/USUPER/", submodule]);
   }
 
   goBack(steps: number){
@@ -106,10 +171,26 @@ export class UsersProfilesComponent implements OnInit {
         1
       ));
 
+      let permissionsEnc = localStorage.getItem('permisos');
+      let permissionsDec = await this._encService.desencriptar(permissionsEnc!);
+      let permissionsArr: Permissions = JSON.parse(permissionsDec);
+
+      let newFunct: SubmoduleFunctions[] = [];
+      let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M02USPE')[0];
+      let subPerm = modPerm.children.filter(item => item.id == submodule.IDSUBMODULO)[0];
+
+      submoduleFunctions.response.forEach(item => {
+        let idFunc = item.IDFUNCION;
+        let func = subPerm.children.filter(item2 => item2.id == idFunc)[0];
+        if(func.access > 0){
+          newFunct.push(item);
+        }
+      });
+
       let dialogRef = this._dialog.open(SubmoduleFunctionsComponent, {
         width: '380px',
         data: {
-          FUNCIONES: submoduleFunctions.response,
+          FUNCIONES: newFunct,
         },
       });
       
@@ -121,7 +202,7 @@ export class UsersProfilesComponent implements OnInit {
           let idSub = submodule.IDSUBMODULO.replace("S002V01S", "");
           idSub = idSub.substring(2);
 
-          this.router.navigate([`sam/USPE/${idSub}/${idFunc}`]);
+          this._router.navigate([`sam/USPE/${idSub}/${idFunc}`]);
         }
       });
     }catch(error: any){

+ 2 - 2
sistema-mantenimiento-front/src/app/interfaces/submodule-functions.interface.ts

@@ -6,7 +6,7 @@ export interface SubmoduleFunctionsResponse{
 
 export interface SubmoduleFunctions{
     IDFUNCION: string;
-    NOMBRE: string;
-    ICONO: string;
+    NOMBREFUNCION: string;
+    ICONOFUNCION: string;
     HASSCREENS: boolean;
 }