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

@haxen/auth

v1.0.21

Published

Uma biblioteca de autenticação da Haxen, projetada para acelerar e facilitar a construção de interfaces consistentes e eficientes nas aplicações.

Readme

@haxen/auth

Biblioteca de autenticacao para padronizar sessao, refresh token, persistencia e integracao React entre projetos web e mobile.

Objetivo

A lib existe para centralizar a responsabilidade de autenticacao. O consumidor integra endpoints, mapeia payloads e conecta efeitos secundarios; a lib controla sessao, persistencia e expiracao.

Responsabilidade da lib no web:

  • persistir a sessao em localStorage
  • manter cookie(s) de autenticacao sincronizados
  • propagar mudancas de sessao para React
  • executar refresh token e logout

Responsabilidade da lib no mobile:

  • usar somente o StorageAdapter informado pelo app
  • nunca depender de window, document, localStorage ou cookie

Componentes principais

  • AuthManager: nucleo da autenticacao e da sessao
  • StorageAdapter: contrato de persistencia
  • WebStorageAdapter: adapter web com localStorage e cookies
  • AuthProvider: integracao React
  • useAuth: leitura da sessao e acesso ao manager
  • AuthMapper: helper opcional para montar AuthSession

Modelo de sessao

type AuthSession = {
  accessToken: string;
  refreshToken: string;
  login: string;
  user: UsuarioAutenticado;
  empresas: Empresa[];
  empresaSelecionada: Empresa | null;
  filiais?: any[];
  expiresAt: number;
};

Campos importantes:

  • accessToken: token bearer usado nas chamadas autenticadas
  • refreshToken: token de refresh
  • login: identificador do usuario
  • user: payload do usuario autenticado
  • empresaSelecionada: contexto ativo
  • filiais: dados complementares enriquecidos pelo projeto
  • expiresAt: timestamp absoluto em milissegundos para expiracao

Fluxo de vida da sessao

  1. O projeto instancia um AuthManager.
  2. O React AuthProvider chama manager.init().
  3. A sessao persistida e restaurada.
  4. A lib rearma o timer de expiracao.
  5. Quando ocorre signIn() ou reauthenticate(), a sessao e persistida novamente.
  6. No web, os cookies configurados pelo WebStorageAdapter sao sincronizados.
  7. Quando a sessao expira, a lib chama onExpired.

Referencias de integracao

mobile-inventario

Padrao coerente com a lib:

  • usa AuthManager com AsyncStorageAdapter
  • deixa a sessao concentrada no manager
  • usa onPostAuth para headers e enriquecimento
  • chama restoreSession() no bootstrap e ao voltar para foreground
  • nao depende de cookie

front-painelvendas

Padrao correto apos alinhamento:

  • usa AuthManager com WebStorageAdapter
  • a lib escreve Auth.Token e User.Session
  • o front usa useAuth().session como fonte do React
  • proxy.ts usa somente Auth.Token para guard SSR/middleware
  • o modal de reautenticacao usa authManager.getSession() apos refresh, nunca cookie manual

Padrao incorreto que causa regressao:

  • gravar Auth.Token e User.Session manualmente fora da lib
  • usar cookie como fallback para montar o estado React
  • reautenticar com token lido de cookie antigo em vez da sessao atual do manager

API publica

init()

Restaura a sessao do storage e marca o manager como inicializado.

Use quando:

  • a app estiver subindo
  • voce precisa evitar expiracao precoce antes do bootstrap

subscribe(listener)

Assina mudancas de sessao.

O listener e chamado quando ocorre:

  • signIn
  • reauthenticate
  • updateSession
  • logout
  • init/restoreSession com sessao existente

restoreSession()

Rele a sessao do adapter configurado e a coloca em memoria.

Use quando:

  • o app voltar ao foreground no mobile
  • o projeto quiser forcar uma reidratacao manual

signIn(credentials)

Executa autenticacao inicial.

Modos suportados:

  • sso
  • credentials

reauthenticate()

Executa refresh token. A lib serializa chamadas concorrentes via reauthInFlight, evitando refresh duplicado.

updateSession(patch)

Atualiza a sessao atual sem novo login.

Aceita:

  • Partial<AuthSession>
  • funcao (current) => next

logout()

Limpa sessao em memoria, storage e cookies gerenciados pela lib.

getSession()

Retorna a sessao atual em memoria.

