aloux-iam 0.0.144 → 0.0.146

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 CHANGED
@@ -1,272 +1,311 @@
1
- # Aloux IAM
1
+ # aloux-iam
2
2
 
3
- Uso de esta librearía para administración de menus, privilegios, funciones, usuarios y envio de notificaciones por medio de correos y mensajes de texto
3
+ Librería Node.js para gestión de identidad y acceso (IAM) en APIs Express + MongoDB.
4
4
 
5
- ## Installation
5
+ ## Instalación
6
6
 
7
7
  ```bash
8
- $ npm install aloux-iam --save
8
+ npm install aloux-iam
9
9
  ```
10
10
 
11
-
12
- ## Usage
13
- En archivo `init.js`
11
+ ## Configuración básica
14
12
 
15
13
  ```js
16
- // Require
17
- const { IAMRouter, IAMSwagger } = require('aloux-iam')
14
+ const express = require('express')
15
+ const mongoose = require('mongoose')
16
+ const cookieParser = require('cookie-parser')
17
+ const { IAMRouter } = require('aloux-iam')
18
18
 
19
+ const app = express()
19
20
 
21
+ app.use(express.json())
22
+ app.use(cookieParser())
20
23
  app.use(IAMRouter)
21
24
 
22
- // swagger
23
- app.use(
24
- "/aloux-iam",
25
- swaggerUI.serveFiles(IAMswagger, {}),
26
- swaggerUI.setup(IAMswagger)
27
- )
28
-
29
- // URL Swagger
30
- // [BASE_URL]/docs-iam/#/default/
31
-
25
+ mongoose.connect(process.env.MONGO_URI)
26
+ app.listen(3000)
32
27
  ```
33
28
 
34
-
35
- En archivo `router.js`
29
+ ### Proteger tus propias rutas
36
30
 
37
31
  ```js
38
- // Require
39
32
  const { IAMAuth } = require('aloux-iam')
40
33
 
41
- // Example
42
- router.post('/customer', IAMAuth, customer.create)
34
+ app.get('/api/mi-recurso', IAMAuth, (req, res) => {
35
+ // req.user → usuario autenticado con funciones y permisos
36
+ // req.token → JWT string
37
+ res.json({ user: req.user })
38
+ })
43
39
  ```
44
40
 
45
- ## Variables de entorno
41
+ ### Swagger
46
42
 
