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

@fmlimao/create-esqueleto-login

v1.1.2

Published

Template para criar projetos baseados no Esqueleto Login - Sistema administrativo com autenticação e autorização

Downloads

12

Readme

🔐 Esqueleto Login

Esqueleto de sistema administrativo completo com autenticação e autorização baseada em perfis e privilégios. Projeto base para desenvolvimento de sistemas que necessitam de controle de acesso granular.

📋 Índice

✨ Funcionalidades

🔑 Autenticação

  • Login via Basic Auth (API) e formulário web
  • Geração de tokens de sessão e acesso
  • Gerenciamento de múltiplos tokens por usuário
  • Cache de tokens no Redis para melhor performance
  • Logout com revogação de tokens
  • Expiração automática de tokens

🛡️ Autorização

  • Sistema de perfis (roles) com suporte a perfil master
  • Privilégios granulares (ex: users.list, users.create, roles.update)
  • Middleware de autorização flexível:
    • Verificação de privilégio único
    • Múltiplos privilégios com lógica OR ou AND
    • Bypass automático para perfis master

👥 Gerenciamento de Usuários

  • CRUD completo de usuários
  • Associação de usuários a perfis
  • Controle de status (ativo/inativo)
  • Soft delete
  • Gerenciamento de tokens de acesso

🎭 Gerenciamento de Perfis

  • CRUD completo de perfis
  • Atribuição de privilégios aos perfis
  • Perfis master com acesso total ao sistema

⚙️ Sistema de Configurações

  • Gerenciamento de configurações do sistema via interface web
  • Configurações agrupadas por categoria
  • Suporte a múltiplos tipos de valores:
    • string - Texto simples
    • integer - Números inteiros
    • float - Números decimais
    • boolean - Valores verdadeiro/falso
    • json - Valores JSON
    • select - Seleção de opções pré-definidas
  • Edição apenas de valores (não permite criar/deletar configurações)
  • Configurações dinâmicas aplicadas em tempo real:
    • THEME_SKIN - Skin do tema AdminLTE
    • APP_TITLE - Título da aplicação
    • APP_SHORT_TITLE - Título curto da aplicação

🌐 Duas Interfaces

  • API REST (/api/v1): Endpoints JSON para integração
  • Interface Web (/): Views EJS para administração

🛠️ Tecnologias

  • Node.js - Runtime JavaScript
  • Express 5 - Framework web
  • EJS - Template engine para views
  • MySQL 8.0 - Banco de dados relacional
  • Knex.js - Query builder para MySQL
  • Redis - Cache e armazenamento de tokens
  • bcrypt - Hash de senhas
  • Helmet - Segurança HTTP
  • ValidatorJS - Validação de dados
  • Docker - Containerização

📦 Pré-requisitos

  • Node.js (versão 18 ou superior)
  • MySQL 8.0
  • Redis 7
  • Docker e Docker Compose (opcional, mas recomendado)

🚀 Instalação

Opção 1: Usar como Template NPM (Recomendado)

Após publicar no npm, você pode criar um novo projeto usando:

npm create @fmlimao/esqueleto-login meu-projeto

Para testar antes de publicar, você pode clonar e executar:

git clone https://github.com/fmlimao/esqueleto-login.git temp-esqueleto
cd temp-esqueleto
node bin/create-esqueleto-login.js ../meu-projeto
cd ..
rm -rf temp-esqueleto

O comando irá:

  • ✅ Criar o diretório do projeto
  • ✅ Copiar todos os arquivos necessários
  • ✅ Instalar as dependências automaticamente
  • ✅ Criar um arquivo .env.example configurado

Depois, siga os passos 3 e 4 abaixo para configurar o banco de dados e variáveis de ambiente.

Opção 2: Instalação Manual

1. Clone o repositório

git clone <url-do-repositorio>
cd esqueleto-login

2. Instale as dependências

cd app
npm install

3. Configure o banco de dados

Execute o script SQL para criar as tabelas e dados iniciais:

mysql -u root -p < base.sql

Ou importe o arquivo base.sql através de um cliente MySQL.

4. Configure as variáveis de ambiente

Crie um arquivo .env na pasta app/ com as seguintes variáveis:

# Aplicação
APP_HOST=http://localhost:3000
APP_PORT=3000
APP_TITLE=Esqueleto Login
APP_SHORT_TITLE=EL

# API
API_HOST=http://localhost:3000/api/v1