Use quando:

  • o projeto precisa ler o estado mais recente dentro de callback assicrona
  • um handler de expiracao quer consultar a sessao apos reauthenticate()
  • um interceptor quer acessar o token atual sem depender de render React

onPostAuth(hook)

Registra efeitos secundarios apos login e refresh.

Casos tipicos:

  • configurar header Authorization
  • carregar menu
  • buscar filiais
  • preencher analytics/telemetria

onExpired(handler)

Registra o fluxo de expiracao.

A lib nao impõe UX. O projeto decide se abre modal, renova automaticamente ou faz logout.

Contratos principais

StorageAdapter

abstract class StorageAdapter {
  abstract get<T>(key: string): Promise<T | null>;
  abstract set<T>(key: string, value: T): Promise<void>;
  abstract remove(key: string): Promise<void>;
}

AuthConfig

type AuthConfig<TMode extends 'sso' | 'credentials', TRawResponse> = {
  storage: StorageAdapter;
  httpClient: {
    post<T>(
      url: string,
      body?: unknown,
      config?: { headers?: Record<string, string> },
    ): Promise<{ data: T }>;
    get<T>(
      url: string,
      config?: { headers?: Record<string, string>; signal?: AbortSignal },
    ): Promise<{ data: T }>;
  };
  mode: TMode;
  endpoints: {
    signIn?: string;
    sso?: string;
    refresh: string;
    authenticatedUser?: string;
  };
  sessionMapper: (raw: TRawResponse) => AuthSession;
  refreshBodyMapper?: (session: AuthSession) => unknown;
  refreshMerger?: (current: AuthSession, raw: RefreshResponse) => AuthSession;
};

O que faz cada campo

  • storage: onde a sessao sera persistida
  • httpClient: cliente HTTP usado pela lib
  • mode: define fluxo sso ou credentials
  • endpoints.signIn: login por credenciais
  • endpoints.sso: login via token SSO/magic token
  • endpoints.refresh: refresh token
  • endpoints.authenticatedUser: GET complementar para buscar usuario autenticado em credentials
  • sessionMapper: converte payload bruto da API para AuthSession
  • refreshBodyMapper: customiza o body do refresh
  • refreshMerger: customiza como a resposta de refresh atualiza a sessao atual

WebStorageAdapter

O WebStorageAdapter implementa o comportamento esperado para projetos browser.

Comportamento padrão:

  • salva a sessao em localStorage
  • grava cookie Auth.Token
  • por padrao, tambem grava User.Session com snapshot completo da sessao sem duplicar os tokens
  • remove cookies gerenciados pela lib no logout

Configuracao suportada:

type WebStorageAdapterOptions = {
  tokenCookieKey?: string; // padrao: 'Auth.Token'
  sessionCookieKey?: string; // padrao: 'User.Session'
  cookiePath?: string; // padrao: '/'
  cookieDomain?: string;
  sameSite?: 'Lax' | 'Strict' | 'None'; // padrao: 'Lax'
  secure?: boolean; // por padrao, detecta https
};

Regra operacional

  • tokenCookieKey deve ser usado quando a aplicacao precisa que middleware/proxy/SSR leiam o token
  • por padrao, a lib tambem grava User.Session
  • sessionCookieKey permite customizar o nome desse cookie quando o projeto precisar
  • o snapshot de sessao inclui login, expiresAt, user completo, empresas, empresaSelecionada e filiais
  • como o cookie carrega user completo, valide o tamanho final do payload; navegadores aplicam limite por cookie e payloads muito grandes podem ser descartados
  • a fonte principal da sessao no React continua sendo useAuth().session, nunca cookie

Fluxo sso

Use quando o projeto recebe um token SSO via URL, deep link ou portal.

Comportamento:

  • POST em endpoints.sso
  • sessionMapper
  • persistencia
  • hooks de onPostAuth

Exemplo:

