npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@laqus/platform-auth-angular

v1.0.1

Published

Biblioteca Angular para autenticação e autorização com o Laqus Platform

Readme

Laqus Platform Auth Angular

Este guia explica como integrar e utilizar as bibliotecas @laqus/platform-auth-angular e @laqus/auth-permissions em aplicações Angular.

Instalação

# Instalar a biblioteca de autenticação para Angular
npm install @laqus/platform-auth-angular --save

# Instalar a biblioteca de permissões
npm install @laqus/auth-permissions --save

Configuração Básica

1. Configurar o Módulo de Autenticação

No seu app.module.ts ou em um módulo específico de autenticação:

import { NgModule } from '@angular/core';
import { PlatformAuthModule } from '@laqus/platform-auth-angular';
import { AUTH_CONFIG } from '@laqus/platform-auth-angular';

@NgModule({
  imports: [
    // ... outros módulos
    PlatformAuthModule
  ],
  providers: [
    {
      provide: AUTH_CONFIG,
      useValue: {
        authMiddlewareApiUrlBase: 'https://sua-api-auth.com',
        cache: {
          authCacheKeysPrefix: 'app_auth_',
          expirationTimeInMs: 1800000 // 30 minutos em milissegundos (opcional, padrão: 30 minutos)
        }
      }
    }
  ]
})
export class AppModule { }

2. Inicialização Automática

A biblioteca @laqus/platform-auth-angular inicializa automaticamente o serviço de autenticação quando é carregada, verificando se existe um token salvo no localStorage.

Uso do AuthService

Login

import { Component } from '@angular/core';
import { AuthService } from '@laqus/platform-auth-angular';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  template: `...`
})
export class LoginComponent {
  constructor(
    private authService: AuthService,
    private router: Router
  ) {}

  login(username: string, password: string) {
    this.authService.loginWithCredentials(username, password).subscribe({
      next: (result) => {
        if (result.success) {
          this.router.navigate(['/dashboard']);
        }
      },
      error: (error) => {
        console.error('Login failed', error);
        // Tratar erro de login
      }
    });
  }
}

Verificar Autenticação

import { Component, OnInit } from '@angular/core';
import { AuthService } from '@laqus/platform-auth-angular';
import { Router } from '@angular/router';

@Component({
  selector: 'app-navbar',
  template: `
    <nav>
      <div *ngIf="isAuthenticated">
        Bem-vindo, {{ username }}
        <button (click)="logout()">Sair</button>
      </div>
      <div *ngIf="!isAuthenticated">
        <a routerLink="/login">Login</a>
      </div>
    </nav>
  `
})
export class NavbarComponent implements OnInit {
  isAuthenticated = false;
  username = '';
  
  constructor(
    private authService: AuthService,
    private router: Router
  ) {}
  
  ngOnInit() {
    // Verificar status de autenticação inicial
    this.authService.checkAuthStatus().subscribe();
    
    // Inscrever-se para mudanças no status de autenticação
    this.authService.isAuthenticated$.subscribe(isAuth => {
      this.isAuthenticated = isAuth;
    });
    
    // Inscrever-se para mudanças no usuário atual
    this.authService.currentUser$.subscribe(user => {
      this.username = user?.name || '';
    });
  }

  logout(): void {
    this.authService.logout().subscribe(() => {
      this.router.navigate(['/login']);
    });
  }
}

Verificação de Permissões

Usando o AuthService para Verificar Permissões

import { Component, OnInit } from '@angular/core';
import { AuthService } from '@laqus/platform-auth-angular';
import { IResourceAction } from '@laqus/platform-auth-angular';
import { PlatformActions } from '@laqus/auth-permissions';

@Component({
  selector: 'app-user-management',
  template: `
    <div *ngIf="canListUsers">
      <!-- Conteúdo visível apenas para usuários com permissão -->
      <button *ngIf="canCreateUsers" (click)="createUser()">Novo Usuário</button>
    </div>
  `
})
export class UserManagementComponent implements OnInit {
  canListUsers = false;
  canCreateUsers = false;

  constructor(private authService: AuthService) {}