# Banco de Dados
DB_HOST=localhost
DB_PORT=3306
DB_NAME=esqueleto_login_demo
DB_USER=esqueleto_login_user
DB_PASS=esqueleto_login_pass

# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=

# Tokens
SESSION_TOKEN_EXPIRY_HOURS=8
MAX_ACCESS_TOKENS_PER_USER=10
TOKEN_CACHE_TTL_SECONDS=3600

5. Inicie a aplicação

node index.js

A aplicação estará disponível em http://localhost:3000

⚙️ Configuração

Variáveis de Ambiente

| Variável | Descrição | Padrão | |----------|-----------|--------| | APP_HOST | URL base da aplicação | - | | APP_PORT | Porta do servidor | - | | APP_TITLE | Título da aplicação (fallback se não encontrar no banco) | APP_TITLE | | APP_SHORT_TITLE | Título curto (fallback se não encontrar no banco) | APP_SHORT_TITLE | | API_HOST | URL base da API | http://192.168.0.210:3000/api/v1 | | DB_HOST | Host do MySQL | - | | DB_PORT | Porta do MySQL | - | | DB_NAME | Nome do banco de dados | - | | DB_USER | Usuário do MySQL | - | | DB_PASS | Senha do MySQL | - | | REDIS_HOST | Host do Redis | 192.168.0.210 | | REDIS_PORT | Porta do Redis | 6379 | | REDIS_PASSWORD | Senha do Redis (opcional) | - | | SESSION_TOKEN_EXPIRY_HOURS | Horas até expiração do token de sessão | 8 | | MAX_ACCESS_TOKENS_PER_USER | Máximo de tokens de acesso por usuário | 10 | | TOKEN_CACHE_TTL_SECONDS | TTL do cache de tokens no Redis | 3600 |

Configurações do Sistema

Algumas configurações podem ser gerenciadas diretamente pela interface web em /settings (apenas usuários master):

  • APP_TITLE - Título da aplicação (substitui a variável de ambiente)
  • APP_SHORT_TITLE - Título curto da aplicação (substitui a variável de ambiente)
  • THEME_SKIN - Skin do tema AdminLTE (ex: skin-blue, skin-purple-light, etc.)
  • SESSION_TOKEN_EXPIRY_HOURS - Tempo de expiração dos tokens de sessão
  • MAX_ACCESS_TOKENS_PER_USER - Máximo de tokens de acesso por usuário
  • TOKEN_CACHE_TTL_SECONDS - TTL do cache de tokens no Redis

As configurações são aplicadas em tempo real, sem necessidade de reiniciar o servidor.

📁 Estrutura do Projeto

esqueleto-login/
├── app/
│   ├── src/
│   │   ├── controllers/
│   │   │   ├── api/v1/          # Controllers da API REST
│   │   │   │   ├── auth/        # Autenticação
│   │   │   │   ├── users/       # Usuários
│   │   │   │   ├── roles/       # Perfis
│   │   │   │   ├── privileges/  # Privilégios
│   │   │   │   └── settings/    # Configurações
│   │   │   └── app/v1/          # Controllers da interface web
│   │   │       └── settings/    # Configurações (web)
│   │   ├── database/
│   │   │   ├── conn.js          # Conexão MySQL
│   │   │   └── redis.js         # Conexão Redis
│   │   ├── helpers/             # Funções auxiliares
│   │   ├── middlewares/         # Middlewares Express
│   │   │   ├── authentication.js
│   │   │   └── authorization.js
│   │   ├── repositories/        # Camada de acesso a dados
│   │   ├── services/            # Serviços externos
│   │   └── views/               # Templates EJS
│   │       ├── layout/          # Layout base
│   │       ├── settings/        # Configurações
│   │       ├── users/           # Usuários
│   │       └── roles/           # Perfis
│   ├── index.js                 # Arquivo principal
│   └── package.json
├── base.sql                      # Script de criação do banco
├── docker-compose.yml            # Configuração Docker
└── README.md

🎯 Como Usar

Login Inicial

Após executar o base.sql, você terá um usuário master criado:

Interface Web

Acesse http://localhost:3000/login para fazer login na interface web.

Configurações do Sistema

Usuários com perfil master podem acessar /settings para gerenciar as configurações do sistema:

  • APP_TITLE e APP_SHORT_TITLE - Títulos da aplicação
  • THEME_SKIN - Skin do tema (ex: skin-blue, skin-purple-light)
  • Configurações de tokens e cache

