ngx-sp-auth 4.20.4 → 4.20.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { importProvidersFrom, NgModule, InjectionToken, Inject, Injectable, Component, EventEmitter, Output, Input, TemplateRef, ContentChild, ViewChild } from '@angular/core';
2
+ import { importProvidersFrom, NgModule, InjectionToken, Inject, Injectable, ViewContainerRef, ViewChild, Component, EventEmitter, Output, Input, TemplateRef, ContentChild } from '@angular/core';
3
3
  import * as i1 from '@angular/common/http';
4
4
  import { HTTP_INTERCEPTORS, HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
5
5
  import * as i1$2 from '@azure/msal-angular';
6
6
  import { MsalInterceptor, MsalGuard, MsalModule, MSAL_GUARD_CONFIG } from '@azure/msal-angular';
7
7
  import { LogLevel, PublicClientApplication, InteractionType } from '@azure/msal-browser';
8
+ import { BehaviorSubject, take, tap, firstValueFrom, Subject, Subscription, debounceTime, distinctUntilChanged, filter, switchMap, timer, map as map$1, of, lastValueFrom, from } from 'rxjs';
8
9
  import { take as take$1, tap as tap$1, map, switchMap as switchMap$1 } from 'rxjs/operators';
9
10
  import * as i1$1 from '@angular/router';
10
11
  import { RouterLink, NavigationEnd, RouterOutlet } from '@angular/router';
11
- import { BehaviorSubject, take, tap, Subject, Subscription, debounceTime, distinctUntilChanged, filter, switchMap, timer, map as map$1, firstValueFrom, of, lastValueFrom, from } from 'rxjs';
12
12
  import * as i3 from 'ngx-sp-infra';
13
13
  import { Utils, SearchInputComponent, InfraModule, FormUtils, LibIconsComponent, ContentContainerComponent } from 'ngx-sp-infra';
14
14
  import { openDB, deleteDB } from 'idb';
@@ -881,15 +881,14 @@ class AuthStorageService {
881
881
  };
882
882
  const url = `${this._BASE_URL}/GetNewToken`;
883
883
  const headers = new HttpHeaders()
884
- .set('Content-Type', 'application/json')
885
- .set('Authorization', `Basic ${btoa(`${localStorage.getItem('configServerUser')}:${localStorage.getItem('configServerPassword')}`)}`);
886
- return this._httpClient
887
- .post(url, token, { 'headers': headers })
888
- .pipe(take(1), tap((response) => {
889
- if (response.Error) {
890
- throw Error(response.ErrorMessage);
891
- }
892
- }));
884
+ .set('Content-Type', 'application/json');
885
+ // Remover/comentar o header abaixo pois o token será enviado via Cookie HttpOnly, e não mais via header Authorization
886
+ // .set('Authorization',
887
+ // `Basic ${btoa(`${localStorage.getItem('configServerUser')}:${localStorage.getItem('configServerPassword')}`)}`
888
+ // );
889
+ return this._httpClient.post(url, token, { 'headers': headers, withCredentials: true })
890
+ .pipe(take(1), tap((response) => { if (response.Error)
891
+ throw Error(response.ErrorMessage); }));
893
892
  }