47
- Requiere las siguientes variables de entorno (.env)
48
-
49
- | Variable | Description |
50
- | ----------------------|---------------|
51
- | AUTH_SECRET | Required, para cifrar la contraseña |
52
- | AWS_SECRET_ACCESS_KEY | Required, para acceso a S3 y SES AWS. |
53
- | AWS_ACCESS_KEY_ID | Required, para acceso a S3 y SES AWS. |
54
- | AWS_REGION | Required, para acceso a S3 y SES AWS. |
55
- | AWS_BUCKET | Required, para guardar la foto de perfil en AWS. |
56
- | AWS_EMAIL_SENDER | Required, para mandar el correo de recuperación de contraseña |
57
- | DEBUG | Required, para validar si el ambiente es dev o PROD |
58
- | SWAGGER_SERVER | Required, para acceder al swagger de IAM |
59
- | MASTER_PWD | Optional, para utilizar contraseña maestra de usuarios en desarrollo |
60
- | BASE_URL | Optional, para swagger |
61
-
62
-
63
- ## Endpoints disponibles
64
-
65
- ### Endpoints user self (no auth)
66
-
67
- | Method | Endpoint | Description |
68
- | --------- | --------------------------|---------------|
69
- | POST | iam/auth/email | Validar correo |
70
- | POST | iam/auth/login | Iniciar sesión |
71
- | POST | iam/auth/forgot/password | Enviar código a correo |
72
- | POST | iam/auth/validate/code | Verificar código |
73
- | POST | iam/auth/verify/mail | Verificar correo |
74
- | GET | iam/auth/verify/mail/token/:token | Valida correo (Manda correo de bienvenida) |
75
- | POST | iam/auth/reset/password | Reestablecer contraseña |
76
- | POST | iam/auth/signup | Registrarse |
77
-
78
-
79
- ### Endpoints user self
80
-
81
- | Method | Endpoint | Description |
82
- | --------- | --------------------------|---------------|
83
- | GET | iam/auth/me | Obtener información de usuario autenticado |
84
- | PUT | iam/auth/profile | Actualizar perfil |
85
- | PUT | iam/auth/profile/pictura | Actualizar solo la foto de perfil |
86
- | PUT | iam/auth/reset/password | Actualizar contraseña |
87
- | POST | iam/auth/send/verify/phone | Enviar código al teléfono de la cuenta para verificarla |
88
- | POST | iam/auth/verify/phone | Valida teléfono del usuario de la cuenta |
89
- | POST | iam/auth/logout | Cerrar sesión |
90
-
91
-
92
- ### Endpoints user
93
-
94
- | Method | Endpoint | Description |
95
- | --------- | ------------------------------|----------------|
96
- | POST | iam/user | Crear usuario |
97
- | GET | iam/user | Obtener todos los usuario |
98
- | GET | iam/user/:USER_ID | Obtener detalle de usuario |
99
- | PUT | iam/user/:USER_ID | Actualizar usuario |
100
- | PUT | iam/user/:USER_ID/status | Activar o desactivar usuario |
101
- | PUT | iam/user/password/:USER_ID | Actualizar la constraseña de un usuario |
102
- | DELETE | iam/user/:USER_ID | Eliminar usuario |
103
- | GET | iam/user/count/all | Obtiene el número de usuarios |
104
-
105
-
106
- ### Endpoints funtions
107
-
108
- | Method | Endpoint | Description |
109
- | --------- | --------------------------------------|----------------|
110
- | POST | iam/functions | Crear función |
111
- | PUT | iam/functions/:FUNCTION_ID | Actualizar función |
112
- | PUT | iam/functions/:FUNCTION_ID/status | Activar o desactivar función |
113
- | GET | iam/functions | Obtener todas las funciones |
114
- | GET | iam/functions/:FUNCTION_ID | Obtener detalle de la función |
115
- | DELETE | iam/functions/:FUNCTION_ID | Eliminar función |
116
- | GET | iam/functions/count/all | Obtiene el número de funciones |
117
-
118
-
119
- ### Endpoints permission
120
-
121
- | Method | Endpoint | Description |
122
- | --------- | ------------------------------------------|---------------|
123
- | POST | iam/permission | Crear permiso
124
- | PUT | iam/permission/:PERMISSION_ID | Actualizar permiso |
125
- | PUT | iam/permission/:PERMISSION_ID/status | Activar o desactivar permiso |
126
- | GET | iam/permission | Obtener todas los permisos |
127
- | GET | iam/permission/:PERMISSION_ID | Obtener detalle de la permiso |
128
- | DELETE | iam/permission/:PERMISSION_ID | Eliminar permiso |
129
- | GET | iam/permission/count/all | Obtiene el número de permisos |
130
-
131
-
132
- ### Endpoints menu
133
-
134
- | Method | Endpoint | Description |
135
- | --------- | --------------------------|---------------|
136
- | POST | /iam/menu | Crea un elemento de menú |
137
- | PUT | /iam/menu/:MENU_ID | Actualiza un elemento de menú |
138
- | PUT | /iam/menu/:MENU_ID/status | Activa o desactiva un menú |
139
- | GET | /iam/menu | Obtiene todos los elementos de menú |
140
- | GET | /iam/menu/:MENU_ID | Obtiene el detalle de un elemento de menú |
141
- | DELETE | /iam/menu/:MENU_ID | Elimina un elemento de menú |
142
- | POST | /iam/menu/order | Ordena los elementos de menú |
143
- | GET | iam/menu/count | Obtiene el número de menús |
144
-
145
-
146
- ## Aloux-AWS
147
- #### Aggregate file
148
43
  ```js
149
- // Require
150
- const { AlouxAWS } = require('aloux-iam')
151
-
152
-
153
- // variables
154
- /*
155
- * AWS_REGION
156
- * AWS_BUCKET
157
- */
158
-
159
- /**
160
- * pathFile = folder/file_name-file_id
161
- * file = req.files.property
162
- */
163
- // a constant is created to save the new element
164
- const result = await AlouxAWS.upload('folder/file_name', req.files.data)
44
+ const swaggerUI = require('swagger-ui-express')
45
+ const { IAMSwagger } = require('aloux-iam')
165
46
 
47
+ app.use('/docs-iam', swaggerUI.serveFiles(IAMSwagger, {}), swaggerUI.setup(IAMSwagger))
166
48
  ```
