@theoptimalpartner/npm-security-kit 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/EXAMPLES.md +528 -0
- package/LICENSE +21 -0
- package/QUICK_START.md +291 -0
- package/README.md +495 -0
- package/bin/check.js +30 -0
- package/bin/install.js +36 -0
- package/bin/install.sh +324 -0
- package/package.json +52 -0
- package/src/index.js +71 -0
- package/template/.github/dependabot.yml +63 -0
- package/template/.github/workflows/security-audit.yml +218 -0
- package/template/.security/config.json +94 -0
- package/template/.security/malicious-packages-blacklist.json +259 -0
- package/template/scripts/check-malicious-packages.sh +118 -0
- package/template/scripts/security-check.sh +166 -0
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
# Ejemplos de Uso - NPM Security Kit
|
|
2
|
+
|
|
3
|
+
## Escenarios Reales
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Ejemplo 1: Proyecto Express API (Existente)
|
|
8
|
+
|
|
9
|
+
### Situación
|
|
10
|
+
Tienes una API Express en producción con 150 dependencias. Quieres agregar protección de seguridad.
|
|
11
|
+
|
|
12
|
+
### Solución
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# 1. Navegar al proyecto
|
|
16
|
+
cd /ruta/a/mi-api-express
|
|
17
|
+
|
|
18
|
+
# 2. Instalar security kit
|
|
19
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
20
|
+
|
|
21
|
+
# 3. Verificar estado actual
|
|
22
|
+
npm run security:full
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Resultado esperado**:
|
|
26
|
+
```
|
|
27
|
+
========================================
|
|
28
|
+
Security Audit Script
|
|
29
|
+
========================================
|
|
30
|
+
|
|
31
|
+
1. Checking package-lock.json...
|
|
32
|
+
✓ package-lock.json exists
|
|
33
|
+
|
|
34
|
+
2. Running npm audit...
|
|
35
|
+
found 2 moderate vulnerabilities
|
|
36
|
+
|
|
37
|
+
3. Checking for outdated packages...
|
|
38
|
+
Package Current Wanted Latest
|
|
39
|
+
express 4.17.1 4.18.2 4.19.0
|
|
40
|
+
jsonwebtoken 8.5.1 8.5.1 9.0.2
|
|
41
|
+
|
|
42
|
+
4. Checking for install scripts...
|
|
43
|
+
⚠ Install scripts detected - review manually
|
|
44
|
+
|
|
45
|
+
5. Checking for hardcoded secrets...
|
|
46
|
+
✓ No hardcoded secrets detected
|
|
47
|
+
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
9. Checking for known malicious packages...
|
|
51
|
+
✓ No known malicious packages detected
|
|
52
|
+
|
|
53
|
+
Summary:
|
|
54
|
+
Errors: 0
|
|
55
|
+
Warnings: 2
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Acciones
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Arreglar vulnerabilidades
|
|
62
|
+
npm run security:audit:fix
|
|
63
|
+
|
|
64
|
+
# Actualizar paquetes desactualizados
|
|
65
|
+
npm update express jsonwebtoken
|
|
66
|
+
|
|
67
|
+
# Verificar de nuevo
|
|
68
|
+
npm run security:full
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Ejemplo 2: Nueva App React (Desde Cero)
|
|
74
|
+
|
|
75
|
+
### Situación
|
|
76
|
+
Inicias una nueva aplicación React y quieres seguridad desde el día 1.
|
|
77
|
+
|
|
78
|
+
### Solución
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# 1. Crear proyecto con Vite
|
|
82
|
+
npm create vite@latest mi-app-react -- --template react-ts
|
|
83
|
+
cd mi-app-react
|
|
84
|
+
|
|
85
|
+
# 2. Instalar security kit ANTES de instalar dependencias
|
|
86
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
87
|
+
|
|
88
|
+
# 3. Ahora instalar dependencias
|
|
89
|
+
npm install
|
|
90
|
+
|
|
91
|
+
# 4. Verificar que todo esté limpio
|
|
92
|
+
npm run security:check-malicious
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Resultado**:
|
|
96
|
+
```
|
|
97
|
+
✓ No malicious packages detected
|
|
98
|
+
Summary:
|
|
99
|
+
- Checked: 342 packages
|
|
100
|
+
- Against: 175 known malicious packages
|
|
101
|
+
- Found: 0 threats
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Workflow de desarrollo
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Cada vez que instales algo
|
|
108
|
+
npm install axios
|
|
109
|
+
npm run security:check-malicious
|
|
110
|
+
|
|
111
|
+
# Antes de commit
|
|
112
|
+
npm run security:full
|
|
113
|
+
git add .
|
|
114
|
+
git commit -m "feat: add axios for API calls"
|
|
115
|
+
|
|
116
|
+
# GitHub Actions verificará automáticamente en el push
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Ejemplo 3: Monorepo con Múltiples Proyectos
|
|
122
|
+
|
|
123
|
+
### Situación
|
|
124
|
+
Tienes un monorepo con varios paquetes (frontend, backend, shared).
|
|
125
|
+
|
|
126
|
+
### Solución
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Estructura
|
|
130
|
+
monorepo/
|
|
131
|
+
├── packages/
|
|
132
|
+
│ ├── frontend/
|
|
133
|
+
│ ├── backend/
|
|
134
|
+
│ └── shared/
|
|
135
|
+
└── package.json
|
|
136
|
+
|
|
137
|
+
# Instalar en cada paquete
|
|
138
|
+
cd packages/frontend
|
|
139
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
140
|
+
|
|
141
|
+
cd ../backend
|
|
142
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
143
|
+
|
|
144
|
+
cd ../shared
|
|
145
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
146
|
+
|
|
147
|
+
# Script global en raíz (package.json)
|
|
148
|
+
{
|
|
149
|
+
"scripts": {
|
|
150
|
+
"security:check-all": "npm run security:check --workspaces"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Ejemplo 4: CI/CD con GitLab
|
|
158
|
+
|
|
159
|
+
### Situación
|
|
160
|
+
Usas GitLab CI en lugar de GitHub Actions.
|
|
161
|
+
|
|
162
|
+
### Solución
|
|
163
|
+
|
|
164
|
+
Crear `.gitlab-ci.yml`:
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
security-audit:
|
|
168
|
+
stage: test
|
|
169
|
+
image: node:18
|
|
170
|
+
before_script:
|
|
171
|
+
- apt-get update && apt-get install -y jq
|
|
172
|
+
- npm ci
|
|
173
|
+
script:
|
|
174
|
+
- npm run security:check-malicious
|
|
175
|
+
- npm run security:audit
|
|
176
|
+
only:
|
|
177
|
+
- merge_requests
|
|
178
|
+
- main
|
|
179
|
+
allow_failure: false
|
|
180
|
+
|
|
181
|
+
weekly-security-scan:
|
|
182
|
+
stage: test
|
|
183
|
+
image: node:18
|
|
184
|
+
before_script:
|
|
185
|
+
- apt-get update && apt-get install -y jq
|
|
186
|
+
- npm ci
|
|
187
|
+
script:
|
|
188
|
+
- npm run security:full
|
|
189
|
+
only:
|
|
190
|
+
- schedules
|
|
191
|
+
allow_failure: false
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Ejemplo 5: Proyecto con Paquete Malicioso Detectado
|
|
197
|
+
|
|
198
|
+
### Situación
|
|
199
|
+
Instalaste un paquete que resultó ser malicioso.
|
|
200
|
+
|
|
201
|
+
### Detección
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npm install some-suspicious-package
|
|
205
|
+
npm run security:check-malicious
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Resultado**:
|
|
209
|
+
```
|
|
210
|
+
✗ MALICIOUS PACKAGES FOUND!
|
|
211
|
+
|
|
212
|
+
Malicious packages found:
|
|
213
|
+
- some-suspicious-package (direct match)
|
|
214
|
+
|
|
215
|
+
IMMEDIATE ACTIONS REQUIRED:
|
|
216
|
+
1. DO NOT use this application
|
|
217
|
+
2. Uninstall malicious packages immediately
|
|
218
|
+
3. Review application logs
|
|
219
|
+
4. Check for data exfiltration
|
|
220
|
+
5. Report to security team
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Respuesta
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# 1. Desinstalar inmediatamente
|
|
227
|
+
npm uninstall some-suspicious-package
|
|
228
|
+
|
|
229
|
+
# 2. Revisar logs
|
|
230
|
+
git log package-lock.json
|
|
231
|
+
|
|
232
|
+
# 3. Verificar si se ejecutó código malicioso
|
|
233
|
+
npm run security:full
|
|
234
|
+
|
|
235
|
+
# 4. Limpiar node_modules
|
|
236
|
+
rm -rf node_modules package-lock.json
|
|
237
|
+
npm install
|
|
238
|
+
|
|
239
|
+
# 5. Verificar de nuevo
|
|
240
|
+
npm run security:check-malicious
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Ejemplo 6: Actualización de Blacklist
|
|
246
|
+
|
|
247
|
+
### Situación
|
|
248
|
+
Socket.dev reporta nuevos paquetes maliciosos y quieres actualizar.
|
|
249
|
+
|
|
250
|
+
### Solución
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# 1. Descargar blacklist actualizada
|
|
254
|
+
curl -o .security/malicious-packages-blacklist.json \
|
|
255
|
+
https://url-to-updated-blacklist.json
|
|
256
|
+
|
|
257
|
+
# 2. Verificar tu proyecto
|
|
258
|
+
npm run security:check-malicious
|
|
259
|
+
|
|
260
|
+
# 3. Si encuentras problemas, actúa
|
|
261
|
+
npm run security:full
|
|
262
|
+
|
|
263
|
+
# 4. Propagar a otros proyectos
|
|
264
|
+
for project in proyecto1 proyecto2 proyecto3; do
|
|
265
|
+
cp .security/malicious-packages-blacklist.json ../$project/.security/
|
|
266
|
+
(cd ../$project && npm run security:check-malicious)
|
|
267
|
+
done
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Ejemplo 7: Pre-commit Hook
|
|
273
|
+
|
|
274
|
+
### Situación
|
|
275
|
+
Quieres bloquear commits si hay paquetes maliciosos.
|
|
276
|
+
|
|
277
|
+
### Solución
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# 1. Instalar Husky
|
|
281
|
+
npm install --save-dev husky
|
|
282
|
+
npx husky init
|
|
283
|
+
|
|
284
|
+
# 2. Crear pre-commit hook
|
|
285
|
+
cat > .husky/pre-commit <<'EOF'
|
|
286
|
+
#!/bin/sh
|
|
287
|
+
. "$(dirname "$0")/_/husky.sh"
|
|
288
|
+
|
|
289
|
+
echo "🔒 Running security checks..."
|
|
290
|
+
|
|
291
|
+
# Check for malicious packages
|
|
292
|
+
npm run security:check-malicious || {
|
|
293
|
+
echo "❌ Security check failed!"
|
|
294
|
+
echo "Run 'npm run security:check-malicious' for details"
|
|
295
|
+
exit 1
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
echo "✅ Security checks passed"
|
|
299
|
+
EOF
|
|
300
|
+
|
|
301
|
+
chmod +x .husky/pre-commit
|
|
302
|
+
|
|
303
|
+
# 3. Probar
|
|
304
|
+
git add .
|
|
305
|
+
git commit -m "test"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Si hay problema**:
|
|
309
|
+
```
|
|
310
|
+
🔒 Running security checks...
|
|
311
|
+
✗ MALICIOUS PACKAGES FOUND!
|
|
312
|
+
❌ Security check failed!
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Commit bloqueado hasta resolver**
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Ejemplo 8: Integración con Slack
|
|
320
|
+
|
|
321
|
+
### Situación
|
|
322
|
+
Quieres notificaciones en Slack cuando se detectan problemas.
|
|
323
|
+
|
|
324
|
+
### Solución
|
|
325
|
+
|
|
326
|
+
Editar `.security/config.json`:
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"notifications": {
|
|
331
|
+
"enabled": true,
|
|
332
|
+
"channels": {
|
|
333
|
+
"slack": {
|
|
334
|
+
"enabled": true,
|
|
335
|
+
"webhook": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Modificar `scripts/check-malicious-packages.sh` (al final):
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
# Si se encuentran amenazas, notificar Slack
|
|
346
|
+
if [ $FOUND_MALICIOUS -gt 0 ]; then
|
|
347
|
+
WEBHOOK=$(jq -r '.notifications.channels.slack.webhook' .security/config.json)
|
|
348
|
+
if [ "$WEBHOOK" != "null" ] && [ -n "$WEBHOOK" ]; then
|
|
349
|
+
curl -X POST -H 'Content-type: application/json' \
|
|
350
|
+
--data "{\"text\":\"🚨 SECURITY ALERT: Malicious packages detected in $(pwd)\"}" \
|
|
351
|
+
"$WEBHOOK"
|
|
352
|
+
fi
|
|
353
|
+
fi
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Ejemplo 9: Proyecto Serverless (AWS Lambda)
|
|
359
|
+
|
|
360
|
+
### Situación
|
|
361
|
+
Despliegas funciones Lambda y quieres asegurar dependencias.
|
|
362
|
+
|
|
363
|
+
### Solución
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# 1. En tu proyecto serverless
|
|
367
|
+
cd mi-proyecto-serverless
|
|
368
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
369
|
+
|
|
370
|
+
# 2. Agregar check pre-deploy en package.json
|
|
371
|
+
{
|
|
372
|
+
"scripts": {
|
|
373
|
+
"predeploy": "npm run security:full",
|
|
374
|
+
"deploy": "serverless deploy"
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
# 3. Ahora npm run deploy verificará seguridad primero
|
|
379
|
+
npm run deploy
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Si hay problemas, el deploy se bloquea**:
|
|
383
|
+
```
|
|
384
|
+
> predeploy
|
|
385
|
+
> npm run security:full
|
|
386
|
+
|
|
387
|
+
✗ Vulnerabilities detected
|
|
388
|
+
Error: Command failed
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## Ejemplo 10: Auditoría de Proyecto Legacy
|
|
394
|
+
|
|
395
|
+
### Situación
|
|
396
|
+
Proyecto viejo con 500+ dependencias, muchas desactualizadas.
|
|
397
|
+
|
|
398
|
+
### Solución
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
# 1. Instalar kit
|
|
402
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
403
|
+
|
|
404
|
+
# 2. Auditoría inicial (probablemente fallará)
|
|
405
|
+
npm run security:full > audit-report.txt
|
|
406
|
+
|
|
407
|
+
# 3. Analizar el reporte
|
|
408
|
+
cat audit-report.txt
|
|
409
|
+
|
|
410
|
+
# 4. Estrategia de remediación
|
|
411
|
+
# - Críticas y High: Arreglar inmediatamente
|
|
412
|
+
npm run security:audit:fix
|
|
413
|
+
|
|
414
|
+
# - Medium/Low: Planificar para próximo sprint
|
|
415
|
+
npm outdated > outdated.txt
|
|
416
|
+
|
|
417
|
+
# 5. Ir arreglando gradualmente
|
|
418
|
+
# Actualizar de a pocas dependencias por vez
|
|
419
|
+
npm update package1 package2
|
|
420
|
+
npm test
|
|
421
|
+
npm run security:full
|
|
422
|
+
|
|
423
|
+
# 6. Repetir hasta estar limpio
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Ejemplo 11: Librería npm Pública
|
|
429
|
+
|
|
430
|
+
### Situación
|
|
431
|
+
Publicas una librería en npm y quieres asegurar que sea segura.
|
|
432
|
+
|
|
433
|
+
### Solución
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# 1. Instalar kit
|
|
437
|
+
bash /home/diego/projects/npm-security-kit/install.sh
|
|
438
|
+
|
|
439
|
+
# 2. Configurar para librería
|
|
440
|
+
# Editar .security/config.json
|
|
441
|
+
{
|
|
442
|
+
"projectType": "library",
|
|
443
|
+
"strictMode": true,
|
|
444
|
+
"settings": {
|
|
445
|
+
"checkTransitiveDeps": true
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
# 3. Pre-publish hook
|
|
450
|
+
# package.json
|
|
451
|
+
{
|
|
452
|
+
"scripts": {
|
|
453
|
+
"prepublishOnly": "npm run security:full && npm run build && npm test"
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
# 4. Intentar publicar
|
|
458
|
+
npm publish
|
|
459
|
+
# Si hay problemas de seguridad, se bloquea
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Ejemplo 12: Docker + Security Kit
|
|
465
|
+
|
|
466
|
+
### Situación
|
|
467
|
+
Construyes imágenes Docker y quieres verificar seguridad en build.
|
|
468
|
+
|
|
469
|
+
### Solución
|
|
470
|
+
|
|
471
|
+
`Dockerfile`:
|
|
472
|
+
|
|
473
|
+
```dockerfile
|
|
474
|
+
FROM node:18-alpine
|
|
475
|
+
|
|
476
|
+
# Instalar jq
|
|
477
|
+
RUN apk add --no-cache jq
|
|
478
|
+
|
|
479
|
+
WORKDIR /app
|
|
480
|
+
|
|
481
|
+
# Copiar archivos de seguridad
|
|
482
|
+
COPY .security .security
|
|
483
|
+
COPY scripts scripts
|
|
484
|
+
COPY package*.json ./
|
|
485
|
+
|
|
486
|
+
# Hacer scripts ejecutables
|
|
487
|
+
RUN chmod +x scripts/*.sh
|
|
488
|
+
|
|
489
|
+
# Instalar dependencias
|
|
490
|
+
RUN npm ci --production
|
|
491
|
+
|
|
492
|
+
# Verificar seguridad
|
|
493
|
+
RUN npm run security:check-malicious || exit 1
|
|
494
|
+
|
|
495
|
+
# Si pasa, continuar con la app
|
|
496
|
+
COPY . .
|
|
497
|
+
|
|
498
|
+
CMD ["npm", "start"]
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Build con seguridad**:
|
|
502
|
+
```bash
|
|
503
|
+
docker build -t mi-app:latest .
|
|
504
|
+
# Si hay paquetes maliciosos, el build falla
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## Resumen de Escenarios
|
|
510
|
+
|
|
511
|
+
| Escenario | Complejidad | Tiempo | Beneficio |
|
|
512
|
+
|-----------|-------------|--------|-----------|
|
|
513
|
+
| Proyecto Express existente | Baja | 5 min | Protección inmediata |
|
|
514
|
+
| Nueva app React | Muy baja | 2 min | Seguridad desde inicio |
|
|
515
|
+
| Monorepo | Media | 15 min | Protección completa |
|
|
516
|
+
| GitLab CI | Media | 10 min | Automatización CI/CD |
|
|
517
|
+
| Paquete malicioso | Alta | Crítico | Prevención de daños |
|
|
518
|
+
| Actualizar blacklist | Baja | 5 min | Protección actualizada |
|
|
519
|
+
| Pre-commit hooks | Media | 10 min | Prevención proactiva |
|
|
520
|
+
| Slack integration | Media | 15 min | Notificaciones tiempo real |
|
|
521
|
+
| Serverless/Lambda | Baja | 5 min | Deploy seguro |
|
|
522
|
+
| Proyecto legacy | Alta | Iterativo | Mejora gradual |
|
|
523
|
+
| Librería npm | Media | 10 min | Reputación |
|
|
524
|
+
| Docker | Media | 15 min | Containers seguros |
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
**Elige el ejemplo que mejor se adapte a tu caso de uso!**
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Your Organization
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|