894
893
  getNewToken() {
895
894
  return new Promise((resolve, reject) => {
@@ -1122,20 +1121,23 @@ class AuthService {
1122
1121
  // #region ==========> PROPERTIES <==========
1123
1122
  // #region PRIVATE
1124
1123
  this._pendingWarning = null;
1125
- this._BASE_URL = ''; // SpInfra2WS
1126
1124
  this._AUTH_BASE_URL = ''; // SpInfra2AuthWS
1125
+ this._BASE_URL = ''; // SpInfra2WS
1127
1126
  this._BASE_OS_URL = ''; // SpInfra2LoginWS
1127
+ this._LOGOUT_BASE_URL = ''; // SpInfra2LoginWS
1128
1128
  this._HTTP_HEADERS = new HttpHeaders().set('Content-Type', 'application/json');
1129
1129
  this.ip = "undefined";
1130
1130
  this.city = "undefined";
1131
1131
  this.state = "undefined";
1132
1132
  this.country = "undefined";
1133
- this._BASE_URL = `${this._customEnvironmentService.SpInfra2LoginWS}/LoginSisproERP`; // SpInfra2WS
1134
1133
  this._AUTH_BASE_URL = `${this._customEnvironmentService.SpInfra2AuthWS}/Auth`; // SpInfra2AuthWS
1134
+ this._BASE_URL = `${this._customEnvironmentService.Sp2LocalhostInfra2LoginWS}/LoginSisproERP`; // SpInfra2WS
1135
1135
  this._BASE_OS_URL = `${this._customEnvironmentService.SpInfra2LoginWS}/LoginIntegradoOS`; // SpInfra2LoginWS
1136
- this._BASE_URL = !this._customEnvironmentService.production ? this._BASE_URL : `${this._customEnvironmentService.SpInfra2LoginWS}/LoginSisproERP`;
1136
+ this._LOGOUT_BASE_URL = `${this._customEnvironmentService.SpInfra2LoginWS}/LogoutSisproErp`; // SpInfra2LoginWS
1137
1137
  this._AUTH_BASE_URL = !this._customEnvironmentService.production ? this._AUTH_BASE_URL : `${this._customEnvironmentService.SpInfra2AuthWS}/Auth`;
1138
+ this._BASE_URL = !this._customEnvironmentService.production ? this._BASE_URL : `${this._customEnvironmentService.SpInfra2LoginWS}/LoginSisproERP`;
1138
1139
  this._BASE_OS_URL = !this._customEnvironmentService.production ? this._BASE_OS_URL : `${this._customEnvironmentService.SpInfra2LoginWS}/LoginIntegradoOS`;
1140
+ this._LOGOUT_BASE_URL = !this._customEnvironmentService.production ? this._BASE_OS_URL : `${this._customEnvironmentService.SpInfra2LoginWS}/LogoutSisproErp`;
1139
1141
  this.getParms();
1140
1142
  }
1141
1143
  // #region ==========> SERVICE METHODS <==========
@@ -1193,8 +1195,10 @@ class AuthService {
1193
1195
  if (response.Error) {
1194
1196
  throw Error(response.ErrorMessage);
1195
1197
  }
1196
- localStorage.setItem('configServerUser', response.User);
1197
- localStorage.setItem('configServerPassword', response.Password);
1198
+ // Comentadas pois não serão mais armazenadas desta forma, o webservice gerará um Cookie com o valor já formatado para Base64
1199
+ // E o mesmo será enviada nas requisições subsequentes via párâmetro `withCredentials: true`, e não mais via header Authorization
1200
+ // localStorage.setItem('configServerUser', response.User);
1201
+ // localStorage.setItem('configServerPassword', response.Password);
1198
1202
  this._authStorageService.tenantId = response.TenantId;
1199
1203
  this._authStorageService.dominio = response.Domain;
1200
1204
  this._authStorageService.infraInAuthTypeId = response.InfraInAuthTypeId;
@@ -1438,14 +1442,19 @@ class AuthService {
1438
1442
  }
1439
1443
  }));
1440
1444
  }
1441
- /** Realiza o logout do sistema, removendo tokens do localStorage e limpando cache */
1445
+ /** Realiza o logout do sistema, consumindo o endpoint de logout para remover os cookies e limpando as informações de autenticação armazenadas no localStorage. */
1442
1446
  logout() {
1443
- this._authStorageService.logout();
1444
- localStorage.removeItem('configsServerUser');
1445
- localStorage.removeItem('configsServerPassword');
1446
- // Método com customizações para inicializações do Logout
1447
- this._customLoginService.authLogout();
1448
- this._router.navigate(["/auth/login"]);
1447
+ // Consumo de endpoint de logout
1448
+ const url = `${this._LOGOUT_BASE_URL}`;
1449
+ firstValueFrom(this._httpClient.post(url, null, { 'headers': this._HTTP_HEADERS })).then(res => {
1450
+ console.log(res);
1451
+ this._authStorageService.logout();
1452
+ localStorage.removeItem('configsServerUser');
1453
+ localStorage.removeItem('configsServerPassword');
1454
+ // Método com customizações para inicializações do Logout
1455
+ this._customLoginService.authLogout();
1456
+ this._router.navigate(["/auth/login"]);
1457
+ });
1449
1458
  }
