npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@resq-sw/security

v0.1.1

Published

Security utilities: encryption, input validation, schemas, and PII sanitization

Readme

@resq-sw/security

Encryption, threat detection, input validation, PII sanitization, and Effect Schema validators.

Installation

bun add @resq-sw/security effect

Peer dependency: effect. Uses Node.js crypto module for encryption.

Quick Start

import { encryptData, decryptData, isSafeInput, escapeHtml, redactPII } from "@resq-sw/security";

// Encrypt/decrypt
const encrypted = await encryptData("sensitive", "my-secret-key");
const decrypted = await decryptData(encrypted, "my-secret-key");

// Validate input
if (!isSafeInput(userInput)) {
  return new Response("Invalid input", { status: 400 });
}

// Sanitize for display
const safe = escapeHtml('<script>alert("xss")</script>');

// Redact PII for logging
const clean = redactPII("Email: [email protected], SSN: 123-45-6789");
// "Email: [EMAIL], SSN: [SSN]"

API Reference

Encryption (crypto.ts)

encryptData(plaintext, encryptionKey): Promise<string>

Encrypts data using AES-256-GCM with scrypt key derivation.

  • plaintext (string) -- data to encrypt.
  • encryptionKey (string) -- encryption key/password.
  • Returns base64 string containing salt:iv:authTag:ciphertext.

decryptData(encryptedData, encryptionKey): Promise<string>

Decrypts data produced by encryptData.

  • encryptedData (string) -- base64-encoded encrypted data.
  • encryptionKey (string) -- same key used for encryption.
  • Returns the original plaintext string.

hashData(data): string

Hashes data using SHA-256. Non-reversible.

  • Returns hex-encoded hash string.

generateSecureToken(length?): string

Generates a cryptographically secure random token.

  • length (number, default 32) -- byte length.
  • Returns hex string (2x the byte length).

maskPII(data): string

Masks a string, showing first 2 and last 2 characters (e.g. "Al****ce"). Returns "****" for strings <= 4 chars.

maskEmail(email): string

Masks email local part (e.g. "j***[email protected]").

sanitizeForLogging(obj, sensitiveFields?): Partial<T>

Recursively redacts sensitive fields from an object for safe logging.

  • sensitiveFields (string[], default: ["password", "passwordHash", "token", "secret", "twoFactorSecret", "apiKey"])
  • Email fields are automatically masked.
sanitizeForLogging({ password: "secret", email: "[email protected]", name: "John" });
// { password: "[REDACTED]", email: "j***[email protected]", name: "John" }

Threat Detection (validators.ts)

detectThreatPatterns(input, config?): ThreatDetectionResult

Runs all configured detectors on input.

  • Returns { isSafe: boolean, threats: ThreatFinding[] }.

| Config Option | Type | Default | Description | |---------------|------|---------|-------------| | checkXSS | boolean | true | Detect script injection, event handlers | | checkSQLInjection | boolean | true | Detect UNION, DROP, stacked queries | | checkNoSQLInjection | boolean | true | Detect MongoDB operators | | checkCommandInjection | boolean | false | Detect shell commands (can cause false positives) | | checkPathTraversal | boolean | true | Detect ../, %2e%2e, null bytes | | checkHomoglyphs | boolean | true | Detect Unicode lookalike characters |

isSafeInput(input, config?): boolean

Quick check returning true if no threats are detected.

Individual Detectors

Each returns ThreatFinding[]:

| Function | Detects | |----------|---------| | containsXSSPatterns(input) | Script tags, event handlers, javascript: URIs, eval() | | containsSQLInjection(input) | UNION SELECT, DROP TABLE, 1=1, SLEEP, stacked queries | | containsNoSQLInjection(input) | MongoDB operators ($gt, $where, $function) | | containsCommandInjection(input) | Command substitution, piped shells | | containsPathTraversal(input) | Directory traversal, null bytes, sensitive paths | | containsHomoglyphs(input) | Cyrillic/Greek lookalike characters |

sanitizeForDisplay(input): string

