nuxt-authenticate-module 1.0.0
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.
- package/README.md +332 -0
- package/dist/module.d.mts +10 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +79 -0
- package/dist/runtime/assets/main.css +1 -0
- package/dist/runtime/components/UserInfo.d.vue.ts +2 -0
- package/dist/runtime/components/UserInfo.vue +29 -0
- package/dist/runtime/components/UserInfo.vue.d.ts +2 -0
- package/dist/runtime/composable/closeSession.d.ts +3 -0
- package/dist/runtime/composable/closeSession.js +13 -0
- package/dist/runtime/middleware/protected.d.ts +2 -0
- package/dist/runtime/middleware/protected.js +6 -0
- package/dist/runtime/page/UserLogin.d.vue.ts +2 -0
- package/dist/runtime/page/UserLogin.vue +112 -0
- package/dist/runtime/page/UserLogin.vue.d.ts +2 -0
- package/dist/runtime/page/UserRegister.d.vue.ts +2 -0
- package/dist/runtime/page/UserRegister.vue +150 -0
- package/dist/runtime/page/UserRegister.vue.d.ts +2 -0
- package/dist/runtime/server/api/auth/closeSession.post.d.ts +4 -0
- package/dist/runtime/server/api/auth/closeSession.post.js +7 -0
- package/dist/runtime/server/api/auth/login.post.d.ts +5 -0
- package/dist/runtime/server/api/auth/login.post.js +9 -0
- package/dist/runtime/server/api/auth/register.post.d.ts +5 -0
- package/dist/runtime/server/api/auth/register.post.js +8 -0
- package/dist/runtime/server/middleware/session.d.ts +2 -0
- package/dist/runtime/server/middleware/session.js +16 -0
- package/dist/runtime/server/modules/auth/auth.errors.d.ts +4 -0
- package/dist/runtime/server/modules/auth/auth.errors.js +32 -0
- package/dist/runtime/server/modules/auth/auth.user.d.ts +24 -0
- package/dist/runtime/server/modules/auth/auth.user.js +10 -0
- package/dist/runtime/server/modules/auth/index.d.ts +2 -0
- package/dist/runtime/server/modules/auth/index.js +2 -0
- package/dist/runtime/server/modules/functions/errors/errors.controler.d.ts +6 -0
- package/dist/runtime/server/modules/functions/errors/errors.controler.js +15 -0
- package/dist/runtime/server/modules/functions/errors/errors.model.d.ts +10 -0
- package/dist/runtime/server/modules/functions/errors/index.d.ts +2 -0
- package/dist/runtime/server/modules/functions/errors/index.js +1 -0
- package/dist/runtime/server/modules/functions/utils/comparePassword.d.ts +1 -0
- package/dist/runtime/server/modules/functions/utils/comparePassword.js +4 -0
- package/dist/runtime/server/modules/functions/utils/hashPassword.d.ts +1 -0
- package/dist/runtime/server/modules/functions/utils/hashPassword.js +4 -0
- package/dist/runtime/server/modules/session/index.d.ts +4 -0
- package/dist/runtime/server/modules/session/index.js +3 -0
- package/dist/runtime/server/modules/session/session.close.d.ts +12 -0
- package/dist/runtime/server/modules/session/session.close.js +7 -0
- package/dist/runtime/server/modules/session/session.errors.d.ts +4 -0
- package/dist/runtime/server/modules/session/session.errors.js +16 -0
- package/dist/runtime/server/modules/session/session.register.d.ts +21 -0
- package/dist/runtime/server/modules/session/session.register.js +5 -0
- package/dist/runtime/server/modules/session/session.types.d.ts +31 -0
- package/dist/runtime/server/modules/users/index.d.ts +5 -0
- package/dist/runtime/server/modules/users/index.js +4 -0
- package/dist/runtime/server/modules/users/user.checkIsExist.d.ts +14 -0
- package/dist/runtime/server/modules/users/user.checkIsExist.js +8 -0
- package/dist/runtime/server/modules/users/user.errors.d.ts +4 -0
- package/dist/runtime/server/modules/users/user.errors.js +64 -0
- package/dist/runtime/server/modules/users/user.register.d.ts +21 -0
- package/dist/runtime/server/modules/users/user.register.js +10 -0
- package/dist/runtime/server/modules/users/user.repository.d.ts +10 -0
- package/dist/runtime/server/modules/users/user.validator.d.ts +9 -0
- package/dist/runtime/server/modules/users/user.validator.js +16 -0
- package/dist/runtime/server/service/index.d.ts +3 -0
- package/dist/runtime/server/service/index.js +3 -0
- package/dist/runtime/server/service/login.service.d.ts +8 -0
- package/dist/runtime/server/service/login.service.js +13 -0
- package/dist/runtime/server/service/registrarionUser.service.d.ts +5 -0
- package/dist/runtime/server/service/registrarionUser.service.js +6 -0
- package/dist/runtime/server/service/sesionClose.service.d.ts +5 -0
- package/dist/runtime/server/service/sesionClose.service.js +8 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/server/types/auth.d.ts +25 -0
- package/dist/runtime/server/utility/getSessionRepository.d.ts +13 -0
- package/dist/runtime/server/utility/getSessionRepository.js +10 -0
- package/dist/runtime/server/utility/getUserRepository.d.ts +13 -0
- package/dist/runtime/server/utility/getUserRepository.js +10 -0
- package/dist/runtime/server/utility/index.d.ts +2 -0
- package/dist/runtime/server/utility/index.js +2 -0
- package/dist/runtime/tsconfig.json +3 -0
- package/dist/runtime/utility/fetchError.d.ts +28 -0
- package/dist/runtime/utility/fetchError.js +4 -0
- package/dist/runtime/utility/index.d.ts +1 -0
- package/dist/runtime/utility/index.js +1 -0
- package/dist/types.d.mts +3 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Authenticate Module
|
|
2
|
+
|
|
3
|
+
Módulo interno de autenticación para microservicios Nuxt de la empresa. Proporciona una solución unificada para el manejo de autenticación de usuarios, sesiones y tokens a través de múltiples microservicios.
|
|
4
|
+
|
|
5
|
+
[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [![License][license-src]][license-href] [![Nuxt][nuxt-src]][nuxt-href]
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Objetivo
|
|
10
|
+
|
|
11
|
+
Un módulo para Nuxt que facilita la autenticación de usuarios en tus aplicaciones, con un enfoque de inversión de dependencias: el módulo no obliga a una conexión directa a una base de datos. En lugar de ello, expone contratos (repositorios y proveedores) que la aplicación anfitriona puede inyectar (por ejemplo: `getUserRepository`, `getSessionRepository`). Esto permite reemplazar la implementación de almacenamiento (Prisma, MSSQL, in-memory, etc.) sin modificar el módulo.
|
|
12
|
+
|
|
13
|
+
El diseño busca estandarizar la autenticación entre microservicios manteniendo independencia de la infraestructura de datos, facilitando pruebas y despliegues.
|
|
14
|
+
|
|
15
|
+
- [✨ Notas de Lanzamiento](/CHANGELOG.md)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Características
|
|
20
|
+
|
|
21
|
+
- 🔐 **Autenticación unificada**: Sistema de registro e inicio de sesión consistente entre microservicios.
|
|
22
|
+
- 🛡️ **Protección de rutas**: Middleware para asegurar endpoints y rutas protegidas.
|
|
23
|
+
- 🔑 **Gestión de tokens JWT**: Generación, validación y manejo centralizado de tokens.
|
|
24
|
+
- 👤 **Manejo de sesiones**: Control de sesiones activas y cierre seguro de sesión.
|
|
25
|
+
- 🏗️ **Arquitectura modular**: Diseñado para ser reutilizado en múltiples microservicios.
|
|
26
|
+
- 📊 **Historial de usuarios**: Seguimiento de cambios y auditoría de usuarios.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Instalación
|
|
31
|
+
|
|
32
|
+
Instala el módulo en tu aplicación Nuxt con el siguiente comando:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install authenticate-module
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Si está en un repositorio interno:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git submodule add <repository-url> modules/authenticate-module
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Configuración
|
|
47
|
+
|
|
48
|
+
### 1. Configuración de Nuxt
|
|
49
|
+
|
|
50
|
+
Agrega el módulo a tu configuración de Nuxt en `nuxt.config.ts`:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
export default defineNuxtConfig({
|
|
54
|
+
modules: ['./modules/authenticate-module/src/module'],
|
|
55
|
+
authenticateModule: {
|
|
56
|
+
enabled: true, // Habilita o deshabilita el módulo
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Variables de Entorno
|
|
62
|
+
|
|
63
|
+
Configura las siguientes variables en tu archivo `.env`. Nota: `DATABASE_URL` es opcional si proporcionas repositorios personalizados; el módulo no requiere una conexión a la base de datos por defecto.
|
|
64
|
+
|
|
65
|
+
```env
|
|
66
|
+
# Base de datos (SQL Server) — Opcional si provees repositorios
|
|
67
|
+
DATABASE_URL="sqlserver://servidor:puerto;database=nombre_db;user=usuario;password=contraseña;encrypt=true"
|
|
68
|
+
|
|
69
|
+
# Clave secreta para JWT — Requerida
|
|
70
|
+
JWT_SECRET="tu_clave_secreta_super_segura"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Inversión de Dependencias
|
|
74
|
+
|
|
75
|
+
El módulo está diseñado para recibir implementaciones de repositorios y proveedores desde la aplicación que lo usa. Proporciona utilidades en `runtime/utility` (`getUserRepository`, `getSessionRepository`) como contratos por defecto. Puedes inyectar tus implementaciones en la configuración del módulo o a través de composables/servicios en runtime.
|
|
76
|
+
|
|
77
|
+
Ejemplo (inyección en `nuxt.config.ts`):
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
export default defineNuxtConfig({
|
|
81
|
+
modules: ['./modules/authenticate-module/src/module'],
|
|
82
|
+
authenticateModule: {
|
|
83
|
+
providers: {
|
|
84
|
+
userRepository: () => createMyUserRepository(),
|
|
85
|
+
sessionRepository: () => createMySessionRepository(),
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Si no se proporcionan proveedores, el módulo puede usar la implementación incluida (Prisma) si está disponible.
|
|
92
|
+
|
|
93
|
+
### Inyección vía Middleware
|
|
94
|
+
|
|
95
|
+
La inyección de dependencias en este módulo se realiza típicamente desde un middleware que adjunta las implementaciones de repositorios al contexto de los eventos. En el playground existe un ejemplo en `playground/server/middleware/auth/inject-repository.ts` que muestra cómo resolver proveedores y exponerlos en `event.context`.
|
|
96
|
+
|
|
97
|
+
Ejemplo de middleware (simplificado):
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
export default defineEventHandler(async (event) => {
|
|
101
|
+
const cfg = useRuntimeConfig().authenticateModule || {}
|
|
102
|
+
const providers = cfg.providers || {}
|
|
103
|
+
|
|
104
|
+
const userRepository = typeof providers.userRepository === 'function'
|
|
105
|
+
? providers.userRepository()
|
|
106
|
+
: providers.userRepository
|
|
107
|
+
|
|
108
|
+
const sessionRepository = typeof providers.sessionRepository === 'function'
|
|
109
|
+
? providers.sessionRepository()
|
|
110
|
+
: providers.sessionRepository
|
|
111
|
+
|
|
112
|
+
event.context.userRepository = userRepository
|
|
113
|
+
event.context.sessionRepository = sessionRepository
|
|
114
|
+
})
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Los controladores y servicios del módulo pueden entonces obtener los repositorios desde `event.context` o usando los helpers del runtime (`getUserRepository`, `getSessionRepository`) que consultan ese contexto.
|
|
118
|
+
|
|
119
|
+
### 3. Configuración de Prisma
|
|
120
|
+
|
|
121
|
+
Si decides usar la implementación incluida basada en Prisma, ejecuta las migraciones de la base de datos:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npx prisma migrate deploy
|
|
125
|
+
npx prisma generate
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Si en su lugar inyectas repositorios personalizados (p. ej. el microservicio comparte su propio cliente), no es necesario ejecutar estas migraciones para que el módulo funcione.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Uso
|
|
133
|
+
|
|
134
|
+
### Rutas de Autenticación
|
|
135
|
+
|
|
136
|
+
El módulo registra automáticamente las siguientes rutas en tu servidor:
|
|
137
|
+
|
|
138
|
+
- **POST** `/api/auth/register`: Registro de nuevos usuarios.
|
|
139
|
+
- **POST** `/api/auth/login`: Inicio de sesión y generación de tokens.
|
|
140
|
+
- **POST** `/api/auth/session`: Validación de sesiones activas.
|
|
141
|
+
- **POST** `/api/auth/closeSession`: Cierre de sesión.
|
|
142
|
+
|
|
143
|
+
### Ejemplo de Uso en Microservicio
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Ejemplo de registro de usuario desde el frontend
|
|
147
|
+
const registrarUsuario = async () => {
|
|
148
|
+
const userData = {
|
|
149
|
+
userName: 'empleado123',
|
|
150
|
+
password: 'contraseñaSegura123',
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const response = await $fetch('/api/auth/register', {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
body: userData,
|
|
157
|
+
})
|
|
158
|
+
console.log('Usuario registrado:', response)
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error('Error en registro:', error)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Ejemplo de inicio de sesión
|
|
165
|
+
const iniciarSesion = async () => {
|
|
166
|
+
const loginData = {
|
|
167
|
+
userName: 'empleado123',
|
|
168
|
+
password: 'contraseñaSegura123',
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const response = await $fetch('/api/auth/login', {
|
|
173
|
+
method: 'POST',
|
|
174
|
+
body: loginData,
|
|
175
|
+
})
|
|
176
|
+
const token = response.token
|
|
177
|
+
console.log('Token recibido:', token)
|
|
178
|
+
} catch (error) {
|
|
179
|
+
console.error('Error en login:', error)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Integración entre Microservicios
|
|
187
|
+
|
|
188
|
+
### Validación de Tokens entre Servicios
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Middleware para validar tokens en rutas protegidas
|
|
192
|
+
export default defineEventHandler(async (event) => {
|
|
193
|
+
const token = getCookie(event, 'auth-token') || getHeader(event, 'authorization')
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
// `authToken` puede ser la implementación incluida o una función que use
|
|
197
|
+
// `event.context.sessionRepository`/`userRepository` inyectados por middleware.
|
|
198
|
+
const isValid = await authToken(token)
|
|
199
|
+
if (!isValid) {
|
|
200
|
+
throw createError({
|
|
201
|
+
statusCode: 401,
|
|
202
|
+
statusMessage: 'Token inválido'
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw createError({
|
|
207
|
+
statusCode: 401,
|
|
208
|
+
statusMessage: 'No autorizado'
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Desarrollo y Pruebas
|
|
217
|
+
|
|
218
|
+
El módulo incluye un conjunto completo de pruebas unitarias utilizando **Vitest**:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Ejecutar todas las pruebas
|
|
222
|
+
npm run test
|
|
223
|
+
|
|
224
|
+
# Ejecutar pruebas en modo watch
|
|
225
|
+
npm run test:watch
|
|
226
|
+
|
|
227
|
+
# Ejecutar pruebas con coverage
|
|
228
|
+
npm run test:coverage
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Estructura del Proyecto
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
authenticate-module/
|
|
237
|
+
├── src/
|
|
238
|
+
│ ├── module.ts # Configuración principal del módulo
|
|
239
|
+
│ └── runtime/
|
|
240
|
+
│ └── server/
|
|
241
|
+
│ ├── api/auth/ # Endpoints de autenticación
|
|
242
|
+
│ ├── middleware/ # Middleware de validación
|
|
243
|
+
│ └── modules/ # Lógica de negocio modular
|
|
244
|
+
├── test/ # Pruebas unitarias completas
|
|
245
|
+
├── prisma/ # Esquemas y migraciones de BD
|
|
246
|
+
├── playground/ # Ejemplo de implementación
|
|
247
|
+
└── README.md # Esta documentación
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Esquema de Base de Datos
|
|
253
|
+
|
|
254
|
+
El módulo incluye un esquema de ejemplo para Prisma (SQL Server). Estos modelos son parte de la implementación opcional con Prisma; si inyectas tus propios repositorios, puedes adaptar el esquema a tu almacenamiento. Los modelos principales incluyen:
|
|
255
|
+
|
|
256
|
+
### Modelo User
|
|
257
|
+
|
|
258
|
+
```prisma
|
|
259
|
+
model User {
|
|
260
|
+
id Int @id @default(autoincrement())
|
|
261
|
+
userName String @unique @db.VarChar(50)
|
|
262
|
+
password String // Encriptada con bcrypt
|
|
263
|
+
createdAt DateTime @default(now())
|
|
264
|
+
updatedAt DateTime @updatedAt
|
|
265
|
+
enable Boolean @default(true)
|
|
266
|
+
|
|
267
|
+
sessions Session[] // Sesiones activas
|
|
268
|
+
userHistory UserHistory[] // Historial de cambios
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Modelo Session
|
|
273
|
+
|
|
274
|
+
```prisma
|
|
275
|
+
model Session {
|
|
276
|
+
id Int @id @default(autoincrement())
|
|
277
|
+
userId Int
|
|
278
|
+
token String @unique @db.VarChar(255)
|
|
279
|
+
ipAddress String? // IP de origen
|
|
280
|
+
userAgent String? // Navegador/dispositivo
|
|
281
|
+
createdAt DateTime @default(now())
|
|
282
|
+
expiresAt DateTime? // Expiración del token
|
|
283
|
+
|
|
284
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Seguridad
|
|
291
|
+
|
|
292
|
+
- **Encriptación de contraseñas**: Uso de bcrypt con salt rounds configurables
|
|
293
|
+
- **Tokens JWT**: Firmados con clave secreta robusta
|
|
294
|
+
- **Validación de entrada**: Sanitización de datos de usuario
|
|
295
|
+
- **Auditoría**: Registro de cambios en UserHistory
|
|
296
|
+
- **Expiración de sesiones**: Control de tiempo de vida de tokens
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Mantenimiento
|
|
301
|
+
|
|
302
|
+
### Actualizaciones del Módulo
|
|
303
|
+
|
|
304
|
+
Para actualizar el módulo en tus microservicios:
|
|
305
|
+
|
|
306
|
+
1. **Hacer pull** de los cambios más recientes
|
|
307
|
+
2. **Ejecutar migraciones** si hay cambios en la BD:
|
|
308
|
+
```bash
|
|
309
|
+
npx prisma migrate deploy
|
|
310
|
+
```
|
|
311
|
+
3. **Regenerar el cliente** Prisma:
|
|
312
|
+
```bash
|
|
313
|
+
npx prisma generate
|
|
314
|
+
```
|
|
315
|
+
4. **Ejecutar pruebas** para validar la integración:
|
|
316
|
+
```bash
|
|
317
|
+
npm run test
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Soporte y Documentación
|
|
323
|
+
|
|
324
|
+
Para dudas sobre la implementación o problemas con el módulo:
|
|
325
|
+
- Revisar los tests para ejemplos de uso
|
|
326
|
+
- Consultar la documentación del código
|
|
327
|
+
- Contactar al equipo de desarrollo interno
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
**Desarrollado para uso interno empresarial** - Este módulo está diseñado específicamente para la arquitectura de microservicios de la empresa y no está destinado para distribución pública.
|
|
332
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface ModuleOptions {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
8
|
+
|
|
9
|
+
export { _default as default };
|
|
10
|
+
export type { ModuleOptions };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, addComponentsDir, addImportsDir, addServerHandler, addRouteMiddleware, addTypeTemplate } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
const apiRoutes = [
|
|
4
|
+
{ route: "/api/auth/login", handler: "auth/login.post" },
|
|
5
|
+
{ route: "/api/auth/register", handler: "auth/register.post" },
|
|
6
|
+
{ route: "/api/auth/closeSession", handler: "auth/closeSession.post" }
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const pageRoutes = [
|
|
10
|
+
{ name: "user-login", path: "/login", file: "UserLogin.vue" },
|
|
11
|
+
{ name: "user-register", path: "/register", file: "UserRegister.vue" }
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
function nuxtConfigAlias(nuxt, alias) {
|
|
15
|
+
nuxt.options.alias = nuxt.options.alias || {};
|
|
16
|
+
nuxt.options.alias = nuxt.options.alias || {};
|
|
17
|
+
nuxt.options.alias = {
|
|
18
|
+
...nuxt.options.alias,
|
|
19
|
+
...alias
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const module$1 = defineNuxtModule({
|
|
24
|
+
meta: {
|
|
25
|
+
name: "authenticate-module",
|
|
26
|
+
configKey: "authenticateModule"
|
|
27
|
+
},
|
|
28
|
+
// Configuración por defecto del módulo de autenticación
|
|
29
|
+
defaults: {
|
|
30
|
+
enabled: true
|
|
31
|
+
},
|
|
32
|
+
async setup(options, nuxt) {
|
|
33
|
+
if (!options.enabled) return;
|
|
34
|
+
const { resolve } = createResolver(import.meta.url);
|
|
35
|
+
nuxtConfigAlias(nuxt, {
|
|
36
|
+
modules: resolve("./runtime/server/modules"),
|
|
37
|
+
utility: resolve("./runtime/server/utility"),
|
|
38
|
+
service: resolve("./runtime/server/service")
|
|
39
|
+
});
|
|
40
|
+
addComponentsDir({
|
|
41
|
+
path: resolve("./runtime/components"),
|
|
42
|
+
prefix: options.prefix || "Auth"
|
|
43
|
+
});
|
|
44
|
+
addImportsDir(resolve("./runtime/composable"));
|
|
45
|
+
addServerHandler({
|
|
46
|
+
handler: resolve("./runtime/server/middleware/session.ts"),
|
|
47
|
+
middleware: true
|
|
48
|
+
});
|
|
49
|
+
apiRoutes.forEach(({ route, handler }) => {
|
|
50
|
+
addServerHandler({
|
|
51
|
+
route,
|
|
52
|
+
handler: resolve(`./runtime/server/api/${handler}`)
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
addRouteMiddleware({
|
|
56
|
+
name: "protected",
|
|
57
|
+
path: resolve("./runtime/middleware/protected.ts"),
|
|
58
|
+
global: false
|
|
59
|
+
});
|
|
60
|
+
nuxt.hook("pages:extend", (pages) => {
|
|
61
|
+
pageRoutes.forEach(({ name, path, file }) => {
|
|
62
|
+
pages.push({
|
|
63
|
+
name,
|
|
64
|
+
// Nombre de la ruta
|
|
65
|
+
path,
|
|
66
|
+
// Ruta de la página en la aplicación
|
|
67
|
+
file: resolve(`./runtime/page/${file}`)
|
|
68
|
+
// Componente asociado
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
addTypeTemplate({
|
|
73
|
+
filename: "types/auth.d.ts",
|
|
74
|
+
src: resolve("./runtime/server/types/auth.d.ts")
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export { module$1 as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";@import "@nuxt/ui";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useUserSession } from "#imports";
|
|
3
|
+
const { closeSession } = useCloseSession();
|
|
4
|
+
const { user } = useUserSession();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div class="flex items-center gap-4">
|
|
9
|
+
<UUser
|
|
10
|
+
:name="user?.name"
|
|
11
|
+
:description="`Id de sesi\xF3n: ${user?.sessionId}`"
|
|
12
|
+
:avatar="{
|
|
13
|
+
icon: 'material-symbols:account-circle'
|
|
14
|
+
}"
|
|
15
|
+
chip
|
|
16
|
+
size="xl"
|
|
17
|
+
/>
|
|
18
|
+
<UTooltip
|
|
19
|
+
text="Cerrar sesión"
|
|
20
|
+
>
|
|
21
|
+
<UButton
|
|
22
|
+
class="cursor-pointer"
|
|
23
|
+
icon="majesticons:logout"
|
|
24
|
+
color="error"
|
|
25
|
+
@click="closeSession"
|
|
26
|
+
/>
|
|
27
|
+
</UTooltip>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function useCloseSession() {
|
|
2
|
+
async function closeSession() {
|
|
3
|
+
const response = await $fetch("/api/auth/closeSession", {
|
|
4
|
+
method: "POST"
|
|
5
|
+
});
|
|
6
|
+
useToast().add({
|
|
7
|
+
title: "Sesi\xF3n cerrada con \xE9xito",
|
|
8
|
+
description: response.message
|
|
9
|
+
});
|
|
10
|
+
await navigateTo("/login");
|
|
11
|
+
}
|
|
12
|
+
return { closeSession };
|
|
13
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
import { useFetchError } from "../utility";
|
|
4
|
+
const { fetch: refreshSession } = useUserSession();
|
|
5
|
+
function getDefaultUser() {
|
|
6
|
+
const userName = useCookie("rememberedUserName");
|
|
7
|
+
return userName.value || "";
|
|
8
|
+
}
|
|
9
|
+
const fields = [{
|
|
10
|
+
name: "userName",
|
|
11
|
+
type: "text",
|
|
12
|
+
label: "Nombre de usuario",
|
|
13
|
+
placeholder: "Ingresa tu nombre de usuario",
|
|
14
|
+
required: true,
|
|
15
|
+
defaultValue: getDefaultUser()
|
|
16
|
+
}, {
|
|
17
|
+
name: "password",
|
|
18
|
+
label: "Contrase\xF1a",
|
|
19
|
+
type: "password",
|
|
20
|
+
placeholder: "Ingresa tu contrase\xF1a",
|
|
21
|
+
required: true
|
|
22
|
+
}, {
|
|
23
|
+
name: "remember",
|
|
24
|
+
label: "Recu\xE9rdame",
|
|
25
|
+
type: "checkbox",
|
|
26
|
+
defaultValue: !!getDefaultUser()
|
|
27
|
+
}];
|
|
28
|
+
const schema = z.object({
|
|
29
|
+
userName: z.string("Nombre de usuario requerido para iniciar sesi\xF3n"),
|
|
30
|
+
password: z.string("Debe introducir su contrase\xF1a para iniciar sesi\xF3n"),
|
|
31
|
+
remember: z.boolean().optional()
|
|
32
|
+
});
|
|
33
|
+
const errorRef = useFetchError();
|
|
34
|
+
async function onSubmit(payload) {
|
|
35
|
+
try {
|
|
36
|
+
const { user } = await $fetch("/api/auth/login", {
|
|
37
|
+
method: "POST",
|
|
38
|
+
body: {
|
|
39
|
+
userName: payload.data.userName,
|
|
40
|
+
password: payload.data.password
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
await refreshSession();
|
|
44
|
+
useToast().add({
|
|
45
|
+
title: "Inicio de sesi\xF3n exitoso",
|
|
46
|
+
icon: "material-symbols:bookmark-check-rounded",
|
|
47
|
+
description: `Bienvenido ${user}`
|
|
48
|
+
});
|
|
49
|
+
const userName = useCookie("rememberedUserName");
|
|
50
|
+
if (payload.data.remember) {
|
|
51
|
+
userName.value = payload.data.userName;
|
|
52
|
+
} else {
|
|
53
|
+
userName.value = "";
|
|
54
|
+
}
|
|
55
|
+
await navigateTo("/");
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const fetchError = error;
|
|
58
|
+
errorRef.value = fetchError;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<div
|
|
65
|
+
class="flex items-center justify-center"
|
|
66
|
+
:style="{ height: '100vh' }"
|
|
67
|
+
>
|
|
68
|
+
<UPageCard class="w-full max-w-md">
|
|
69
|
+
<UAuthForm
|
|
70
|
+
:schema="schema"
|
|
71
|
+
:fields="fields"
|
|
72
|
+
title="Iniciar sesión"
|
|
73
|
+
icon="i-lucide-lock"
|
|
74
|
+
:submit="{
|
|
75
|
+
label: 'Iniciar Sesion',
|
|
76
|
+
class: 'cursor-pointer'
|
|
77
|
+
}"
|
|
78
|
+
@submit="onSubmit"
|
|
79
|
+
>
|
|
80
|
+
<template #description>
|
|
81
|
+
Inicio de sesión, sistema de Salva Mar SA
|
|
82
|
+
</template>
|
|
83
|
+
<template #validation>
|
|
84
|
+
<UAlert
|
|
85
|
+
v-if="errorRef"
|
|
86
|
+
color="error"
|
|
87
|
+
icon="i-lucide-info"
|
|
88
|
+
:title="`Error ${errorRef.statusCode}`"
|
|
89
|
+
:description="errorRef.data.message"
|
|
90
|
+
/>
|
|
91
|
+
</template>
|
|
92
|
+
<template #footer>
|
|
93
|
+
<div class="flex flex-col gap-1">
|
|
94
|
+
<ULink
|
|
95
|
+
to="/register"
|
|
96
|
+
class="text-primary font-medium"
|
|
97
|
+
>Registrar usuario</ULink>.
|
|
98
|
+
<UBadge
|
|
99
|
+
variant="subtle"
|
|
100
|
+
color="warning"
|
|
101
|
+
size="lg"
|
|
102
|
+
>
|
|
103
|
+
<span class="text-center">
|
|
104
|
+
Si olvidó la contraseña contacte al administrador del sistema
|
|
105
|
+
</span>
|
|
106
|
+
</UBadge>
|
|
107
|
+
</div>
|
|
108
|
+
</template>
|
|
109
|
+
</UAuthForm>
|
|
110
|
+
</UPageCard>
|
|
111
|
+
</div>
|
|
112
|
+
</template>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|