  ngOnInit() {
    // Verificar permissões específicas
    this.canListUsers = this.authService.hasAction(
      PlatformActions.PlatformManagement.Tenant.User.Users.List
    );
    
    this.canCreateUsers = this.authService.hasAction(
      PlatformActions.PlatformManagement.Tenant.User.Users.Create
    );
    
    // Verificar múltiplas permissões
    const hasAllPermissions = this.authService.hasAllActions([
      PlatformActions.PlatformManagement.Tenant.User.Users.List,
      PlatformActions.PlatformManagement.Tenant.User.Users.Create
    ]);
    
    // Verificar se tem pelo menos uma permissão
    const hasAnyPermission = this.authService.hasAnyAction([
      PlatformActions.PlatformManagement.Tenant.User.Users.List,
      PlatformActions.PlatformManagement.Tenant.User.Users.Create
    ]);
  }
}

Usando Diretivas de Permissão

Para usar as diretivas de permissão, importe o PlatformAuthModule no seu módulo:

import { NgModule } from '@angular/core';
import { PlatformAuthModule } from '@laqus/platform-auth-angular';

@NgModule({
  imports: [
    // ... outros módulos
    PlatformAuthModule
  ]
})
export class FeatureModule { }

Então, use a diretiva hasAction nos seus templates:

<!-- Elemento visível apenas se o usuário tiver a permissão específica -->
<button *hasAction="PlatformActions.PlatformManagement.Tenant.User.Users.Create">
  Criar Usuário
</button>

<!-- Elemento visível apenas se o usuário tiver todas as permissões -->
<div *hasAllActions="[listAction, createAction, deleteAction]">
  Acesso completo
</div>

<!-- Elemento visível se o usuário tiver pelo menos uma das permissões -->
<div *hasAnyAction="[listAction, createAction]">
  Acesso parcial
</div>

Proteção de Rotas

Use o ActionAuthGuard para proteger rotas com base em permissões:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ActionAuthGuard } from '@laqus/platform-auth-angular';
import { PlatformActions } from '@laqus/auth-permissions';