const authManager = new AuthManager<'sso', any>({
  storage: new WebStorageAdapter(),
  httpClient: api,
  mode: 'sso',
  endpoints: {
    sso: '/Auth/v1/Autenticacao/authenticate',
    refresh: '/Auth/v1/Autenticacao/refresh-token',
  },
  sessionMapper: data => ({
    accessToken: data.autenticacao.accessToken,
    refreshToken: data.autenticacao.refreshToken,
    login: data.usuario.login,
    user: data.usuario,
    empresas: data.usuario.empresas,
    empresaSelecionada: data.usuario.empresas?.[0] ?? null,
    filiais: [],
    expiresAt: data.usuario.expiraEm
      ? new Date(data.usuario.expiraEm).getTime()
      : Date.now() + (data.autenticacao.expiresIn ?? 3600) * 1000,
  }),
  refreshBodyMapper: session => ({
    login: session.login,
    refreshToken: session.refreshToken,
    codigoCliente: session.empresaSelecionada?.codigoCliente,
    codigoEmpresa: session.empresaSelecionada?.codigoEmpresa,
  }),
});

Fluxo credentials

Use quando o projeto autentica com login e senha.

Comportamento:

  • POST em endpoints.signIn
  • opcionalmente GET em endpoints.authenticatedUser
  • merge do payload
  • sessionMapper
  • persistencia

Exemplo:

const authManager = new AuthManager<'credentials', any>({
  storage: new WebStorageAdapter(),
  httpClient: api,
  mode: 'credentials',
  endpoints: {
    signIn: '/Auth/v1/Autenticacao/login',
    authenticatedUser: '/Admin/v1/Usuario/Autenticado',
    refresh: '/Auth/v1/Autenticacao/refresh-token',
  },
  sessionMapper: data => ({
    accessToken: data.autenticacao.accessToken,
    refreshToken: data.autenticacao.refreshToken,
    login: data.usuario.login,
    user: data.usuario,
    empresas: data.usuario.empresas,
    empresaSelecionada: data.usuario.empresas?.[0] ?? null,
    filiais: data.usuario.filiais ?? [],
    expiresAt: new Date(data.usuario.expiraEm).getTime(),
  }),
});

Como integrar efeitos secundarios

Header de autenticacao

authManager.onPostAuth(async session => {
  api.defaults.headers.common.Authorization = `Bearer ${session.accessToken}`;
});

Enriquecer a sessao com dados adicionais

authManager.onPostAuth(async session => {
  const filiais = await getUserBranchs(
    session.accessToken,
    session.user.codigoUsuario,
  );

  await authManager.updateSession({ filiais });
});

Modal de expiracao

authManager.onExpired(({ reauthenticate, logout }) => {
  openModal({
    onConfirm: () => reauthenticate(),
    onCancel: () => logout(),
  });
});

Boa pratica:

  • dentro do callback de expiracao, leia authManager.getSession() quando precisar do estado atual
  • nao use cookie como fonte de verdade da sessao do componente

Integracao React

Provider

<AuthProvider manager={authManager}>
  <App />
</AuthProvider>

O AuthProvider da lib:

  • chama manager.init()
  • restaura a sessao
  • assina subscribe()
  • atualiza automaticamente useAuth().session

Hook

const { session, manager } = useAuth();

Use:

  • session para renderizacao
  • manager para comandos e callbacks

Implementacao recomendada no web

  1. Instancie o manager com new WebStorageAdapter().
  2. O comportamento padrao ja grava Auth.Token e User.Session.
  3. Use sessionCookieKey apenas quando precisar customizar o nome do cookie de snapshot da sessao.
  4. Use useAuth().session como fonte principal no React.
  5. Deixe a lib ser dona do cookie Auth.Token.
  6. Deixe a lib ser dona tambem do cookie User.Session ou do nome customizado configurado.
  7. Use cookie apenas onde Next/middleware realmente precisar.

Contrato de persistencia no web

  • localStorage:
    • sempre recebe a AuthSession completa sob @haxen/auth/session
  • cookie Auth.Token:
    • contem somente o bearer token
    • existe para middleware, proxy, SSR e integracoes externas ao React
  • cookie User.Session ou configurado em sessionCookieKey:
    • contem snapshot da sessao sem duplicar accessToken ou refreshToken
    • inclui login, expiresAt, user completo, empresas, empresaSelecionada e filiais

Leitura correta no web

  • componente React: useAuth().session
  • callback fora do React: authManager.getSession()
  • middleware/proxy Next: cookie Auth.Token
  • necessidades excepcionais de SSR com dados do usuario: cookie User.Session ou equivalente customizado

Exemplo:

export const authManager = new AuthManager<'sso', any>({
  storage: new WebStorageAdapter({
    tokenCookieKey: 'Auth.Token',
    sessionCookieKey: 'User.Session',
  }),
  httpClient: api,
  mode: 'sso',
  endpoints: {
    sso: '/Auth/v1/Autenticacao/authenticate',
    refresh: '/Auth/v1/Autenticacao/refresh-token',
  },
  sessionMapper,
  refreshBodyMapper,
  refreshMerger,
});

O que o front web nao deve fazer

  • gravar Auth.Token manualmente
  • gravar User.Session manualmente
  • usar cookie para montar o estado React da sessao
  • manter copia paralela da sessao apenas para contornar falta de subscribe

Implementacao recomendada no mobile

  1. Implemente um adapter mobile para StorageAdapter.
  2. Passe esse adapter ao AuthManager.
  3. Chame authManager.init() no bootstrap.
  4. Configure headers em onPostAuth.
  5. Se fizer sentido, reexecute restoreSession() ao voltar ao foreground.

Exemplo de adapter:

import AsyncStorage from '@react-native-async-storage/async-storage';
import type { StorageAdapter } from '@haxen/auth';

export class AsyncStorageAdapter implements StorageAdapter {
  async get<T>(key: string): Promise<T | null> {
    const value = await AsyncStorage.getItem(key);
    return value ? JSON.parse(value) : null;
  }

  async set<T>(key: string, value: T): Promise<void> {
    await AsyncStorage.setItem(key, JSON.stringify(value));
  }

  async remove(key: string): Promise<void> {
    await AsyncStorage.removeItem(key);
  }
}

Bootstrap:

useEffect(() => {
  (async () => {
    await authManager.init();
    const restored = await authManager.restoreSession();
    setSession(restored);
  })();
}, []);

Contrato de persistencia no mobile

  • a lib nao cria cookie
  • a lib nao acessa window, document ou localStorage
  • toda persistencia depende exclusivamente do adapter informado pelo app
  • se o app precisar trocar AsyncStorage por secure storage, a troca acontece no adapter sem mudar o AuthManager

Diferença entre web e mobile

  • Web:
    • WebStorageAdapter
    • localStorage
    • cookie Auth.Token
    • cookie User.Session por padrao
  • Mobile:
    • adapter customizado
    • storage informado pelo app
    • sem cookie

Erros comuns

  • nao chamar init() no bootstrap
  • mapear expiresAt incorretamente
  • depender de cookie dentro do React
  • regravar Auth.Token fora da lib
  • regravar User.Session fora da lib
  • esquecer de atualizar headers do cliente HTTP em onPostAuth
  • nao remover o sso da URL depois do login web

Troubleshooting

Modal de reautenticacao abrindo repetidamente no web

Causas mais comuns:

  • cookie manual ficou diferente da sessao real do manager
  • onExpired abriu modal lendo estado stale
  • o front refez header com token lido do cookie em vez do token atualizado por reauthenticate()
  • havia mais de uma fonte de verdade para sessao

Correcao recomendada:

  1. manter WebStorageAdapter como unico dono de Auth.Token e User.Session
  2. usar useAuth().session ou authManager.getSession()
  3. apos reauthenticate(), reler a sessao do manager e atualizar headers com ela
  4. remover qualquer setCookie/destroyCookie manual ligado a auth

Cookie de sessao nao contem dados suficientes

Se o projeto precisar de dados completos do usuario fora do React:

  1. use o cookie padrao User.Session ou configure sessionCookieKey
  2. deixe a lib sincronizar esse cookie
  3. consuma esse cookie apenas em middleware/SSR/integracao, nunca como fonte principal de renderizacao

Checklist de integracao

Web

  • AuthManager configurado com WebStorageAdapter
  • sessionMapper implementado
  • refreshBodyMapper implementado quando a API exigir
  • AuthProvider envolvendo a aplicacao
  • useAuth().session como fonte principal
  • nenhum setCookie('Auth.Token') manual no front
  • nenhum setCookie('User.Session') manual no front

Mobile

  • adapter implementando StorageAdapter
  • authManager.init() chamado no bootstrap
  • headers configurados em onPostAuth
  • sessao restaurada ao iniciar e quando necessario

Resumo

  • A lib e dona da sessao.
  • No web, a lib e dona dos cookies de autenticacao configurados.
  • O consumidor integra UX e efeitos secundarios, mas nao reimplementa persistencia auth.
  • useAuth().session deve ser a fonte principal para componentes React.