As alterações são aplicadas imediatamente, sem necessidade de reiniciar o servidor.

API REST

Para usar a API, primeiro faça login para obter um token:

curl -X POST http://localhost:3000/api/v1/auth/login \
  -H "Authorization: Basic $(echo -n '[email protected]:senha' | base64)"

Use o token retornado nas requisições subsequentes:

curl -X GET http://localhost:3000/api/v1/users \
  -H "Authorization: Bearer SEU_TOKEN_AQUI"

🔌 API REST

Autenticação

POST /api/v1/auth/login

Faz login e retorna um token de sessão.

Headers:

Authorization: Basic <base64(email:senha)>

Resposta:

{
  "error": false,
  "code": 200,
  "messages": ["Login realizado com sucesso."],
  "content": {
    "token": "token_aqui",
    "tokenData": {
      "uuid": "...",
      "tokenType": "session",
      "expiresAt": "...",
      "createdAt": "..."
    },
    "user": {
      "uuid": "...",
      "name": "...",
      "email": "...",
      "role": {
        "uuid": "...",
        "name": "...",
        "master": true
      }
    }
  }
}

GET /api/v1/auth/me

Retorna informações do usuário autenticado.

Headers:

Authorization: Bearer <token>

POST /api/v1/auth/logout

Faz logout e revoga o token atual.

Headers:

Authorization: Bearer <token>

Usuários

  • GET /api/v1/users - Lista usuários (requer: users.list)
  • POST /api/v1/users - Cria usuário (requer: users.create)
  • GET /api/v1/users/:uuid - Mostra usuário (requer: users.view)
  • PUT /api/v1/users/:uuid - Atualiza usuário (requer: users.update)
  • DELETE /api/v1/users/:uuid - Deleta usuário (requer: users.delete)

Tokens de Usuário

  • GET /api/v1/users/:uuid/tokens - Lista tokens do usuário
  • POST /api/v1/users/:uuid/tokens - Cria token de acesso
  • DELETE /api/v1/users/:uuid/tokens/:tokenUuid - Revoga token

Perfis

  • GET /api/v1/roles - Lista perfis (requer: roles.list)
  • POST /api/v1/roles - Cria perfil (requer: roles.create)
  • GET /api/v1/roles/:uuid - Mostra perfil (requer: roles.view)
  • PUT /api/v1/roles/:uuid - Atualiza perfil (requer: roles.update)
  • DELETE /api/v1/roles/:uuid - Deleta perfil (requer: roles.delete)

Privilégios de Perfis

  • GET /api/v1/roles/:uuid/privileges - Lista privilégios do perfil
  • POST /api/v1/roles/:uuid/privileges - Adiciona privilégio ao perfil
  • DELETE /api/v1/roles/:uuid/privileges/:privilegeUuid - Remove privilégio do perfil

Privilégios

  • GET /api/v1/privileges - Lista todos os privilégios disponíveis

Configurações

  • GET /api/v1/settings/by-key/:keyName - Busca configuração por chave (público)
  • GET /api/v1/settings - Lista todas as configurações agrupadas por categoria (requer: master)
  • PUT /api/v1/settings/:uuid - Atualiza valor de uma configuração (requer: master)

🔐 Autenticação e Autorização

Autenticação

A autenticação é feita via Bearer Token no header Authorization:

Authorization: Bearer <seu_token>

O token é validado através do middleware authentication.js, que:

  1. Extrai o token do header
  2. Gera o hash do token
  3. Busca no Redis (cache)
  4. Se não encontrar, busca no banco de dados
  5. Valida expiração
  6. Popula req.user e req.userPrivileges

Autorização

A autorização é feita através do middleware authorization.js:

// Verifica um privilégio
authorization('users.list')

// Verifica múltiplos privilégios (OR - precisa ter pelo menos um)
authorization(['users.list', 'users.view'])

// Verifica múltiplos privilégios (AND - precisa ter todos)
authorization(['users.list', 'users.view'], { requireAll: true })

// Desabilita bypass para master
authorization('users.list', { allowMaster: false })

Privilégios Disponíveis

  • users.list - Listar usuários
  • users.view - Ver usuário
  • users.create - Criar usuário
  • users.update - Atualizar usuário
  • users.delete - Deletar usuário
  • roles.list - Listar perfis
  • roles.view - Ver perfil
  • roles.create - Criar perfil
  • roles.update - Atualizar perfil
  • roles.delete - Deletar perfil
  • roles.privileges.list - Listar privilégios do perfil
  • roles.privileges.add - Adicionar privilégio ao perfil
  • roles.privileges.remove - Remover privilégio do perfil
  • privileges.list - Listar privilégios