167
49
 
168
- #### Eliminate many files
169
- ```js
170
- // Require
171
- const { AlouxAWS } = require('aloux-iam')
50
+ ## Integración con aloux-cloud
172
51
 
173
-
174
- // variables
175
- /*
176
- * AWS_REGION
177
- * AWS_BUCKET
178
- */
179
-
180
- /**
181
- * files = [{key: 'folder/file1'},{key: 'folder/file1'}]
182
- */
183
- // delete selected files
184
- const files = [{key: 'folder/file1.png'},{key: 'folder/file1.png'}]
185
- const deleteFiles = await AlouxAWS.deleteMany(files)
186
-
187
- ```
188
-
189
- #### Eliminate file
190
52
  ```js
191
- // Require
192
- const { AlouxAWS } = require('aloux-iam')
193
-
194
-
195
- // variables
196
- /*
197
- * AWS_REGION
198
- * AWS_BUCKET
199
- */
200
-
201
- /**
202
- * file = folder/file_name
203
- */
204
- // delete the file
205
- const file = 'folder/file_name.png'
206
- const deleteFile = await AlouxAWS.delete(file)
207
-
53
+ const iam = require('aloux-iam')
54
+ const cloud = require('aloux-cloud')
55
+
56
+ iam.init({
57
+ email: cloud.ses,
58
+ sms: cloud.sns,
59
+ storage: cloud.s3,
60
+ analytics: cloud.bigQuery,
61
+ })
208
62
  ```
209
63
 