const routes: Routes = [
  {
    path: 'users',
    component: UserListComponent,
    canActivate: [ActionAuthGuard],
    data: {
      requiredAction: PlatformActions.PlatformManagement.Tenant.User.Users.List
    }
  },
  {
    path: 'users/create',
    component: UserCreateComponent,
    canActivate: [ActionAuthGuard],
    data: {
      requiredAction: PlatformActions.PlatformManagement.Tenant.User.Users.Create
    }
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class UsersRoutingModule { }

Estrutura de Permissões

A biblioteca @laqus/auth-permissions fornece uma estrutura tipada para as permissões do sistema:

import { PlatformActions } from '@laqus/auth-permissions';

// Exemplos de permissões disponíveis
const userListAction = PlatformActions.PlatformManagement.Tenant.User.Users.List;
const userCreateAction = PlatformActions.PlatformManagement.Tenant.User.Users.Create;
const userUnassignAction = PlatformActions.PlatformManagement.Tenant.User.Users.Unassign;
const allUserActions = PlatformActions.PlatformManagement.Tenant.User.Users.All;

Boas Práticas

  1. Inicialização Automática: A biblioteca gerencia automaticamente o token no localStorage.

  2. Verificação de Autenticação: Use authService.isAuthenticated() para verificar se o usuário está autenticado.

  3. Verificação de Permissões: Use os métodos hasAction(), hasAllActions() ou hasAnyAction() para verificar permissões.

  4. Diretivas: Use as diretivas *hasAction, *hasAllActions e *hasAnyAction para controle de acesso no template.

  5. Proteção de Rotas: Use o ActionAuthGuard para proteger rotas com base em permissões.

Integração com Auth Middleware API Diretamente

Se sua aplicação já realiza autenticação diretamente com o endpoint /api/v1/auth/user/sessions/credentials/login do Auth Middleware API, você pode integrar facilmente com a biblioteca para usar os recursos de autorização. Este endpoint estabelece uma sessão de usuário que é utilizada pela biblioteca.

1. Autenticação Direta com Auth Middleware API

import { HttpClient } from '@angular/common/http';
import { AuthService } from '@laqus/platform-auth-angular';
import { Router } from '@angular/router';

@Component({...})
export class LoginComponent {
  constructor(
    private http: HttpClient,
    private authService: AuthService,
    private router: Router
  ) {}

  async login(username: string, password: string) {
    try {
      // Chamada direta ao endpoint do Auth Middleware API que estabelece a sessão
      const response = await this.http.post<{
        success: boolean;
        // outros campos...
      }>('https://sua-api.com/api/v1/auth/user/sessions/credentials/login', {
        username,
        password
      }, {
        withCredentials: true // Importante para estabelecer a sessão
      }).toPromise();
      
      if (response && response.success) {
        // A sessão já foi estabelecida pelo endpoint
        // Apenas inicialize o AuthService para carregar as permissões
        await this.authService.initialize();
        this.router.navigate(['/dashboard']);
        return true;
      }
      return false;
    } catch (error) {
      console.error('Falha no login:', error);
      return false;
    }
  }
}

2. Sistema de Autenticação Baseado em Sessão

A biblioteca @laqus/platform-auth-angular utiliza autenticação baseada em sessão, de forma idêntica ao projeto portal-monorepo:

Autenticação via Sessão

O endpoint /api/v1/auth/user/sessions/credentials/login do auth-middleware-api estabelece uma sessão de usuário e define um cookie seguro (__Secure-lqsid) no navegador. Este cookie tem a flag HttpOnly e é gerenciado automaticamente pelo navegador e pelo servidor.

Fluxo de Autenticação e Carregamento de Permissões

A biblioteca utiliza um fluxo em duas etapas para autenticação e carregamento de permissões:

  1. Verificação de Status de Autenticação:

    // Verificar status de autenticação
    this.authMiddlewareApiService.getUserSessionStatus().pipe(
      switchMap((status: AuthStatus) => {
        // Se autenticado e tem token, busca as permissões completas
        if (status.authenticated && status.session?.accessToken) {
          return this.authMiddlewareApiService.getUserSelf(status.session.accessToken);
        }
        return of(null);
      })
    );
  2. Carregamento de Permissões:

    // Carregar permissões do usuário usando o token de acesso
    this.authMiddlewareApiService.getUserSelf(token).pipe(
      map(userSelfData => {
        // Define os dados de permissão no serviço de autorização
        this.authorizationContextService.setPermissionData(userSelfData);
        this.permissionsLoaded = true;
      })
    );

Nota: A biblioteca não manipula diretamente os cookies de sessão, pois eles têm a flag HttpOnly e não são acessíveis via JavaScript. O navegador envia automaticamente os cookies de sessão em requisições para o mesmo domínio quando a opção withCredentials: true é usada.

Cache de Permissões

A biblioteca também armazena as permissões do usuário em cache para evitar requisições desnecessárias:

// Verificar cache primeiro
const cachedPermissions = this.cacheService.get<IUserSelfDto>('user_permissions');
if (cachedPermissions) {
  // Usar permissões do cache
  this.authorizationContextService.setPermissionData(cachedPermissions);
  this.currentUserSubject.next(cachedPermissions);
  this.permissionsLoaded = true;
  return;
}

// Se não estiver em cache, buscar da API e armazenar
// A sessão é enviada automaticamente via cookies
const status = await firstValueFrom(this.http.get<AuthStatus>(`${apiUrl}/api/v1/auth/user/sessions/status`, {
  withCredentials: true
}));

// Processar dados e armazenar em cache
if (status.user) {
  this.cacheService.set('user_permissions', status.user);
}

Configuração do Cache

Você pode configurar o prefixo usado para as chaves de cache no localStorage e o tempo de expiração do cache:

@NgModule({
  imports: [PlatformAuthModule],
  providers: [
    {
      provide: AUTH_CONFIG,
      useValue: {
        authMiddlewareApiUrlBase: 'https://sua-api.com',
        cache: {
          authCacheKeysPrefix: 'minha_app_auth_', // Prefixo personalizado
          expirationTimeInMs: 1800000 // 30 minutos em milissegundos (opcional)
        }
      }
    }
  ]
})
export class AppModule { }

Limpeza de Cache

Quando o usuário faz logout, todo o cache é limpo:

clearAuth(): void {
  this._token = null;
  this.permissionsLoaded = false;
  this.currentUserSubject.next(null);
  this.cacheService.clear(); // Limpa todo o cache
  this.removeStoredToken(); // Remove o token
}

3. Como o initialize() Funciona

O método initialize() do AuthService verifica o status de autenticação e carrega as permissões do usuário:

public async initialize(): Promise<boolean> {
  try {
    // Verifica o status de autenticação e carrega as permissões
    const status = await firstValueFrom(this.checkAuthStatus(true));
    return status.authenticated;
  } catch (error) {
    console.error('Failed to initialize auth service', error);
    return false;
  }
}

Internamente, o método checkAuthStatus realiza o fluxo completo de verificação de autenticação e carregamento de permissões descrito anteriormente.

Arquitetura de Serviços

A biblioteca utiliza uma arquitetura de serviços bem definida para separar responsabilidades:

AuthMiddlewareApiService

Responsável por todas as chamadas de API para o middleware de autenticação:

@Injectable({ providedIn: 'root' })
export class AuthMiddlewareApiService {
  // Verifica o status da sessão do usuário
  getUserSessionStatus(): Observable<AuthStatus> { ... }
  
  // Obtém os dados do usuário e suas permissões
  getUserSelf(token: string): Observable<IUserSelfDto> { ... }
  
  // Realiza o login do usuário usando credenciais
  loginWithCredentials(email: string, password: string): Observable<{ success: boolean }> { ... }
  
  // Realiza o logout do usuário
  logout(): Observable<{ success: boolean }> { ... }
  
  // Atualiza o token de acesso
  refreshToken(): Observable<{ success: boolean }> { ... }
}

AuthService

Gerencia o estado de autenticação e autorização da aplicação:

@Injectable({ providedIn: 'root' })
export class AuthService {
  // Observables para o estado de autenticação
  public readonly currentUser$ = this.currentUserSubject.asObservable();
  public readonly isAuthenticated$ = this.isAuthenticatedSubject.asObservable();
  public readonly currentSessionStatus$ = this.currentSessionStatusSubject.asObservable();
  
  // Verifica o status de autenticação
  public checkAuthStatus(forceRefresh: boolean = false): Observable<AuthStatus> { ... }
  
  // Inicializa o serviço
  public async initialize(): Promise<boolean> { ... }
  
  // Verifica se o usuário está autenticado
  isAuthenticated(): boolean { ... }
  
  // Verifica permissões
  hasAction(action: IResourceAction): boolean { ... }
  hasAllActions(actions: IResourceAction[]): boolean { ... }
  hasAnyAction(actions: IResourceAction[]): boolean { ... }
}

AuthorizationContextService

Responsável por gerenciar o contexto de autorização e verificar permissões:

@Injectable({ providedIn: 'root' })
export class AuthorizationContextService {
  // Define os dados de permissões
  setPermissionData(data: any): void { ... }
  
  // Verifica permissões
  hasAction(action: IResourceAction): boolean { ... }
  hasAllRequiredActions(actions: IResourceAction[]): boolean { ... }
  hasAnyOfRequiredActions(actions: IResourceAction[]): boolean { ... }
}

Solução de Problemas

Token Expirado

A biblioteca verifica automaticamente se o token está expirado. Se estiver, o método isAuthenticated() retornará false.

Permissões Não Carregadas

Se as permissões não estiverem carregadas, os métodos de verificação de permissão retornarão false e exibirão um aviso no console:

hasAction(action: IResourceAction): boolean {
  if (!this.isAuthenticated() || !this.permissionsLoaded) {
    console.warn('User not authenticated or permissions not loaded yet');
    return false;
  }
  return this.authorizationContextService.hasAction(action);
}

Atualização de Permissões

Para forçar uma atualização das permissões (por exemplo, após uma alteração de perfil):

// Forçar atualização do status e permissões
authService.checkAuthStatus(true).subscribe();

// Ou limpar autenticação e redirecionar para login
authService.clearAuth();
router.navigate(['/login']);