Nota: O gerenciamento de configurações (/settings) requer perfil master. Futuramente será adicionado o privilégio settings.manage.

Perfil Master

Usuários com perfil master = true têm acesso total ao sistema, ignorando verificações de privilégios (exceto quando allowMaster: false).

🐳 Docker

O projeto inclui um docker-compose.yml para facilitar o desenvolvimento:

# Inicia os serviços (MySQL e Redis)
docker-compose up -d

# Para os serviços
docker-compose down

# Para os serviços e remove volumes
docker-compose down -v

Serviços

  • MySQL: Porta 3306
  • Redis: Porta 6379

🗄️ Estrutura de Banco de Dados

Tabelas Principais

users

Armazena os usuários do sistema.

  • id - ID único
  • uuid - UUID para identificação externa
  • name - Nome do usuário
  • email - Email (único)
  • password - Hash da senha (bcrypt)
  • role_id - ID do perfil
  • active - Status ativo/inativo
  • created_at, updated_at, deleted_at - Timestamps

roles

Armazena os perfis de acesso.

  • id - ID único
  • uuid - UUID para identificação externa
  • name - Nome do perfil
  • description - Descrição
  • master - Flag de perfil master
  • created_at, updated_at, deleted_at - Timestamps

privileges

Armazena os privilégios disponíveis.

  • id - ID único
  • uuid - UUID para identificação externa
  • category - Categoria (ex: 'users', 'roles')
  • name - Nome do privilégio
  • slug - Slug único (ex: 'users.list')
  • description - Descrição
  • created_at, updated_at, deleted_at - Timestamps

role_privileges

Tabela de relacionamento muitos-para-muitos entre perfis e privilégios.

  • role_id - ID do perfil
  • privilege_id - ID do privilégio

user_tokens

Armazena os tokens de autenticação.

  • id - ID único
  • uuid - UUID para identificação externa
  • user_id - ID do usuário
  • token_hash - Hash do token (único)
  • token_type - Tipo ('session' ou 'access')
  • name - Nome do token (opcional)
  • expires_at - Data de expiração
  • last_used_at - Último uso
  • revoked_at - Data de revogação
  • created_at, updated_at - Timestamps

settings

Armazena configurações do sistema.

  • id - ID único
  • uuid - UUID para identificação externa
  • category - Categoria da configuração (para agrupamento)
  • key_name - Chave da configuração (único)
  • type - Tipo do valor: string, integer, boolean, float, json, select
  • value - Valor da configuração
  • values_options - Opções disponíveis (JSON array) - usado quando type = 'select'
  • description - Descrição da configuração
  • created_at, updated_at - Timestamps

📝 Notas

  • Todas as tabelas principais suportam soft delete através do campo deleted_at
  • Tokens são armazenados com hash no banco e cache no Redis
  • O sistema popula automaticamente o Redis com tokens válidos no startup
  • Perfis master têm acesso total, ignorando verificações de privilégios
  • Configurações do sistema (APP_TITLE, APP_SHORT_TITLE, THEME_SKIN) são buscadas do banco de dados e aplicadas dinamicamente
  • As variáveis de ambiente APP_TITLE e APP_SHORT_TITLE servem apenas como fallback caso as configurações não sejam encontradas no banco

📦 Publicando no NPM

Este projeto pode ser usado como template npm. Para publicar:

1. Configure o package.json

O package.json na raiz já está configurado como template. Certifique-se de que:

  • O nome do pacote está correto (@fmlimao/create-esqueleto-login)
  • As informações de autor e repositório estão atualizadas

2. Faça login no npm

npm login

3. Publique o pacote

npm publish --access public

Importante: Como você está usando um escopo (@fmlimao), você precisa adicionar --access public para tornar o pacote público. Sem isso, o pacote será privado (requer plano pago).

4. Teste o template

Após publicar, você pode testar criando um novo projeto:

npm create @fmlimao/esqueleto-login meu-projeto-teste

Como funciona:

  • O pacote se chama @fmlimao/create-esqueleto-login
  • O comando para usar é npm create @fmlimao/esqueleto-login
  • O npm remove automaticamente o prefixo create- do nome do pacote

📄 Licença

ISC