1450
1459
  validateAuthentication2Fa(code) {
1451
1460
  let Code2Fa = {
@@ -1972,16 +1981,12 @@ class PesquisaTelasGlobalService {
1972
1981
  // #region PUBLIC
1973
1982
  // #endregion PUBLIC
1974
1983
  // #endregion ==========> PROPERTIES <==========
1975
- constructor(_componentFactoryResolver, _appRef, _injector, _httpClient, _customEnvironmentService, _authUtils) {
1976
- this._componentFactoryResolver = _componentFactoryResolver;
1984
+ constructor(_appRef, _injector, _httpClient, _customEnvironmentService, _authUtils) {
1977
1985
  this._appRef = _appRef;
1978
1986
  this._injector = _injector;
1979
1987
  this._httpClient = _httpClient;
1980
1988
  this._customEnvironmentService = _customEnvironmentService;
1981
1989
  this._authUtils = _authUtils;
1982
- // #region ==========> PROPERTIES <==========
1983
- // #region PRIVATE
1984
- // #region GERENCIAMENTO DINÂMICO DO COMPONENTE
1985
1990
  /**
1986
1991
  * Referência ao componente dinâmico criado.
1987
1992
  * Usado para gerenciar o ciclo de vida e estado do componente.
@@ -2103,7 +2108,7 @@ class PesquisaTelasGlobalService {
2103
2108
  *
2104
2109
  * Este método utiliza a API baixo nível do Angular para criar um componente dinamicamente e anexá-lo ao DOM. O processo envolve:
2105
2110
  *
2106
- * 1. Criar o componente via ComponentFactoryResolver
2111
+ * 1. Criar o componente via `container.createComponent()`
2107
2112
  * 2. Configurar suas propriedades iniciais
2108
2113
  * 3. Registrá-lo no mecanismo de detecção de mudanças do Angular
2109
2114
  * 4. Anexá-lo ao DOM (fora da hierarquia normal de componentes)
@@ -2119,24 +2124,18 @@ class PesquisaTelasGlobalService {
2119
2124
  if (this._componentRef) {
2120
2125
  return;
2121
2126
  }
2122
- // 1. Resolve a fábrica do componente - primeiro passo para criar
2123
- // um componente dinamicamente no Angular. A fábrica contém os metadados
2124
- // necessários para instanciar o componente.
2125
- const componentFactory = this._componentFactoryResolver.resolveComponentFactory(SearchInputComponent);
2126
- // 2. Cria uma nova instância do componente usando o injector raiz
2127
- // Isso garante que o componente tenha acesso aos mesmos serviços
2128
- // que componentes criados normalmente via template
2129
- this._componentRef = componentFactory.create(this._injector);
2130
- // 3. Registra a view do componente no ApplicationRef
2127
+ // 1. Cria uma nova instância do componente
2128
+ this._componentRef = this._container.createComponent(SearchInputComponent);
2129
+ // 2. Registra a view do componente no ApplicationRef
2131
2130
  // Isso é CRÍTICO: sem este passo, o componente não participaria
2132
2131
  // do ciclo de detecção de mudanças do Angular
2133
2132
  this._appRef.attachView(this._componentRef.hostView);
2134
- // 4. Obtém o elemento DOM raiz do componente e o anexa ao body
2133
+ // 3. Obtém o elemento DOM raiz do componente e o anexa ao body
2135
2134
  // Como este componente é criado fora da hierarquia normal,
2136
2135
  // precisamos anexá-lo manualmente ao DOM
2137
2136
  const domElem = this._componentRef.hostView.rootNodes[0];
2138
2137
  document.body.appendChild(domElem);
2139
- // 5. Configura os listeners dos eventos do componente
2138
+ // 4. Configura os listeners dos eventos do componente
2140
2139
  // Em vez de tratar o hide() diretamente aqui, encaminhamos o evento para o Subject _onClose$ e guardamos a subscription para poder removê-la quando escondermos o componente.
2141
2140
  this._componentCloseSub = this._componentRef.instance.onClose.subscribe(() => this._onClose$.next());
2142
2141
  // Em vez de tratar o getTelas() diretamente aqui, encaminhamos o evento para o Subject _onSearch$ e guardamos a subscription para poder removê-la quando escondermos o componente.
@@ -2180,13 +2179,16 @@ class PesquisaTelasGlobalService {
2180
2179
  // #endregion GERENCIAMENTO DO COMPONENTE
2181
2180
  showErrorMessage(response) { if (response.Error)
2182
2181
  throw Error(response.ErrorMessage); }
2183
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PesquisaTelasGlobalService, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: i1.HttpClient }, { token: LibCustomEnvironmentService }, { token: AuthUtilService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2182
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PesquisaTelasGlobalService, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }, { token: i1.HttpClient }, { token: LibCustomEnvironmentService }, { token: AuthUtilService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2184
2183
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PesquisaTelasGlobalService, providedIn: 'root' }); }
2185
2184
  }
2186
2185
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PesquisaTelasGlobalService, decorators: [{
2187
2186
  type: Injectable,
2188
2187
  args: [{ providedIn: 'root' }]
2189
- }], ctorParameters: () => [{ type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: i1.HttpClient }, { type: LibCustomEnvironmentService }, { type: AuthUtilService }] });
2188
+ }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.Injector }, { type: i1.HttpClient }, { type: LibCustomEnvironmentService }, { type: AuthUtilService }], propDecorators: { _container: [{
2189
+ type: ViewChild,
2190
+ args: ['container', { read: ViewContainerRef, static: true }]
2191
+ }] } });
2190
2192
 
2191
2193
  class ErrorMenuNotAllowed {
2192
2194
  constructor(router, authStorageService) {
@@ -4321,15 +4323,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
4321
4323
  ;
4322
4324
 
4323
4325
  /**
4324
- * \brief Intercepta uma chamada HTTP para inserir o usuário logado no header em conjunto
4325
- * com o login para uso da API.
4326
- *
4326
+ * Intercepta uma chamada HTTP para inserir o usuário logado nos cookies (e header, para compatibilidade) em conjunto com o login para uso da API.
4327
4327
  * Depende do serviço de autenticação.
4328
- */
4328
+ */
4329
4329
  class AuthAplicInterceptor {
4330
- constructor(authCheckService, token, _customEnvironmentService) {
4331
- this.authCheckService = authCheckService;
4332
- this.token = token;
4330
+ constructor(_authCheckService, _authStorage, _customEnvironmentService) {
4331
+ this._authCheckService = _authCheckService;
4332
+ this._authStorage = _authStorage;
4333
4333
  this._customEnvironmentService = _customEnvironmentService;
4334
4334
  }
4335
4335
  intercept(req, next) {
@@ -4338,12 +4338,16 @@ class AuthAplicInterceptor {
4338
4338
  }
4339
4339
  async handle(req, next) {
4340
4340
  let changedReq = req;
4341
- if (this.authCheckService.needsAuthRequest(req.url, req.method, this._customEnvironmentService.needsAuthAplic)) {
4341
+ if (this._authCheckService.needsAuthRequest(req.url, req.method, this._customEnvironmentService.needsAuthAplic)) {
4342
4342
  // Verifica se o Token precisa ser renovado
4343
- await this.token.renewToken();
4343
+ await this._authStorage.renewToken();
4344
4344
  // Adiciona as autenticações necessárias ao servidor.
4345
- let headers = req.headers.set('Authorization', `Bearer ${this.token.authToken}`);
4346
- changedReq = req.clone({ headers: headers });
4345
+ // Daqui alguns dias este trecho será removido e os tokens serão enviados exclusivamente pelos Cookies, mas por enquanto, para manter compatibilidade com o que já existe, o token será enviado no header
4346
+ let headers = req.headers.set('Authorization', `Bearer ${this._authStorage.authToken}`);
4347
+ changedReq = req.clone({
4348
+ headers: headers,
4349
+ withCredentials: true // Parâmetro necessário para utilização dos Cookies HttpOnly
4350
+ });
4347
4351
  }
4348
4352
  return await lastValueFrom(next.handle(changedReq));
4349
4353
  }
@@ -4355,21 +4359,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
4355
4359
  args: [{ providedIn: 'root' }]
4356
4360
  }], ctorParameters: () => [{ type: i3.CheckUrlAndMethodService }, { type: AuthStorageService }, { type: LibCustomEnvironmentService }] });
4357
4361
 
4358
- /**
4359
- * \brief Intercepta uma chamada HTTP para inserir a autenticação da Sispro.
4360
- */
4362
+ /** Intercepta uma chamada HTTP para inserir a autenticação da básica das APIs nos Cookies (e no header, para compatibilidade) */
4361
4363
  class AuthInfraInterceptor {
4362
- constructor(authCheckService, _customEnvironmentService) {
4363
- this.authCheckService = authCheckService;
4364
+ constructor(_authCheckService, _customEnvironmentService) {
4365
+ this._authCheckService = _authCheckService;
4364
4366
  this._customEnvironmentService = _customEnvironmentService;
4365
4367
  }
4366
4368
  intercept(req, next) {
4367
4369
  let changedReq = req;
4368
- if (this.authCheckService.needsAuthRequest(req.url, req.method, this._customEnvironmentService.needsAuthInfra)) {
4370
+ if (this._authCheckService.needsAuthRequest(req.url, req.method, this._customEnvironmentService.needsAuthInfra)) {
4371
+ // Instanciado inicialmente com os headers da requisição original, para não perder nenhum header que já tenha sido adicionado
4372
+ let headers = req.headers;
4369
4373
  // Adiciona as autenticações necessárias ao servidor. Autenticação básica.
4370
- let headers = req.headers.set("Authorization", `Basic ${btoa(`${localStorage.getItem('configServerUser')}:${localStorage.getItem('configServerPassword')}`)}
4374
+ // Daqui alguns dias este trecho será removido e os tokens serão enviados exclusivamente pelos Cookies, mas por enquanto, para manter compatibilidade com o que já existe, o token será enviado no header
4375
+ if (localStorage.getItem('configServerUser') && localStorage.getItem('configServerPassword')) {
4376
+ headers = req.headers.set("Authorization", `Basic ${btoa(`${localStorage.getItem('configServerUser')}:${localStorage.getItem('configServerPassword')}`)}
4371
4377
  `);
4372
- changedReq = req.clone({ headers: headers });
4378
+ }
4379
+ changedReq = req.clone({
4380
+ headers: headers,
4381
+ withCredentials: true // Parâmetro necessário para utilização dos Cookies HttpOnly
4382
+ });
4373
4383
  }
4374
4384
  return next.handle(changedReq);
4375
4385
  }