{"_id":"@alloylab/security","name":"@alloylab/security","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.2":{"name":"@alloylab/security","version":"1.0.2","description":"Security utilities and middleware for modern web applications","main":"dist/index.js","type":"module","keywords":["security","middleware","cors","rate-limiting","helmet","validation","sanitization","express","typescript","authentication","authorization"],"author":{"name":"Stephen Way","email":"stephen@stephenway.net"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alloy-lab/overland.git","directory":"packages/security"},"bugs":{"url":"https://github.com/alloy-lab/overland/issues"},"homepage":"https://github.com/alloy-lab/overland/tree/main/packages/security#readme","engines":{"node":">=18.0.0"},"peerDependencies":{"express":">=4.0.0"},"dependencies":{"cors":"^2.8.5","express-rate-limit":"^7.4.1","express-validator":"^7.2.0","helmet":"^8.0.0","zod":"^3.23.8"},"devDependencies":{"@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@eslint/js":"^9.16.0","@types/cors":"^2.8.17","@types/express":"^5.0.0","@types/node":"^24.5.2","@vitest/coverage-v8":"^3.2.4","eslint":"^9.16.0","express":"^4.21.1","lefthook":"^1.13.2","prettier":"^3.6.2","typescript":"^5.9.2","typescript-eslint":"^8.16.0","vitest":"^3.2.4"},"scripts":{"build":"tsc","dev":"tsc --watch","test":"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","test:watch":"vitest --watch","lint":"eslint src --ext .js,.ts","lint:fix":"eslint src --ext .js,.ts --fix","commitlint":"commitlint","format":"prettier --write .","format:check":"prettier --check .","typecheck":"tsc --noEmit","clean":"rm -rf dist","prebuild":"npm run clean","hooks:install":"lefthook install","hooks:uninstall":"lefthook uninstall","version":"npm run format && git add -A","postversion":"git push && git push --tags"},"_id":"@alloylab/security@1.0.2","types":"./dist/index.d.ts","_integrity":"sha512-gdapBa3fwsTSu5V/2oNyqinptPFWUgILWPmT/fMA16sp7OCPmZDnyfgPCQ2hgwb6JpNc0A1Hp4R+7fzAdWjErA==","_resolved":"/tmp/cc790a86ceb3561f6b9dc4577aa46584/alloylab-security-1.0.2.tgz","_from":"file:alloylab-security-1.0.2.tgz","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-gdapBa3fwsTSu5V/2oNyqinptPFWUgILWPmT/fMA16sp7OCPmZDnyfgPCQ2hgwb6JpNc0A1Hp4R+7fzAdWjErA==","shasum":"a90244392969e63b337652026f1c7e7e6b0d5e64","tarball":"https://registry.npmjs.org/@alloylab/security/-/security-1.0.2.tgz","fileCount":24,"unpackedSize":73465,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBWfg42ZL+ytbemtAZN2aq2+eWscWu8a6Vw+9+rHSz2vAiEA4uJ3/5flFcA+5zUkoPJgB+WfY/kjvokWjoiJbzYHB4c="}]},"_npmUser":{"name":"stephenway","email":"stephen@stephenway.net"},"directories":{},"maintainers":[{"name":"stephenway","email":"stephen@stephenway.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/security_1.0.2_1759098732157_0.6144166864849698"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-28T22:32:12.030Z","1.0.2":"2025-09-28T22:32:12.345Z","modified":"2025-09-28T22:32:12.687Z"},"maintainers":[{"name":"stephenway","email":"stephen@stephenway.net"}],"description":"Security utilities and middleware for modern web applications","homepage":"https://github.com/alloy-lab/overland/tree/main/packages/security#readme","keywords":["security","middleware","cors","rate-limiting","helmet","validation","sanitization","express","typescript","authentication","authorization"],"repository":{"type":"git","url":"git+https://github.com/alloy-lab/overland.git","directory":"packages/security"},"author":{"name":"Stephen Way","email":"stephen@stephenway.net"},"bugs":{"url":"https://github.com/alloy-lab/overland/issues"},"license":"MIT","readme":"# @alloylab/security\n\n[![npm version](https://badge.fury.io/js/%40alloylab%2Fsecurity.svg)](https://badge.fury.io/js/%40alloy-lab%2Fsecurity)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nSecurity utilities and middleware for modern web applications. This package provides comprehensive security tools including CORS configuration, rate limiting, request sanitization, validation, and API security middleware.\n\n## Features\n\n- 🛡️ **CORS Configuration**: Flexible CORS setup with origin validation\n- ⏱️ **Rate Limiting**: Configurable rate limiting for different endpoint types (general, auth, password reset)\n- 🔒 **Security Headers**: Helmet configuration for comprehensive security headers\n- 🧹 **Request Sanitization**: XSS protection and input sanitization\n- ✅ **Validation**: Express-validator integration with common and API-specific validation rules\n- 🔑 **API Security**: API key validation, admin authentication, and request logging\n- 📁 **File Upload Security**: Secure file upload validation with type, size, and extension checks\n- 🌍 **Environment Validation**: Zod-based environment variable validation with type safety\n- 📊 **Request Logging**: Comprehensive API request and response logging with timing\n- 🔧 **TypeScript Support**: Full TypeScript definitions and type safety\n- 📦 **Framework Agnostic**: Works with any Express-based application\n- 🎯 **Specialized Middleware**: Pre-configured security middleware for different use cases.\n\n## Installation\n\n```bash\nnpm install @alloylab/security\n# or\nyarn add @alloylab/security\n# or\npnpm add @alloylab/security\n```\n\n## Quick Start\n\n### 1. Basic Security Middleware\n\n```typescript\nimport express from 'express';\nimport { createApiSecurity } from '@alloylab/security';\n\nconst app = express();\n\n// Apply security middleware to all routes\napp.use(createApiSecurity(['https://yourdomain.com']));\n\napp.get('/api/data', (req, res) => {\n  res.json({ message: 'Secure data' });\n});\n```\n\n### 2. Environment Validation\n\n```typescript\nimport { validateEnv } from '@alloylab/security';\n\n// Validate environment variables on startup\nconst env = validateEnv();\n\nconsole.log('Server running on port:', env.PORT);\n```\n\n### 3. API Security\n\n```typescript\nimport express from 'express';\nimport {\n  createValidateApiKey,\n  createRequireAdmin,\n  createFormatApiResponse,\n} from '@alloylab/security';\n\nconst app = express();\n\n// API key validation for public API\napp.use('/api/public', createValidateApiKey());\n\n// Admin authentication for admin routes\napp.use('/api/admin', createRequireAdmin());\n\n// Format API responses\napp.use(createFormatApiResponse());\n\napp.get('/api/public/data', (req, res) => {\n  res.json({ data: 'public data' });\n});\n\napp.get('/api/admin/users', (req, res) => {\n  res.json({ users: [] });\n});\n```\n\n### 4. File Upload Security\n\n```typescript\nimport express from 'express';\nimport multer from 'multer';\nimport { createValidateFileUpload } from '@alloylab/security';\n\nconst app = express();\nconst upload = multer();\n\n// Secure file upload\napp.post(\n  '/api/upload',\n  upload.single('file'),\n  createValidateFileUpload(\n    5 * 1024 * 1024, // 5MB max size\n    ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] // Allowed types\n  ),\n  (req, res) => {\n    res.json({ message: 'File uploaded successfully' });\n  }\n);\n```\n\n## API Reference\n\n### Environment Validation\n\n#### `validateEnv(logger?)`\n\nValidates environment variables using a predefined schema.\n\n```typescript\nimport { validateEnv } from '@alloylab/security';\n\nconst env = validateEnv();\n```\n\n#### `createEnvSchema(schema)`\n\nCreates a custom environment validation schema.\n\n```typescript\nimport { createEnvSchema, validateCustomEnv } from '@alloylab/security';\nimport { z } from 'zod';\n\nconst customSchema = createEnvSchema({\n  CUSTOM_VAR: z.string().min(1),\n  OPTIONAL_VAR: z.string().optional(),\n});\n\nconst env = validateCustomEnv(customSchema);\n```\n\n### Security Middleware\n\n#### `createApiSecurity(allowedOrigins?, logger?)`\n\nCreates comprehensive security middleware for API routes.\n\n```typescript\nimport { createApiSecurity } from '@alloylab/security';\n\napp.use(createApiSecurity(['https://yourdomain.com']));\n```\n\n#### `createAuthSecurity(allowedOrigins?, logger?)`\n\nCreates security middleware for authentication routes with stricter rate limiting.\n\n```typescript\nimport { createAuthSecurity } from '@alloylab/security';\n\napp.use('/auth', createAuthSecurity());\n```\n\n#### `createPasswordResetSecurity(allowedOrigins?, logger?)`\n\nCreates security middleware for password reset with very strict rate limiting.\n\n```typescript\nimport { createPasswordResetSecurity } from '@alloylab/security';\n\napp.use('/auth/reset', createPasswordResetSecurity());\n```\n\n#### `createFormSecurity(allowedOrigins?, logger?)`\n\nCreates security middleware for form submissions with general rate limiting.\n\n```typescript\nimport { createFormSecurity } from '@alloylab/security';\n\napp.use('/forms', createFormSecurity());\n```\n\n#### `createStaticSecurity()`\n\nCreates security middleware for static file serving with cache headers.\n\n```typescript\nimport { createStaticSecurity } from '@alloylab/security';\n\napp.use('/static', createStaticSecurity());\n```\n\n### API Security\n\n#### `createValidateApiKey(logger?)`\n\nValidates API keys from headers or query parameters.\n\n```typescript\nimport { createValidateApiKey } from '@alloylab/security';\n\napp.use('/api', createValidateApiKey());\n```\n\n#### `createRequireAdmin(logger?)`\n\nRequires admin authentication via X-Admin-Token header.\n\n```typescript\nimport { createRequireAdmin } from '@alloylab/security';\n\napp.use('/admin', createRequireAdmin());\n```\n\n#### `createValidateFileUpload(maxSize?, allowedTypes?, logger?)`\n\nValidates file uploads for size, type, and malicious extensions.\n\n```typescript\nimport { createValidateFileUpload } from '@alloylab/security';\n\napp.post(\n  '/upload',\n  upload.single('file'),\n  createValidateFileUpload(10 * 1024 * 1024, ['image/jpeg', 'image/png'])\n);\n```\n\n#### `createApiRequestLogger(logger?)`\n\nLogs API requests and responses with timing information.\n\n```typescript\nimport { createApiRequestLogger } from '@alloylab/security';\n\napp.use('/api', createApiRequestLogger());\n```\n\n#### `createValidateApiRequest(logger?)`\n\nValidates API requests using express-validator results.\n\n```typescript\nimport { createValidateApiRequest } from '@alloylab/security';\n\napp.post(\n  '/api/data',\n  validationRules.email,\n  createValidateApiRequest(),\n  handler\n);\n```\n\n### Validation Rules\n\nThe package includes pre-configured validation rules:\n\n```typescript\nimport { validationRules } from '@alloylab/security';\n\n// Use in your routes\napp.post(\n  '/users',\n  validationRules.email,\n  validationRules.password,\n  validationRules.name,\n  createValidateRequest(),\n  (req, res) => {\n    // Handle validated request\n  }\n);\n```\n\nAvailable validation rules:\n\n- `email` - Email validation with normalization\n- `password` - Strong password requirements (8+ chars, uppercase, lowercase, number)\n- `name` - Name validation with character restrictions (letters, spaces, hyphens, apostrophes, periods)\n- `slug` - URL-friendly slug validation (lowercase letters, numbers, hyphens)\n- `content` - Content length validation (1-10,000 characters)\n- `title` - Title length validation (1-200 characters)\n- `page` - Pagination page validation (positive integer)\n- `limit` - Pagination limit validation (1-100)\n\n### API Validation Rules\n\nThe package also includes specialized API validation rules:\n\n```typescript\nimport { apiValidationRules } from '@alloylab/security';\n\n// Page creation/update validation\napp.post(\n  '/api/pages',\n  apiValidationRules.createPage,\n  createValidateApiRequest(),\n  handler\n);\n\n// Page update validation\napp.put(\n  '/api/pages/:id',\n  apiValidationRules.updatePage,\n  createValidateApiRequest(),\n  handler\n);\n\n// Media upload validation\napp.post(\n  '/api/media',\n  apiValidationRules.uploadMedia,\n  createValidateApiRequest(),\n  handler\n);\n\n// Site settings validation\napp.put(\n  '/api/settings',\n  apiValidationRules.updateSiteSettings,\n  createValidateApiRequest(),\n  handler\n);\n\n// Pagination validation\napp.get(\n  '/api/data',\n  apiValidationRules.pagination,\n  createValidateApiRequest(),\n  handler\n);\n\n// Search validation\napp.get(\n  '/api/search',\n  apiValidationRules.search,\n  createValidateApiRequest(),\n  handler\n);\n```\n\nAvailable API validation rule sets:\n\n- `createPage` - Page creation validation (title, content, slug, status)\n- `updatePage` - Page update validation (ID, optional title/content/status)\n- `deletePage` - Page deletion validation (MongoDB ObjectId)\n- `uploadMedia` - Media upload validation (alt text, caption)\n- `updateSiteSettings` - Site settings validation (title, description, contact email)\n- `pagination` - Pagination validation (page, limit, sort)\n- `search` - Search validation (query, type)\n\n### Request Sanitization\n\n#### `createSanitizeRequest(logger?)`\n\nSanitizes request body and query parameters to prevent XSS attacks.\n\n```typescript\nimport { createSanitizeRequest } from '@alloylab/security';\n\napp.use(createSanitizeRequest());\n```\n\n### Response Formatting\n\n#### `createFormatApiResponse(includeRequestId?, logger?)`\n\nFormats API responses with consistent structure and security headers.\n\n```typescript\nimport { createFormatApiResponse } from '@alloylab/security';\n\napp.use(createFormatApiResponse(true));\n```\n\n### Additional Utilities\n\n#### `createRequestSizeLimit(limit)`\n\nCreates middleware to limit request body size.\n\n```typescript\nimport { createRequestSizeLimit } from '@alloylab/security';\n\napp.use(createRequestSizeLimit('10MB'));\n```\n\n#### `createCorsConfig(allowedOrigins?, logger?)`\n\nCreates CORS configuration object.\n\n```typescript\nimport { createCorsConfig } from '@alloylab/security';\n\nconst corsConfig = createCorsConfig(['https://yourdomain.com']);\n```\n\n#### `createRateLimitConfig()`\n\nCreates rate limiting configuration with different limits for different endpoint types.\n\n```typescript\nimport { createRateLimitConfig } from '@alloylab/security';\n\nconst rateLimitConfig = createRateLimitConfig();\n// Returns: { general, auth, passwordReset }\n```\n\n#### `createHelmetConfig()`\n\nCreates Helmet security headers configuration.\n\n```typescript\nimport { createHelmetConfig } from '@alloylab/security';\n\nconst helmetConfig = createHelmetConfig();\n```\n\n#### `createApiRateLimit(windowMs, max, message)`\n\n⚠️ **Note**: This function is currently a placeholder implementation and requires Redis integration for production use.\n\n```typescript\nimport { createApiRateLimit } from '@alloylab/security';\n\n// Currently returns a no-op middleware\nconst rateLimit = createApiRateLimit(60000, 100, 'Too many requests');\n```\n\n## Configuration\n\n### Environment Variables\n\nThe package validates these environment variables:\n\n```bash\n# Required\nNODE_ENV=development|production|test\nDATABASE_URI=your_database_uri\nPAYLOAD_SECRET=your_32_character_secret\nPAYLOAD_PUBLIC_SERVER_URL=https://your-api.com\nPAYLOAD_PUBLIC_CMS_URL=https://your-cms.com\n\n# Optional Security\nAPI_KEY=your_api_key\nADMIN_TOKEN=your_admin_token\nALLOWED_ORIGIN_1=https://yourdomain.com\nALLOWED_ORIGIN_2=https://anotherdomain.com\nADMIN_IP_WHITELIST=192.168.1.0/24\n\n# Features\nENABLE_RATE_LIMITING=true\nENABLE_CORS=true\nLOG_LEVEL=info\nSENTRY_DSN=https://your-sentry-dsn\n\n# File uploads\nMAX_FILE_SIZE=10MB\nALLOWED_FILE_TYPES=image/jpeg,image/png,image/gif,image/webp\n```\n\n### Custom Logger\n\nYou can provide a custom logger that implements the `Logger` interface:\n\n```typescript\nimport type { Logger } from '@alloylab/security';\n\nconst customLogger: Logger = {\n  info: (message, meta) => console.log(`[INFO] ${message}`, meta),\n  warn: (message, meta) => console.warn(`[WARN] ${message}`, meta),\n  error: (message, meta) => console.error(`[ERROR] ${message}`, meta),\n  debug: (message, meta) => console.debug(`[DEBUG] ${message}`, meta),\n};\n\nconst env = validateEnv(customLogger);\n```\n\n## Integration Examples\n\n### Express.js Application\n\n```typescript\nimport express from 'express';\nimport {\n  validateEnv,\n  createApiSecurity,\n  createValidateApiKey,\n  createFormatApiResponse,\n} from '@alloylab/security';\n\n// Validate environment\nconst env = validateEnv();\n\nconst app = express();\n\n// Apply security middleware\napp.use(createApiSecurity([env.ALLOWED_ORIGIN_1, env.ALLOWED_ORIGIN_2]));\n\n// API routes with key validation\napp.use('/api', createValidateApiKey());\n\n// Format responses\napp.use(createFormatApiResponse());\n\napp.get('/api/data', (req, res) => {\n  res.json({ data: 'secure data' });\n});\n\napp.listen(env.PORT, () => {\n  console.log(`Server running on port ${env.PORT}`);\n});\n```\n\n### Next.js API Routes\n\n```typescript\n// pages/api/secure.ts\nimport { NextApiRequest, NextApiResponse } from 'next';\nimport { createValidateApiKey } from '@alloylab/security';\n\nexport default function handler(req: NextApiRequest, res: NextApiResponse) {\n  // Apply API key validation\n  const validateApiKey = createValidateApiKey();\n\n  validateApiKey(req as any, res as any, () => {\n    res.json({ message: 'Secure API response' });\n  });\n}\n```\n\n## Best Practices\n\n1. **Environment Validation**: Always validate environment variables on startup\n2. **Rate Limiting**: Use appropriate rate limits for different endpoint types\n3. **CORS Configuration**: Only allow necessary origins\n4. **Input Sanitization**: Sanitize all user inputs\n5. **File Upload Security**: Validate file types and sizes\n6. **API Key Management**: Use strong, unique API keys\n7. **Logging**: Implement comprehensive security logging\n8. **Headers**: Always include security headers\n\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md) for details.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.\n\n## Support\n\n- 📖 [Documentation](https://github.com/alloy-lab/overland/tree/main/packages/security#readme)\n- 🐛 [Issue Tracker](https://github.com/alloy-lab/overland/issues)\n- 💬 [Discussions](https://github.com/alloy-lab/overland/discussions)\n","readmeFilename":"README.md","_rev":"1-c7ffee95b5f4a28ddf3713574a7bf98d"}