Escapes HTML entities (<, >, &, ", ', /) for safe rendering.

normalizeUnicode(input): string

Normalizes to NFC form and replaces known homoglyphs with ASCII equivalents.

validateSafeText(input): boolean

Validates text is safe from all attack patterns. For use as a schema refinement.

validateSafeName(input): boolean

Validates a name field -- allows international characters but blocks injection patterns.

validateSafeEmail(input): boolean

Validates email format and checks for injection patterns.

getThreatErrorMessage(result): string

Returns a human-readable error message for a threat detection result.

Sanitization (sanitize.ts)

escapeHtml(text): string

Escapes &, <, >, ", ' to HTML entities.

escapeHtml('<img onerror="alert(1)">'); // "&lt;img onerror=&quot;alert(1)&quot;&gt;"

sanitizeUrl(url, allowedProtocols?): string

Validates and returns a safe URL; returns empty string if unsafe.

  • allowedProtocols (string[], default: ["http:", "https:", "mailto:"]).
  • Blocks javascript:, data: URIs.

sanitizeUrlEffect(url, allowedProtocols?): Exit<string, unknown>

Effect-based version returning an Exit.

validateUserInput(input, maxLength?, allowHtml?): string

Strips HTML tags, normalizes whitespace, removes dangerous patterns, and truncates.

  • maxLength (number, default 500).
  • allowHtml (boolean, default false).

validateUserInputEffect(input, options?): Exit<string, unknown>

Effect-based version with full options.

| Option | Type | Default | Description | |--------|------|---------|-------------| | maxLength | number | 500 | Max output length | | allowHtml | boolean | false | Preserve HTML tags | | allowNewlines | boolean | false | Preserve newlines | | trimWhitespace | boolean | true | Trim leading/trailing whitespace |

sanitizeJson<T>(jsonString): T | null

Safely parses JSON with prototype pollution protection. Removes __proto__, constructor, prototype keys.

parseJsonWithSchema<A>(jsonString, schema): Option<A>

Parses JSON with Effect Schema validation and prototype pollution protection. Returns Option.some(value) or Option.none().

const UserSchema = Schema.Struct({ name: Schema.String, age: Schema.Number });
const user = parseJsonWithSchema('{"name":"John","age":30}', UserSchema);
// Option.some({ name: "John", age: 30 })

stripAnsi(text): string

Removes ANSI escape codes from strings.

redactPII(text, options?): string

Replaces PII patterns with redaction markers.

| Option | Type | Default | Marker | |--------|------|---------|--------| | redactEmails | boolean | true | [EMAIL] | | redactPhones | boolean | true | [PHONE] | | redactSSN | boolean | true | [SSN] | | redactCreditCards | boolean | true | [CREDIT_CARD] | | redactIPs | boolean | true | [IP_ADDRESS] | | customPatterns | Array<{ pattern, replacement }> | [] | custom |

safeStringify(obj, sensitiveKeys?, indent?): string

JSON.stringify with automatic redaction of sensitive keys.

  • sensitiveKeys (string[], default: ["password", "token", "apiKey", "secret", "authorization", "cookie", "ssn", "creditCard"]).

Validation Helpers

| Function | Description | |----------|-------------| | isValidEmail(email) | Validates email format | | isValidPhone(phone) | Validates US phone format | | isValidSSN(ssn) | Validates US SSN format | | isValidUrl(url) | Validates safe URL |

Effect Schemas

Exported for runtime validation: SafeUrlSchema, EmailSchema, PhoneNumberSchema, SSNSchema, CreditCardSchema, IPv4Schema, SanitizedStringSchema, UrlProtocolSchema, PIIRedactionOptionsSchema, UserInputOptionsSchema.

Types

Exported types: ThreatDetectionResult, ThreatFinding, ThreatType, ThreatDetectionConfig, PIIRedactionOptions, UserInputOptions, SafeUrl, Email, PhoneNumber, SSN, CreditCard, IPv4, UrlProtocol.

License

Apache-2.0