Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"extends": [
"plugin:security-node/recommended",
"plugin:promise/recommended"
],
"plugins": [
"security-node",
"promise",
"no-unsanitized",
"sonarjs"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module",
"project": "./tsconfig.eslint.json",
"warnOnUnsupportedTypeScriptVersion": false
},
"rules": {
"no-unsanitized/method": "error",
"no-unsanitized/property": "error",
"eol-last": ["error", "always"],
"quotes": ["error", "single"],

"security-node/detect-child-process": "error",
"security-node/detect-eval-with-expr": "error",
"security-node/detect-non-literal-require-calls": "warn",
"security-node/non-literal-reg-expr": "error",
"security-node/detect-html-injection": "error",
"security-node/detect-sql-injection": "error",
"security-node/detect-unhandled-async-errors": "error",
"security-node/detect-possible-timing-attacks": "error",
"security-node/detect-nosql-injection": "error",
"security-node/detect-security-missconfiguration-cookie": "error",
"security-node/detect-dangerous-redirects": "error",
"security-node/detect-insecure-randomness": "error",

"sonarjs/no-all-duplicated-branches": "error",
"sonarjs/no-element-overwrite": "error",
"sonarjs/no-identical-conditions": "error",
"sonarjs/no-identical-expressions": "error",
"sonarjs/no-one-iteration-loop": "error",
"sonarjs/no-use-of-empty-return-value": "error",
"sonarjs/no-extra-arguments": "error",
"sonarjs/no-identical-functions": "error",
"sonarjs/no-duplicated-branches": "error",
"sonarjs/cognitive-complexity": [
"error",
15
]
}
}
40 changes: 40 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: "npm"
# Look for package.json and package-lock.json in the root directory
directory: "/"
# Check for updates once a week
schedule:
interval: "weekly"
# Specify labels for npm pull requests
labels:
- "npm"
- "dependencies"
# Set maximum number of open pull requests
open-pull-requests-limit: 10
# Allow up to 5 minor version updates
versioning-strategy: widen
# Group minor and patch updates together
groups:
dev-dependencies:
patterns:
- "@types/*"
- "eslint*"
- "prettier"
- "jest"
update-types:
- "minor"
- "patch"

# Enable version updates for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
# Specify labels for GitHub Actions pull requests
labels:
- "github-actions"
- "dependencies"
# Set maximum number of open pull requests
open-pull-requests-limit: 5
52 changes: 52 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: "CodeQL Analysis"

on:
push:
branches-ignore:
- main
- master
pull_request:
branches:
- main
- master
schedule:
- cron: '0 0 * * 1' # Run weekly on Mondays

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

58 changes: 58 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# .github/workflows/npm-publish.yml
name: Build and Publish

on:
push:
branches-ignore:
- main
- master
pull_request:
branches:
- main
- master
release:
types: [created]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18.x'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Test
run: npm test

- name: Build
run: npm run build

publish:
needs: build
if: github.event_name == 'release'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18.x'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Publish to NPM
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
44 changes: 44 additions & 0 deletions .github/workflows/snyk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Snyk Security Checks

on:
push:
branches-ignore:
- main
- master
pull_request:
branches:
- main
- master
schedule:
- cron: '0 0 * * 0' # Weekly scan on Sundays

jobs:
security-checks:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run ESLint security checks
run: npm run lint

- name: Run tests with coverage
run: npm run test

- name: Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --all-projects --org=${{ secrets.SNYK_ORG }} --severity-threshold=high
41 changes: 41 additions & 0 deletions .github/workflows/sonar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: SonarQube Analysis

on:
push:
branches-ignore:
- main
- master
pull_request:
branches:
- main
- master
types: [opened, synchronize, reopened]
schedule:
- cron: '0 0 * * 0' # Weekly scan on Sundays

jobs:
sonarqube:
name: SonarQube
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run tests with coverage
run: npm run test

- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL || 'https://sonarcloud.io' }}
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Dependency directories
node_modules/

# Built output
dist/

# Environment files
.env

# Logs
logs
*.log
npm-debug.log*

# Coverage directory used by tools like istanbul
coverage

# IDE specific files
.idea/
.vscode/
*.swp
*.swo

# OS specific files
.DS_Store
Thumbs.db

# Jest coverage reports
coverage/
Empty file added .scannerwork/.sonar_lock
Empty file.
6 changes: 6 additions & 0 deletions .scannerwork/report-task.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
projectKey=timiagama_nigerian-mobile-validator
serverUrl=http://localhost:9000
serverVersion=25.3.0.104237
dashboardUrl=http://localhost:9000/dashboard?id=timiagama_nigerian-mobile-validator
ceTaskId=a57b8f19-5721-4b8f-b17e-5a6f3dda7c06
ceTaskUrl=http://localhost:9000/api/ce/task?id=a57b8f19-5721-4b8f-b17e-5a6f3dda7c06
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Changelog

All notable changes to the Nigerian Mobile Validator will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2025-03-31

### Added
- Initial release of Nigerian Mobile Validator
- Validation based on NCC March 2025 numbering plan
- Support for network codes 700-919
- Telco identification for all active Nigerian operators
- Stream-based API for reactive updates
- Batch validation for processing multiple numbers
- CSV export functionality
- TypeScript declarations for better type safety
- Comprehensive unit and integration tests
- Documentation with usage examples
- Enhanced security features through new `ValidatorSecurity` class
- Rolling window rate limiting to prevent abuse
- Input sanitization against control characters and overly long inputs
- Fast rejection mechanism for obviously invalid inputs
- PII (Personally Identifiable Information) protection in logs
- Automatic phone number masking in all logging
- Memory leak prevention with EventEmitter listener limits
- Improved test data generation with NetworkAccessCode enums
- Comprehensive property-based testing for validation robustness
- Integration tests for security features
- Event emitter for reactive validation and lifecycle management

### Technical Features
- Map-based lookup for optimal performance
- Lazy loading to reduce memory footprint
- Sanitization of common input mistakes
- Support for multiple number formats
- Detailed validation status messages
- Complex number range validations
- Security protection against denial of service
- PII masking for all phone numbers in logs
- Prevention for memory leaks in event handling
- Input sanitization against malicious patterns
- Maximum input length restrictions
Loading
Loading