210
- ### Usage for emails
211
- #### Send email
212
- ```js
213
- // Require
214
- const { AlouxAWS } = require('aloux-iam')
215
-
216
-
217
- // variables
218
- /*
219
- * AWS_REGION
220
- * AWS_EMAIL_SENDER
221
- */
222
-
223
- /**
224
- * email: Destination email
225
- * message: Mail body
226
- * subject: Mail subject
227
- */
228
- // a constant is created to request the data from the req.body.
229
- const { email, message, subject } = req.body
230
- const sendEmail = await AlouxAWS.sendCustom(email, message, subject)
231
-
232
- // example of the messages variable
233
- // this variable must be sent as a string if you want to send modified HTML
234
- /*
235
-
236
- message: "<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'><title>Document</title></head><body><h1>Information</h1></body></html>"
237
-
238
- */
64
+ Cada provider es opcional. Si no se configura, el IAM funciona sin ese servicio.
239
65
 
66
+ ## Variables de entorno
240
67
 
68
+ ### Requeridas
69
+
70
+ | Variable | Descripción |
71
+ |----------|-------------|
72
+ | `AUTH_SECRET` | Clave secreta para firmar JWT |
73
+ | `MONGO_URI` | URI de conexión a MongoDB |
74
+
75
+ ### Sesión y autenticación
76
+
77
+ | Variable | Default | Descripción |
78
+ |----------|---------|-------------|
79
+ | `SESSION_TIME` | — | Duración del token en minutos |
80
+ | `MAX_TOKENS` | `5` | Sesiones activas simultáneas por usuario |
81
+ | `FAILED_ATTEMPS` | `5` | Intentos fallidos antes de bloquear la cuenta |
82
+ | `SESSION_INTERRUPTOR` | — | Si `true`, valida expiración en cada request |
83
+ | `SERVICE_ACCOUNT_TTL_DAYS` | permanente | Días de vida del token de cuentas de servicio |
84
+ | `DEBUG` | — | Si `true`, activa `MASTER_PWD` y URL de Swagger |
85
+ | `MASTER_PWD` | — | Contraseña maestra que omite bcrypt (requiere `DEBUG=true`) |
86
+ | `SWAGGER_SERVER` | — | URL del servidor en Swagger cuando `DEBUG=true` |
87
+
88
+ ### Emails (requiere provider `email`)
89
+
90
+ | Variable | Descripción |
91
+ |----------|-------------|
92
+ | `SEND_EMAIL_USER` | Si `true`, envía credenciales al crear usuario admin |
93
+ | `SUBJECT_EMAIL` | Asunto por defecto de los emails |
94
+ | `CHANGE_PWD` | Si `true`, fuerza cambio de contraseña en primer login |
95
+ | `VERIFY_ACCOUNT_URL` | URL base para verificación de cuenta |
96
+ | `URL_VERIFY_EMAIL` | URL para confirmar cambio de email |
97
+ | `TEMPLATE_ACCOUNT` | Path al template HTML de credenciales |
98
+ | `TEMPLATE_RECOVER_PASSWORD` | Path al template HTML de recuperación |
99
+ | `TEMPLATE_VERIFY_EMAIL` | Path al template HTML de verificación |
100
+ | `TEMPLATE_WELCOME` | Path al template HTML de bienvenida |
101
+ | `TEMPLATE_CHANGE_MAIL` | Path al template HTML de cambio de email |
102
+
103
+ ### Branding y multi-app
104
+
105
+ | Variable | Descripción |
106
+ |----------|-------------|
107
+ | `APP` | Identificador de app para templates con sufijo |
108
+ | `PROJECT_NAME` | Nombre de la app en templates y SMS |
109
+ | `PROJECT_URL` | URL del proyecto en SMS de verificación |
110
+ | `BRAND_COLOR` | Color principal para templates de email |
111
+ | `BRAND_LOGO` | URL del logo para templates de email |
112
+ | `FUNCTION_NAME` | Función asignada por defecto al hacer signup |
113
+
114
+ ### Historial
115
+
116
+ | Variable | Descripción |
117
+ |----------|-------------|
118
+ | `HISTORY` | Si `true`, registra historial de acciones |
119
+ | `HISTORY_ENDPOINTS` | Paths separados por coma a registrar |
120
+
121
+ ### Analytics (requiere provider `analytics`)
122
+
123
+ | Variable | Descripción |
124
+ |----------|-------------|
125
+ | `UPLOAD_CUSTOMER` | Si `true`, inserta nuevos usuarios en BigQuery |
126
+ | `UPLOAD_CUSTOMER_TABLE` | Tabla de BigQuery donde insertar |
127
+
128
+ ## Exportaciones
129
+
130
+ | Export | Tipo | Descripción |
131
+ |--------|------|-------------|
132
+ | `IAMRouter` | Express Router | Monta todos los endpoints `/iam/*` |
133
+ | `IAMAuth` | Middleware | Autenticación JWT para tus rutas |
134
+ | `IAMSwagger` | Object | Spec OpenAPI lista para swagger-ui-express |
135
+ | `IAMUserModel` | Mongoose Model | Modelo User |
136
+ | `IAMUserBusiness` | Mongoose Model | Modelo Business |
137
+ | `IAMFunctionsModel` | Mongoose Model | Modelo Functions |
138
+ | `IAMPermissionModel` | Mongoose Model | Modelo Permission |
139
+ | `IAMMenuModel` | Mongoose Model | Modelo Menu |
140
+ | `AlouxHistory` | Service | Controlador de historial |
141
+ | `init` | Function | Registra providers de aloux-cloud |
142
+
143
+ ## Flujos de creación de usuarios
144
+
145
+ ### Signup público — `POST /iam/auth/signup`
146
+ El usuario se registra solo. Requiere `email` y `pwd`. Se le asigna la función definida en `FUNCTION_NAME`.
147
+
148
+ ### Usuario administrado — `POST /iam/user`
149
+ Un admin crea el usuario. Requiere `email` y `pwd`. Permite asignar funciones, empresas y negocios.
150
+
151
+ ### Cuenta de servicio — `POST /iam/user/service`
152
+ Sin `email` ni contraseña. Para comunicación machine-to-machine. Devuelve un API token permanente una sola vez en la respuesta.
153
+
154
+ ## Endpoints
155
+
156
+ ### Autenticación (sin token)
157
+
158
+ | Método | Endpoint | Descripción |
159
+ |--------|----------|-------------|
160
+ | `POST` | `/iam/auth/email` | Verificar si un email existe |
161
+ | `POST` | `/iam/auth/login` | Iniciar sesión |
162
+ | `POST` | `/iam/auth/logo` | Logo de empresa por email |
163
+ | `POST` | `/iam/auth/forgot/password` | Enviar código de recuperación |
164
+ | `POST` | `/iam/auth/validate/code` | Validar código de recuperación |
165
+ | `POST` | `/iam/auth/reset/password` | Resetear contraseña con código |
166
+ | `POST` | `/iam/auth/verify/mail` | Enviar email de verificación de cuenta |
167
+ | `GET` | `/iam/auth/verify/mail/token/:token` | Activar cuenta por token |
168
+ | `POST` | `/iam/auth/signup` | Registro público (requiere `pwd`) |
169
+ | `GET` | `/iam/generatePassword` | Generar contraseña segura aleatoria |
170
+
171
+ ### Autenticación (con token)
172
+
173
+ | Método | Endpoint | Descripción |
174
+ |--------|----------|-------------|
175
+ | `GET` | `/iam/auth/me` | Perfil del usuario autenticado |
176
+ | `PATCH` | `/iam/auth/profile` | Actualizar perfil |
177
+ | `PUT` | `/iam/auth/profile/pictura` | Actualizar foto de perfil |
178
+ | `PUT` | `/iam/auth/reset/password` | Cambiar contraseña |
179
+ | `POST` | `/iam/auth/send/verify/phone` | Enviar código SMS |
180
+ | `POST` | `/iam/auth/verify/phone` | Validar código de teléfono |
181
+ | `POST` | `/iam/auth/logout` | Cerrar sesión |
182
+ | `PATCH` | `/iam/auth/mail` | Iniciar cambio de email |
183
+ | `POST` | `/iam/auth/validate/mail` | Confirmar nuevo email |
184
+
185
+ ### 2FA / TOTP
186
+
187
+ | Método | Endpoint | Descripción |
188
+ |--------|----------|-------------|
189
+ | `GET` | `/iam/totp/setup` | Genera QR y secreto TOTP |
190
+ | `POST` | `/iam/totp/activate` | Activa 2FA tras escanear QR |
191
+ | `POST` | `/iam/totp/verify` | Verifica código TOTP en el login |
192
+
193
+ ### Usuarios
194
+
195
+ | Método | Endpoint | Descripción |
196
+ |--------|----------|-------------|
197
+ | `POST` | `/iam/user` | Crear usuario administrado |
198
+ | `POST` | `/iam/user/service` | Crear cuenta de servicio |
199
+ | `GET` | `/iam/user` | Listar usuarios `?page&itemsPerPage&search` |
200
+ | `GET` | `/iam/user/:USER_ID` | Obtener usuario |
201
+ | `PATCH` | `/iam/user/:USER_ID` | Actualizar usuario |
202
+ | `PUT` | `/iam/user/:USER_ID/status` | Cambiar estado |
203
+ | `PUT` | `/iam/user/password/:USER_ID` | Cambiar contraseña |
204
+ | `DELETE` | `/iam/user/:USER_ID` | Eliminar usuario |
205
+ | `GET` | `/iam/user/count/all` | Contar usuarios |
206
+ | `GET` | `/iam/business/user` | Usuarios del negocio actual |
207
+ | `GET` | `/iam/user/by/my/companies` | Usuarios de mis empresas |
208
+
209
+ ### Funciones
210
+
211
+ | Método | Endpoint | Descripción |
212
+ |--------|----------|-------------|
213
+ | `POST` | `/iam/functions` | Crear función |
214
+ | `GET` | `/iam/functions` | Listar funciones |
215
+ | `GET` | `/iam/functions/:FUNCTION_ID` | Obtener función |
216
+ | `PATCH` | `/iam/functions/:FUNCTION_ID` | Actualizar función |
217
+ | `PUT` | `/iam/functions/:FUNCTION_ID/status` | Cambiar estado |
218
+ | `DELETE` | `/iam/functions/:FUNCTION_ID` | Eliminar función |
219
+ | `GET` | `/iam/functions/count/all` | Contar funciones |
220
+
221
+ ### Permisos
222
+
223
+ | Método | Endpoint | Descripción |
224
+ |--------|----------|-------------|
225
+ | `POST` | `/iam/permission` | Crear permiso |
226
+ | `GET` | `/iam/permission` | Listar permisos |
227
+ | `GET` | `/iam/permission/:PERMISSION_ID` | Obtener permiso |
228
+ | `PATCH` | `/iam/permission/:PERMISSION_ID` | Actualizar permiso |
229
+ | `PUT` | `/iam/permission/:PERMISSION_ID/status` | Cambiar estado |
230
+ | `DELETE` | `/iam/permission/:PERMISSION_ID` | Eliminar permiso |
231
+ | `GET` | `/iam/permission/count/all` | Contar permisos |
232
+
233
+ ### Menús
234
+
235
+ | Método | Endpoint | Descripción |
236
+ |--------|----------|-------------|
237
+ | `POST` | `/iam/menu` | Crear elemento |
238
+ | `GET` | `/iam/menu` | Listar menús |
239
+ | `GET` | `/iam/menu/:MENU_ID` | Obtener elemento |
240
+ | `PATCH` | `/iam/menu/:MENU_ID` | Actualizar elemento |
241
+ | `PUT` | `/iam/menu/:MENU_ID/status` | Cambiar estado |
242
+ | `POST` | `/iam/menu/order` | Reordenar |
243
+ | `DELETE` | `/iam/menu/:MENU_ID` | Eliminar elemento |
244
+ | `GET` | `/iam/menu/count/all` | Contar menús |
245
+
246
+ ### Empresas
247
+
248
+ | Método | Endpoint | Descripción |
249
+ |--------|----------|-------------|
250
+ | `POST` | `/iam/company` | Crear empresa |
251
+ | `GET` | `/iam/company` | Listar empresas |
252
+ | `GET` | `/iam/company/my` | Mis empresas |
253
+ | `GET` | `/iam/company/:COMPANY_ID` | Detalle |
254
+ | `PATCH` | `/iam/company/:COMPANY_ID` | Actualizar |
255
+ | `PATCH` | `/iam/company/:COMPANY_ID/picture` | Actualizar logo |
256
+ | `PATCH` | `/iam/company/:COMPANY_ID/favicon` | Actualizar favicon |
257
+ | `GET` | `/iam/company/:ID/identity` | Identidad pública |
258
+ | `PUT` | `/iam/company/:COMPANY_ID/gkey` | Configurar Google Key |
259
+ | `DELETE` | `/iam/company/:COMPANY_ID/gkey` | Eliminar Google Key |
260
+ | `DELETE` | `/iam/company/:COMPANY_ID` | Eliminar empresa |
261
+
262
+ ### Negocios
263
+
264
+ | Método | Endpoint | Descripción |
265
+ |--------|----------|-------------|
266
+ | `POST` | `/iam/business` | Crear negocio |
267
+ | `GET` | `/iam/business` | Listar negocios |
268
+ | `POST` | `/iam/business/company` | Negocios de una empresa |
269
+ | `GET` | `/iam/business/my` | Mis negocios |
270
+ | `GET` | `/iam/business/my/company/:COMPANY_ID` | Mis negocios por empresa |
271
+ | `GET` | `/iam/business/:BUSINESS_ID` | Detalle |
272
+ | `PUT` | `/iam/business/:BUSINESS_ID` | Actualizar |
273
+ | `PATCH` | `/iam/business/:BUSINESS_ID/picture` | Actualizar logo |
274
+ | `PATCH` | `/iam/business/:BUSINESS_ID/favicon` | Actualizar favicon |
275
+ | `GET` | `/iam/business/:ID/identity` | Identidad pública |
276
+ | `PATCH` | `/iam/business/:BUSINESS_ID/useCompanyKey` | Usar clave de empresa |
277
+ | `POST` | `/iam/business/:BUSINESS_ID/inheritKey` | Heredar clave de empresa |
278
+ | `DELETE` | `/iam/business/:BUSINESS_ID` | Eliminar negocio |
279
+
280
+ ### Logs, Etiquetas e Historial
281
+
282
+ | Método | Endpoint | Descripción |
283
+ |--------|----------|-------------|
284
+ | `POST` | `/iam/log` | Crear log |
285
+ | `POST` | `/iam/log/retrieve` | Recuperar logs con filtros y analytics |
286
+ | `GET` | `/iam/log/:LOG_ID` | Obtener log |
287
+ | `PATCH` | `/iam/log/:LOG_ID` | Actualizar log |
288
+ | `PUT` | `/iam/log/:LOG_ID/status` | Cambiar estado |
289
+ | `DELETE` | `/iam/log/:LOG_ID` | Eliminar log |
290
+ | `GET` | `/iam/log/count/all` | Contar logs |
291
+ | `POST` | `/iam/label` | Crear etiqueta |
292
+ | `GET` | `/iam/label` | Listar etiquetas |
293
+ | `POST` | `/iam/retrieve/history` | Listar historial |
294
+ | `GET` | `/iam/history/:HISTORY_ID` | Detalle de historial |
295
+
296
+ ## Respuesta de error estándar
297
+
298
+ Todos los errores del IAM devuelven siempre la misma estructura:
299
+
300
+ ```json
301
+ {
302
+ "code": 400,
303
+ "title": "Título del error",
304
+ "detail": "Descripción detallada",
305
+ "suggestion": "Qué hacer para resolverlo"
306
+ }
241
307
  ```
242
308
 
243
- ### Usage for sns
244
- #### Send sns
245
- ```js
246
- // Require
247
- const { AlouxAWS } = require('aloux-iam')
248
-
249
-
250
- // variables
251
- /*
252
- * AWS_REGION
253
- */
254
-
255
- /**
256
- * phoneNumber: Destination number
257
- * message: Message body
258
- */
259
- // a constant is created to request the data from the req.body.
260
- const { phoneNumber, message } = req.body
261
- const sendSns = await AlouxAWS.sendMessagePhone(phoneNumber, message)
262
-
263
- // example of the phoneNumber variable
264
- // this variable must be sent as a string and taking into account the telephone prefix
265
-
266
- /*
267
-
268
- phoneNumber: "+52244-------"
269
-
270
- */
309
+ ## Licencia
271
310
 
