CenixPackage 2.0.4
dotnet add package CenixPackage --version 2.0.4
NuGet\Install-Package CenixPackage -Version 2.0.4
<PackageReference Include="CenixPackage" Version="2.0.4" />
<PackageVersion Include="CenixPackage" Version="2.0.4" />
<PackageReference Include="CenixPackage" />
paket add CenixPackage --version 2.0.4
#r "nuget: CenixPackage, 2.0.4"
#:package CenixPackage@2.0.4
#addin nuget:?package=CenixPackage&version=2.0.4
#tool nuget:?package=CenixPackage&version=2.0.4
CenixPackage
build
dotnet pack -C Release
Pacote NuGet desenvolvido pela Cenix para integração com os serviços internos da plataforma. Oferece autenticação JWT, gestão de usuários, empresas, departamentos, módulos, sistemas e permissões — tudo configurável em uma única chamada de injeção de dependência.
Versão atual: 2.0.1 · .NET 8.0
Superfície pública: apenas as interfaces
ICenix*Service(injetadas via DI) e os DTOs. As interfaces de API e as classes de Infrastructure sãointernal(uso interno do pacote).
Sumário
Instalação
dotnet add package CenixPackage
Configuração
Configuração mínima
Auto‑configuração por ambiente (recomendado): se as variáveis padrão existirem no ambiente (o .env do projeto), não precisa passar nada — o pacote lê sozinho:
using CenixPackage.CrossCutting.IoC;
builder.Services.CenixServiceInjection(); // lê MODULE_ID, JWT_KEY, JWT_ISSUER, JWT_AUDIENCE, AIACOS_API, ZEUS_API
Variáveis reconhecidas automaticamente:
| Variável | Vai para | Obrigatória |
|---|---|---|
MODULE_ID |
ModuleId |
✅ |
JWT_KEY / JWT_ISSUER / JWT_AUDIENCE |
Jwt.* |
✅ |
AIACOS_API |
Urls.AiacosApi |
✅ |
ZEUS_API |
Urls.ZeusApi |
necessária p/ users/permissões/etc. |
AIACOS_APP |
Urls.AiacosApp |
opcional |
Se faltar alguma obrigatória (nem no ambiente nem no
options), a injeção lança um erro claro dizendo qual faltou. As variáveis precisam estar no ambiente do processo (ex.:.envcarregado no startup / env do container).
Passando manualmente (o que você informar sobrescreve o ambiente):
builder.Services.CenixServiceInjection(options =>
{
options.ModuleId = 1;
options.Jwt = new CenixJwtSettignsDTO
{
Issuer = "seu-issuer",
Audience = "seu-audience",
Key = "sua-chave-secreta"
};
options.Urls = new CenixUrlSettingsDTO
{
AiacosApi = "https://aiacos.suaempresa.com.br", // autenticação (obrigatório)
ZeusApi = "https://zeus.suaempresa.com.br" // usuários, empresas, etc.
};
});
Dá pra misturar: passe só o que quiser customizar; o resto vem do ambiente.
Adicione também o middleware de autenticação no pipeline:
app.UseAuthentication();
app.UseAuthorization();
Todas as opções
builder.Services.CenixServiceInjection(options =>
{
options.ModuleId = 1;
// JWT — obrigatório
options.Jwt = new CenixJwtSettignsDTO
{
Issuer = builder.Configuration["Jwt:Issuer"]!,
Audience = builder.Configuration["Jwt:Audience"]!,
Key = builder.Configuration["Jwt:Key"]!
};
// URLs das APIs — obrigatório
options.Urls = new CenixUrlSettingsDTO
{
AiacosApi = builder.Configuration["Urls:AiacosApi"]!,
AiacosApp = builder.Configuration["Urls:AiacosApp"], // opcional
ZeusApi = builder.Configuration["Urls:ZeusApi"]!
};
});
Exemplo de appsettings.json:
{
"Jwt": {
"Issuer": "seu-issuer",
"Audience": "seu-audience",
"Key": "sua-chave-secreta-muito-longa"
},
"Urls": {
"AiacosApi": "https://aiacos.suaempresa.com.br",
"ZeusApi": "https://zeus.suaempresa.com.br"
}
}
Serviços disponíveis
Todos os serviços são registrados automaticamente e podem ser injetados via construtor:
public class MeuController : ControllerBase
{
private readonly ICenixUserService _userService;
private readonly ICenixAuthService _authService;
public MeuController(
ICenixUserService userService,
ICenixAuthService authService)
{
_userService = userService;
_authService = authService;
}
}
| Serviço | Descrição | Requisito |
|---|---|---|
ICenixAuthService |
Autenticação, usuário logado, login de módulo, login de conta de serviço | Urls.AiacosApi |
ICenixUserService |
Busca e listagem de usuários | Urls.ZeusApi |
ICenixCompanyService |
Empresas | Urls.ZeusApi |
ICenixDepartmentService |
Departamentos | Urls.ZeusApi |
ICenixModuleService |
Módulos | Urls.ZeusApi |
ICenixSystemService |
Sistemas | Urls.ZeusApi |
ICenixPermissionSyncService |
Registra o catálogo de permissões do módulo no Zeus | Urls.ZeusApi |
Erros: qualquer falha nas chamadas às APIs internas lança
CenixApiException(CenixPackage.Application.Exceptions) comStatusCode,ResponseBodyeEndpoint. UseIsAuthError(401/403) para distinguir problema de autenticação de erro do servidor (5xx) ou não encontrado (404).
ICenixAuthService
Responsável por autenticação, obtenção do usuário logado e login de módulo.
Requer:
Urls.AiacosApi
// Realiza login com e-mail/usuário e senha, retornando token, refresh token e dados do usuário
// Se storeToken = true, o token retornado é armazenado internamente e usado nas demais chamadas
// quando não houver HttpContext (cenários de background service)
Task<CenixAuthResponseDTO?> LoginAsync(string emailOrUsername, string password, bool storeToken = false)
// Seleciona um módulo para o usuário autenticado (usa o Bearer token do HttpContext)
// moduleId é obrigatório; companyId, code2FA e rememberDevice são opcionais
// Se storeToken = true, o novo token (com o módulo selecionado) é armazenado internamente
Task<CenixAuthResponseDTO?> SelectModuleAsync(
int moduleId,
int? companyId = null,
string? code2FA = null,
bool? rememberDevice = null,
bool storeToken = false)
// Login de CONTA DE SERVIÇO (M2M) em uma única chamada: autentica pela credencial da
// conta de serviço e já emite o token no módulo indicado (moduleKey), sem precisar de
// login + seleção de módulo. Por padrão armazena o token internamente (storeToken = true)
// para uso em chamadas de background sem HttpContext. Só funciona para contas de serviço.
Task<CenixAuthResponseDTO?> ServiceLoginAsync(
string emailOrUsername,
string password,
string moduleKey,
int? companyId = null, // usado quando o módulo de destino não é global
string? moduleKeyUsed = null, // moduleKey do sistema chamador (rastreio nos logs)
bool storeToken = true)
// Define manualmente o token a ser usado nas chamadas quando não houver HttpContext
// (background services, schedulers, workers, etc.)
void SetAuthorizationToken(string token)
// Remove o token armazenado internamente
void ClearAuthorizationToken()
// Retorna os dados do usuário autenticado (lê o Bearer token do HttpContext automaticamente)
Task<CenixLoggedUserDTO> GetLoggedUserAsync()
// Retorna os módulos e perfis do usuário logado, opcionalmente filtrado por módulo
Task<List<CenixModulesAndProfilesOfUserDTO>> GetProfilesOfUserAsync(int? moduleId = null)
// Realiza login de módulo com clientId/clientSecret e armazena o token internamente
Task<CenixLoginResponseModuleDTO?> LoginModuleAsync(string clientId, string clientSecret)
// Retorna o módulo atualmente logado
Task<CenixModuleDTO> GetLoggedModuleAsync()
// Retorna as empresas acessíveis no módulo informado
Task<List<CenixCompanyDTO>> GetCompaniesByModuleAsync(int moduleId)
// ----- Senha / desbloqueio / SSO -----
// Dispara o e-mail de recuperação (envia um código ao usuário)
Task ForgotPasswordAsync(string emailOrUsername)
// Redefine a senha com o código recebido por e-mail
Task ResetPasswordAsync(string emailOrUsername, string code, string password, string confirmationPassword)
// Dispara o e-mail de desbloqueio de conta
Task RequestUnlockAsync(string emailOrUsername)
// Desbloqueia a conta com o token recebido por e-mail
Task UnlockAccountAsync(string token)
// Troca a senha do usuário logado (usa o token do HttpContext)
Task ChangePasswordAsync(string currentPassword, string password, string confirmationPassword)
// Troca um transfer-token (SSO) por um token de acesso normal; storeToken armazena o novo token
Task<CenixAuthResponseDTO?> ExchangeTransferTokenAsync(string transferToken, bool storeToken = false)
Exemplo — login de usuário:
var resposta = await _authService.LoginAsync("luiz.natividade", "minhasenha");
if (resposta != null)
{
var token = resposta.Token;
var usuario = resposta.User;
Console.WriteLine($"Bem-vindo, {usuario.Name}");
}
Exemplo — seleção de módulo:
var resposta = await _authService.SelectModuleAsync(
moduleId: 9,
companyId: null,
code2FA: "123456", // opcional
rememberDevice: true // opcional
);
if (resposta != null)
{
// Novo token contendo o módulo selecionado
var tokenComModulo = resposta.Token;
}
Exemplo — login de conta de serviço (M2M / integração):
Para integrações e workers que usam uma conta de serviço, o ServiceLoginAsync faz tudo em uma chamada: autentica pela credencial e já emite o token no módulo (moduleKey). Por padrão o token fica armazenado internamente, então as demais chamadas do pacote funcionam sem HttpContext.
var resposta = await _authService.ServiceLoginAsync(
emailOrUsername: "svc.integracao",
password: "***",
moduleKey: "ZEUS_GESTAO_DE_USUARIOS", // módulo de DESTINO
companyId: 4, // opcional (módulo não-global)
moduleKeyUsed: "ARGUS_WMS" // opcional (rastreio: quem está chamando)
);
// A partir daqui, qualquer chamada do pacote usa o token da conta de serviço.
var usuarios = await _userService.GetAllUsersAsync(name: null, departmentId: null, permissionId: null);
A conta precisa ser marcada como conta de serviço e ter acesso ao módulo. A trava de IP (allowlist da conta) continua valendo — a credencial só funciona a partir das origens autorizadas.
Exemplo — uso em background service (sem HttpContext):
Em workers, schedulers e outros serviços de background, não há HttpContext para extrair o token. Para esses casos, autentique-se via LoginAsync + SelectModuleAsync (ou ServiceLoginAsync para conta de serviço) e armazene o token internamente — assim as demais chamadas do pacote funcionam normalmente.
public class MeuWorker : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
public MeuWorker(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using var scope = _serviceProvider.CreateScope();
var authService = scope.ServiceProvider.GetRequiredService<ICenixAuthService>();
var userService = scope.ServiceProvider.GetRequiredService<ICenixUserService>();
// Opção 1 — usando storeToken (mais conciso)
await authService.LoginAsync("usuario.background", "senha");
await authService.SelectModuleAsync(moduleId: 9, storeToken: true);
// Opção 2 — controle explícito do token
// var login = await authService.LoginAsync("usuario.background", "senha");
// var module = await authService.SelectModuleAsync(moduleId: 9);
// authService.SetAuthorizationToken(module!.Token);
// A partir daqui, qualquer chamada do pacote funciona normalmente
var usuarios = await userService.GetAllUsersAsync(name: null, departmentId: null, permissionId: null);
// (opcional) ao final do ciclo
authService.ClearAuthorizationToken();
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}
}
Importante: o token armazenado por
SetAuthorizationToken/storeToken: trueé mantido em um Singleton interno (LocalStorage) e tem escopo global na aplicação. Isso é ideal para workers e schedulers (um único token por processo), mas não deve ser usado em requests web — nessas, o token continua sendo lido automaticamente doHttpContext, que é por-request. O pacote prioriza oHttpContextquando ele existe.
Exemplo — usuário logado:
var user = await _authService.GetLoggedUserAsync();
Console.WriteLine(user.Name);
// Verificar permissão por chave
bool podeCriar = user.PermissionsKeys?.Contains("USER_CREATE") ?? false;
// Verificar departamentos gerenciados
var deptsGerenciados = user.ManagedDepartments;
ICenixUserService
Busca e listagem de usuários. Por padrão, os métodos de listagem filtram pelo ModuleId configurado na injeção de dependência.
Requer:
Urls.ZeusApi
// Busca um usuário pelo ID
Task<CenixUserDTO?> GetByIdAsync(int id)
// Busca múltiplos usuários por lista de IDs
Task<List<CenixUserDTO>> GetByListIdAsync(List<int> ids, bool? includeDeleted = false)
// Lista usuários com filtros simples
// filterByModule = true → filtra pelo ModuleId configurado
// filterByModule = false → retorna usuários de todos os módulos
Task<List<CenixUserDTO>> GetAllUsersAsync(
string? name,
int? departmentId,
int? permissionId,
bool? filterByModule = true,
bool? includeDeleted = false)
// Lista usuários paginados com filtros avançados e ordenação
Task<CenixPagedResponseDTO<CenixUserDTO>> GetAllUsersPagedAsync(
string? name = null,
int? departmentId = null,
int? permissionId = null,
string? permissionKey = null, // ex: "USER_CREATE"
List<int>? ids = null,
bool? filterByModule = true,
bool? includeDeleted = false,
int pageNumber = 0,
int pageSize = 10, // máximo: 50
string sortBy = "Id",
string direction = "desc") // "asc" ou "desc"
Exemplo — busca paginada:
var resultado = await _userService.GetAllUsersPagedAsync(
permissionKey: "USER_CREATE",
pageNumber: 0,
pageSize: 20,
sortBy: "Name",
direction: "asc"
);
Console.WriteLine($"Total: {resultado.TotalCount}, Páginas: {resultado.TotalPages}");
foreach (var u in resultado.Data)
Console.WriteLine(u.Name);
ICenixCompanyService
Requer:
Urls.ZeusApi
// Retorna todas as empresas
Task<List<CenixCompanyDTO>> GetAllAsync()
// Retorna uma empresa pelo ID
Task<CenixCompanyDTO?> GetByIdAsync(int id)
ICenixDepartmentService
Requer:
Urls.ZeusApi
// Retorna todos os departamentos, opcionalmente filtrado por empresa
Task<List<CenixDepartmentDTO>> GetAllAsync(int? companyId = null)
// Retorna um departamento pelo ID
Task<CenixDepartmentDTO?> GetByIdAsync(int id)
ICenixModuleService
Requer:
Urls.ZeusApi
// Retorna um módulo pelo ID
Task<CenixModuleDTO?> GetByIdAsync(int id)
// Lista módulos com filtros opcionais
Task<List<CenixModuleDTO>?> GetAllAsync(
int? systemId = null,
string? name = null,
bool? isGlobal = null,
bool? required2FA = null,
bool? deleted = null)
// Lista módulos paginados com filtros e ordenação
Task<CenixPagedResponseDTO<CenixModuleDTO>> GetPagedAsync(
string? name = null,
int? systemId = null,
int pageNumber = 0,
int pageSize = 10,
string sortBy = "Id",
string direction = "desc")
Exemplo — busca paginada de módulos:
var resultado = await _moduleService.GetPagedAsync(
name: "Admin",
systemId: 1,
pageNumber: 0,
pageSize: 20,
sortBy: "Name",
direction: "asc"
);
Console.WriteLine($"Total: {resultado.TotalCount}, Páginas: {resultado.TotalPages}");
foreach (var m in resultado.Data)
Console.WriteLine(m.Name);
ICenixSystemService
Requer:
Urls.ZeusApi
// Retorna um sistema pelo ID
Task<CenixSystemDTO?> GetByIdAsync(int id)
// Lista sistemas com filtros opcionais
Task<List<CenixSystemDTO>?> GetAllAsync(string? name = null, bool? deleted = null)
// Lista sistemas paginados com filtro e ordenação
Task<CenixPagedResponseDTO<CenixSystemDTO>> GetPagedAsync(
string? name = null,
int pageNumber = 0,
int pageSize = 10,
string sortBy = "Id",
string direction = "desc")
Exemplo — busca paginada de sistemas:
var resultado = await _systemService.GetPagedAsync(
name: "ERP",
pageNumber: 0,
pageSize: 20,
sortBy: "Name",
direction: "asc"
);
Console.WriteLine($"Total: {resultado.TotalCount}, Páginas: {resultado.TotalPages}");
foreach (var s in resultado.Data)
Console.WriteLine(s.Name);
ICenixPermissionSyncService
Registra/atualiza o catálogo de permissões deste módulo no Zeus. Cria as que faltam e vincula ao perfil Administrador do módulo. Idempotente — ideal para chamar no boot.
Você passa as KEYS completas (as mesmas que usa no can(...)). O Zeus valida o prefixo do módulo (SISTEMA_MODULO_) e o formato (MAIÚSCULAS/underscore) e rejeita as fora do padrão — listando as inválidas. Assim você mantém as keys no seu código (sem olhar no Zeus) e ninguém sobe uma key errada.
Requer:
Urls.ZeusApi+ token comPERMISSOES_CADASTRARno Zeus (ex.: conta de serviço do módulo).
Task<CenixPermissionSyncResultDTO> SyncAsync(IEnumerable<string> permissionKeys)
Padrão recomendado — declare as keys uma vez (constantes) e reuse:
public static class WmsPermissions
{
private const string P = "ARGUS_WMS_"; // prefixo do módulo
public const string AdminSistema = P + "ADMINISTRADOR_DE_SISTEMA";
public const string AdminArmazem = P + "ADMINISTRADOR_DE_ARMAZEM";
public const string Conferente = P + "CONFERENTE";
public static readonly string[] All = { AdminSistema, AdminArmazem, Conferente };
}
// no boot — registra o catálogo:
var r = await _permissionSync.SyncAsync(WmsPermissions.All);
// r.Created / r.Linked / r.Keys
// em qualquer lugar — usa a MESMA constante (sem olhar no Zeus):
if (user.PermissionsKeys.Contains(WmsPermissions.Conferente)) { ... }
Se alguma key não começar com o prefixo do módulo ou estiver mal formatada, o
SyncAsynclança erro (viaCenixApiException) com a lista das inválidas — você corrige e sobe de novo.
Em background (sem HttpContext), autentique antes com
ServiceLoginAsync(..., storeToken: true)para o token ser usado na chamada.
DTOs de referência
CenixAuthResponseDTO — resposta de login/seleção de módulo
Retornado por LoginAsync() e SelectModuleAsync().
| Campo | Tipo | Descrição |
|---|---|---|
Token |
string |
JWT de acesso |
RefreshToken |
string |
Token de renovação |
User |
CenixLoggedUserDTO |
Dados completos do usuário autenticado |
CenixLoggedUserDTO — usuário autenticado
Retornado por GetLoggedUserAsync(). Contém os dados completos do usuário no contexto de autenticação:
| Campo | Tipo | Descrição |
|---|---|---|
Id |
int |
ID do usuário |
Name |
string |
Nome completo |
Email |
string |
|
Username |
string |
Login do usuário |
CompanyId |
int? |
ID da empresa principal |
DepartmentId |
int? |
ID do departamento principal |
Company |
CenixCompanyDTO? |
Empresa principal (objeto) |
Department |
CenixDepartmentDTO? |
Departamento principal (objeto) |
Profile |
CenixProfileDTO? |
Perfil do usuário no módulo atual |
Permissions |
List<int>? |
IDs das permissões |
PermissionsKeys |
List<string>? |
Chaves textuais das permissões (ex: "USER_CREATE") |
SecondaryDepartments |
List<CenixDepartmentDTO>? |
Departamentos secundários |
ManagedDepartments |
List<CenixDepartmentDTO>? |
Departamentos gerenciados pelo usuário |
ChangePasswordOnNextLogin |
bool |
Troca de senha obrigatória |
TwoFactorActive |
bool |
2FA ativo |
ProtheusCode |
string? |
Código Protheus vinculado |
ExpiresAt |
DateTime? |
Data de expiração do acesso |
CreatedAt |
DateTime? |
Data de criação |
DeletedAt |
DateTime? |
Data de exclusão (soft delete) |
CenixUserDTO
| Campo | Tipo | Descrição |
|---|---|---|
Id |
int |
ID do usuário |
Name |
string |
Nome completo |
Email |
string |
|
Username |
string |
Login do usuário |
CompanyId |
int? |
ID da empresa principal |
DepartmentId |
int? |
ID do departamento principal |
Company |
CenixCompanyDTO? |
Empresa principal (objeto) |
Department |
CenixDepartmentDTO? |
Departamento principal (objeto) |
Permissions |
List<int>? |
IDs das permissões |
PermissionsKeys |
List<string> |
Chaves textuais das permissões (ex: "USER_CREATE") |
SecondaryDepartments |
List<CenixDepartmentDTO>? |
Departamentos secundários |
ManagedDepartments |
List<CenixDepartmentDTO>? |
Departamentos gerenciados pelo usuário |
ForcePasswordChange |
bool |
Exige troca de senha no próximo login |
LastLogin |
DateTime? |
Último acesso |
EmailVerifiedAt |
DateTime? |
Data de verificação do e-mail |
AccessUntil |
DateTime? |
Data limite de acesso |
CreatedAt |
DateTime |
Data de criação |
DeletedAt |
DateTime? |
Data de exclusão (soft delete) |
CenixCompanyDTO
| Campo | Tipo | Descrição |
|---|---|---|
Id |
int |
ID da empresa |
Name |
string |
Nome da empresa |
Code |
string? |
Código interno |
ParentCompanyId |
int? |
ID da empresa pai |
IsExternal |
bool |
Empresa externa |
Type |
string? |
Tipo da empresa |
StoreNumber |
string? |
Número da loja |
CpfCnpj |
string? |
CPF/CNPJ |
CreatedAt |
DateTime? |
Data de criação |
DeletedAt |
DateTime? |
Data de exclusão |
CenixDepartmentDTO
| Campo | Tipo | Descrição |
|---|---|---|
Id |
int |
ID do departamento |
Name |
string |
Nome do departamento |
Company |
CenixCompanyDTO? |
Empresa vinculada |
Managers |
List<CenixUserDTO>? |
Gestores do departamento |
CenixModuleDTO
| Campo | Tipo | Descrição |
|---|---|---|
Id |
int |
ID do módulo |
Name |
string |
Nome do módulo |
Link |
string |
URL do módulo |
SystemId |
int |
ID do sistema vinculado |
System |
CenixSystemDTO? |
Sistema vinculado (objeto) |
IsGlobal |
bool |
Módulo global |
Requires2FA |
bool |
Exige autenticação de dois fatores |
CreatedAt |
DateTime |
Data de criação |
DeletedAt |
DateTime? |
Data de exclusão |
CenixSystemDTO
| Campo | Tipo | Descrição |
|---|---|---|
Id |
int |
ID do sistema |
Name |
string |
Nome do sistema |
CreatedAt |
DateTime |
Data de criação |
DeletedAt |
DateTime? |
Data de exclusão |
CenixPagedResponseDTO<T> — resposta paginada
| Campo | Tipo | Descrição |
|---|---|---|
Data |
List<T> |
Itens da página atual |
CurrentPage |
int |
Página atual (base 0) |
TotalPages |
int |
Total de páginas |
PageSize |
int |
Itens por página |
TotalCount |
int |
Total de registros |
Arquitetura
O pacote segue o padrão DDD em camadas:
Application/ → DTOs e serviços de aplicação (implementações internal)
Domain/ → Interfaces (contratos)
Infrastructure/ → Implementações HTTP (Zeus / Aiacos) (internal)
CrossCutting/ → Injeção de dependência
Superfície pública: só as interfaces ICenix*Service (injetadas via DI) e os DTOs. As interfaces de API (ICenix*API) e as classes de Infrastructure são internal — não fazem parte do contrato do pacote.
Propagação do token JWT
Todas as chamadas às APIs internas repassam automaticamente o Bearer token. O pacote suporta dois contextos:
- Login de usuário — token lido do
HttpContext.Request.Headers["Authorization"] - Login de módulo / conta de serviço — token obtido via
LoginModuleAsync()/ServiceLoginAsync()e armazenado internamente, usado em chamadas de background (sem HttpContext)
Notas de Atualização
Resumo rápido (desde 08/02/2026)
| Versão | O que mudou |
|---|---|
| 2.0.1 | ICenixPermissionSyncService finalizado: o módulo envia as keys (as mesmas do can(...), como constantes no código) e o Zeus valida o prefixo SISTEMA_MODULO_ + formato, rejeitando as fora do padrão. Sem precisar consultar o Zeus pra saber a key. |
| 2.0.0 | ⚠️ Breaking. Removidos ICenixLogService, ICenixCacheService (Redis), o pipeline RabbitMQ e o serviço de e-mail (ICenixEmailService). Superfície pública restrita às interfaces ICenix*Service + DTOs (API e Infrastructure agora internal). Dependências RabbitMQ.Client e StackExchangeRedis removidas. Novos: auto-configuração por variáveis de ambiente (configureOptions opcional); ServiceLoginAsync (conta de serviço M2M); fluxos de senha/desbloqueio/SSO no ICenixAuthService (forgot/reset/unlock/change-password/exchange-transfer-token); ICenixPermissionSyncService (registra o catálogo de permissões do módulo no Zeus); cache por-request do /auth/me; erros agora lançam CenixApiException (status HTTP + corpo reais, não mais 401 genérico); GetLoggedModuleAsync nullable |
| 1.5.4 | Novo método ServiceLoginAsync no ICenixAuthService — login de conta de serviço (M2M) em uma chamada (autentica + emite token no módulo por moduleKey) |
| 1.5.3 | Novos métodos LoginAsync e SelectModuleAsync no ICenixAuthService, suporte a autenticação em background services via SetAuthorizationToken / ClearAuthorizationToken |
| 1.5.2 | Novos campos PermissionsKeys e ManagedDepartments no CenixUserDTO |
| 1.5.1 | Serviço de cache Redis (ICenixCacheService), novos campos em CenixLoggedUserDTO e CenixCompanyDTO |
| 1.5.0 | Serviço de sistemas (ICenixSystemService), endpoints paginados para sistemas e módulos |
| 1.4.9 | Endpoint paginado de usuários (GetAllUsersPagedAsync), novos campos no CenixUserDTO |
| 1.4.8 | Propriedade PermissionsKeys no CenixLoggedUserDTO |
v2.0.1 — 03/09/2026
Registro de permissões do módulo — por KEY, com validação
O ICenixPermissionSyncService foi finalizado no formato definitivo. O módulo envia as keys completas (as MESMAS usadas no can(...)), normalmente declaradas uma vez como constantes no próprio código:
public static class WmsPermissions
{
private const string P = "ARGUS_WMS_";
public const string Conferente = P + "CONFERENTE";
public const string AdminArmazem = P + "ADMINISTRADOR_DE_ARMAZEM";
public static readonly string[] All = { Conferente, AdminArmazem };
}
// no boot:
await _permissionSync.SyncAsync(WmsPermissions.All);
// em qualquer lugar (sem olhar no Zeus):
if (user.PermissionsKeys.Contains(WmsPermissions.Conferente)) { ... }
- O Zeus valida cada key contra o prefixo do módulo (
SISTEMA_MODULO_) e o formato (MAIÚSCULAS/underscore) e rejeita as fora do padrão, retornando a lista das inválidas (o pacote entrega isso viaCenixApiException). - Vantagem: a key vive no código do módulo (fonte única, reusada no
SyncAsynce nocan(...)) — você não precisa consultar o Zeus pra saber a key, e ninguém sobe uma key errada. SyncAsync(IEnumerable<string> permissionKeys); resultado trazCreated,LinkedeKeys. Idempotente; cria as ausentes (Id pela sequence) e vincula ao Administrador do módulo.- Requer o endpoint
POST /permissions/syncno Zeus (deploy).
v2.0.0 — 02/09/2026
✨ Novidades
- Auto‑configuração por ambiente:
configureOptionsagora é opcional — o que não for passado é lido das variáveis padrão (MODULE_ID,JWT_KEY,JWT_ISSUER,JWT_AUDIENCE,AIACOS_API,ZEUS_API, +AIACOS_APPopcional). O que o dev passa manualmente sempre vence. Erro claro se faltar alguma obrigatória. ICenixAuthService.ServiceLoginAsync(...)— login de conta de serviço (M2M) em uma chamada (POST /auth/service-login).- Fluxos de senha/desbloqueio/SSO no
ICenixAuthService:ForgotPasswordAsync,ResetPasswordAsync,RequestUnlockAsync,UnlockAccountAsync,ChangePasswordAsync,ExchangeTransferTokenAsync. ICenixPermissionSyncService.SyncAsync(permissionKeys)— o módulo registra o próprio catálogo passando as keys (as mesmas docan(...)); o Zeus valida o prefixoSISTEMA_MODULO_+ formato e rejeita as fora do padrão. Vincula ao Administrador do módulo. Idempotente; ideal no boot. RequerUrls.ZeusApi+ token comPERMISSOES_CADASTRAR.CenixApiException— toda falha de API interna agora lança essa exceção comStatusCode,ResponseBodyeEndpointreais (antes:UnauthorizedAccessExceptiongenérico pra qualquer erro).IsAuthError(401/403) ajuda a mapear a resposta ao cliente.- Cache por‑request do
/auth/me— dentro de uma mesma requisição, oGetLoggedUserAsyncé resolvido uma vez só (guardado noHttpContext.Items, chaveado pelo hash do token) e reusado; some no fim do request. Sem risco de role velha (cada nova ação busca de novo). NovoRefreshLoggedUser()limpa o cache no mesmo request se você alterar as permissões do próprio usuário e precisar reler. SemHttpContext(background) não cacheia. GetLoggedModuleAsyncagora éTask<CenixModuleDTO?>(pode ser null quando não é login de módulo) — evitaNullReferenceException.
⚠️ Mudanças que quebram compatibilidade (major)
- Superfície pública restrita: só as interfaces
ICenix*Service(injetadas via DI) e os DTOs continuam públicos. As interfaces de API (ICenix*API), as classes de Infrastructure (clientes HTTP,LocalStorage) e as implementações dos serviços passaram ainternal. Quem só injeta osICenix*Service(uso recomendado) não é afetado; quem referenciava tipos internos precisa parar de fazê-lo. - Removido
ICenixLogService(logs de erro/auditoria/info) e oZeusLogApideUrls. - Removido
ICenixCacheService(cache Redis) e a opçãoRedis; dependênciaMicrosoft.Extensions.Caching.StackExchangeRedisremovida. - Removido RabbitMQ (consumer + fila) e a opção
RabbitMQ; dependênciaRabbitMQ.Clientremovida. - Removido o serviço de e-mail (
ICenixEmailService), oCenixEmailMessageDTO, ooptions.Emaile o envio via SMTP — não era usado.
Migração: remova options.Redis, options.RabbitMQ, options.Email e Urls.ZeusLogApi do setup; troque usos de ICenixLogService/ICenixCacheService/ICenixEmailService por implementação própria, se necessário.
v1.5.4 — 02/09/2026
Login de conta de serviço (M2M)
- Novo método
ServiceLoginAsync(emailOrUsername, password, moduleKey, companyId?, moduleKeyUsed?, storeToken = true)noICenixAuthService— autentica a conta de serviço e já emite o token no módulo de destino (moduleKey) em uma única chamada (POST /auth/service-loginno Aiacos), sem precisar de login + seleção de módulo. Por padrão armazena o token internamente (ideal para workers/integrações). - Novo DTO
CenixServiceLoginDTO. Só funciona para contas marcadas como conta de serviço; a allowlist de IP da conta continua sendo aplicada pelo Aiacos.
v1.5.3 — 11/05/2026
Autenticação direta no ICenixAuthService
- Novo método
LoginAsync(emailOrUsername, password, storeToken)— autenticação viaPOST /auth/loginno Aiacos, retornaCenixAuthResponseDTO(token + refreshToken + usuário) - Novo método
SelectModuleAsync(moduleId, companyId?, code2FA?, rememberDevice?, storeToken)— seleção de módulo viaPOST /auth/select-moduleno Aiacos, retornaCenixAuthResponseDTOcom novo token contendo o módulo no payload
Suporte a background services
- Novos métodos
SetAuthorizationToken(token)eClearAuthorizationToken()para definir/limpar manualmente o token usado em chamadas semHttpContext(workers, schedulers) - Parâmetro opcional
storeTokenemLoginAsynceSelectModuleAsync: quandotrue, o token retornado é armazenado automaticamente para uso nas chamadas subsequentes
Novos DTOs
CenixLoginDTO,CenixSelectModuleDTO(request)CenixAuthResponseDTO(response compartilhado entre login e seleção de módulo)
v1.5.2 — 07/05/2026
DTOs atualizados
CenixUserDTO: adicionadosPermissionsKeys(List<string>) eManagedDepartments(List<CenixDepartmentDTO>?), espelhando os campos já existentes emCenixLoggedUserDTO
v1.5.1 — 16/04/2026
Cache Redis
- Novo serviço
ICenixCacheServicecom métodosSetAsync<T>,GetAsync<T>,RemoveAsynceExistsAsync - Configuração opcional: basta informar
Redis.StringConnectionno setup. Se não informar, o cache não é registrado - Dependência
StackExchangeRedisatualizada para 8.0.22
DTOs atualizados
CenixLoggedUserDTO: adicionadosCompanyId,CreatedAt,SecondaryDepartmentsCenixCompanyDTO: adicionadosParentCompanyId,CreatedAt,DeletedAt
v1.5.0 — 01/03/2026
Serviço de Sistemas
- Novo
ICenixSystemServicecomGetByIdAsync,GetAllAsync(filtros por nome e status) eGetPagedAsync(paginação com ordenação) - Injeção de dependência do
CenixSystemServiceregistrada automaticamente
Endpoints paginados para Módulos
ICenixModuleService.GetPagedAsync— paginação com filtros por nome, sistema, e ordenação
v1.4.9 — 27/02/2026
Endpoint paginado de Usuários
- Novo
GetAllUsersPagedAsyncemICenixUserServicecom paginação, filtros avançados (nome, departamento, permissão, permissionKey, lista de IDs) e ordenação - Novo DTO
CenixPagedResponseDTO<T>para respostas paginadas padronizadas CenixUserDTOatualizado com novos campos
v1.4.8 — 08/02/2026
Permissões por chave
- Adicionada propriedade
PermissionsKeys(List<string>) noCenixLoggedUserDTOpara acesso às chaves textuais de permissão (ex:ZEUS_GESTAO_DE_USUARIOS_USUARIOS_VISUALIZAR)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.8)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 8.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.