272
- ```
311
+ MIT
package/index.js CHANGED
@@ -1,10 +1,16 @@
1
+ const REQUIRED_ENV = ['AUTH_SECRET', 'SESSION_TIME'];
2
+ const missingEnv = REQUIRED_ENV.filter(k => !process.env[k]);
3
+ if (missingEnv.length > 0) {
4
+ throw new Error(`[aloux-iam] Variables de entorno requeridas faltantes: ${missingEnv.join(', ')}`);
5
+ }
6
+
1
7
  const IAMrouter = require("./lib/router");
2
8
  const IAMauth = require("./lib/middleware");
3
- const awsAloux = require("./lib/controllers/operationsAWS");
4
9
  const historyAloux = require("./lib/controllers/history");
5
- const awsBQ = require("./lib/services/bigQuery");
6
- const YAML = require("yamljs");
10
+ const providers = require("./lib/providers");
11
+ const jsyaml = require("js-yaml");
7
12
  const path = require("path");
13
+ const fs = require("fs");
8
14
 
9
15
  const User = require("./lib/models/User");
10
16
  const Functions = require("./lib/models/Functions");
@@ -14,7 +20,7 @@ const Business = require("./lib/models/Business");
14
20
 
15
21
  // swagger
16
22
  const swagger_path = path.resolve(__dirname, "./lib/swagger.yaml");
17
- const swagger = YAML.load(swagger_path);
23
+ const swagger = jsyaml.load(fs.readFileSync(swagger_path, "utf8"));
18
24
 
19
25
  if (process.env.DEBUG === "true") {
20
26
  swagger["servers"] = [];
@@ -32,7 +38,7 @@ module.exports = {
32
38
  IAMPermissionModel: Permission,
33
39
  IAMMenuModel: Menu,
34
40
 
35
- AlouxAWS: awsAloux,
36
- AlouxBQ: awsBQ,
37
41
  AlouxHistory: historyAloux,
42
+
43
+ init: (p = {}) => providers.set(p),
38
44
  };
@@ -1,17 +1,22 @@
1
1
  const fs = require("fs");
2
2
  const self = module.exports;
3
3
 
4
- self.responseError = async (res, error) => {
5
- let obj = error;
6
- if (!error.code) {
7
- obj = {
8
- code: 400,
9
- title: "Error",
10
- detail: error.message,
11
- suggestion: "Revisar el detalle",
12
- };
4
+ self.responseError = (res, error, defaultCode, defaultTitle, defaultSuggestion) => {
5
+ let code, title, detail, suggestion;
6
+
7
+ if (error && typeof error.code === "number") {
8
+ code = error.code;
9
+ title = error.title || "Error";
10
+ detail = typeof error.detail === "string" ? error.detail : "";
11
+ suggestion = error.suggestion || "Revisa el detalle";
12
+ } else {
13
+ code = defaultCode || 400;
14
+ title = defaultTitle || "Error";
15
+ detail = error?.message || "";
16
+ suggestion = defaultSuggestion || "Revisa el detalle";
13
17
  }
14
- res.status(obj.code).send(obj);
18
+
19
+ res.status(code).send({ code, title, detail, suggestion });
15
20
  };
16
21
 
17
22
  self.generatePaginationResponse = async (count, page, itemsPerPage, items) => {
@@ -69,6 +74,31 @@ self.brand = {
69
74
  },
70
75
  };
71
76
 
77
+ self.escapeRegex = (str) => {
78
+ if (typeof str !== 'string') return '';
79
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
80
+ };
81
+
82
+ self.hashToken = (token) => {
83
+ const crypto = require('crypto');
84
+ return crypto.createHash('sha256').update(String(token)).digest('hex');
85
+ };
86
+
87
+ self.hashCode = (code) => {
88
+ const crypto = require('crypto');
89
+ return crypto.createHash('sha256').update(String(code)).digest('hex');
90
+ };
91
+
92
+ self.sanitizeSort = (sort, allowedFields) => {
93
+ if (!sort || typeof sort !== 'object' || Array.isArray(sort)) return null;
94
+ const safe = {};
95
+ for (const [key, val] of Object.entries(sort)) {
96
+ const n = Number(val);
97
+ if (allowedFields.includes(key) && (n === 1 || n === -1)) safe[key] = n;
98
+ }
99
+ return Object.keys(safe).length > 0 ? safe : null;
100
+ };
101
+
72
102
  // Gkey
73
103
  self.resolveGkey = (business) => {
74
104
  const businessGkey = business.gkey || null;