sanitize-contents 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/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # sanitize-content
2
+
3
+ A robust, lightweight library to sanitize sensitive information (passwords, tokens, connection strings, etc.) from strings and HTML content.
4
+
5
+ ## Features
6
+
7
+ - **Connection Strings**: Redacts user:pass from `mongodb://`, `postgres://`, `redis://`, etc.
8
+ - **Query Parameters**: Redacts sensitive keys like `api_key`, `access_token`, `secret`, `password` from URLs.
9
+ - **Authorization Headers**: Sanitizes `Bearer` and `Basic` auth tokens.
10
+ - **Credential Labels**: Identifies and redacts common patterns like `Password: ...`, `API Key: ...`.
11
+ - **CURL Auth**: Sanitizes `-u user:pass` flags in curl commands.
12
+ - **Lightweight**: Zero dependencies.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install sanitize-content
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```javascript
23
+ import { sanitizeContent } from 'sanitize-content';
24
+
25
+ const rawContent = 'Connecting to mongodb://user:pass123@localhost:27017/db';
26
+ const cleanContent = sanitizeContent(rawContent);
27
+ // Connecting to mongodb://[REDACTED]@localhost:27017/db
28
+
29
+ const url = 'https://api.example.com?api_key=sk-123456789';
30
+ console.log(sanitizeContent(url));
31
+ // https://api.example.com?api_key=[REDACTED]
32
+
33
+ const header = 'Authorization: Bearer my-secret-token';
34
+ console.log(sanitizeContent(header));
35
+ // Authorization: Bearer [REDACTED]
36
+ ```
37
+
38
+ ## License
39
+
40
+ ISC
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Sanitizes sensitive information from content.
3
+ * Redacts passwords, connection strings, API keys, etc.
4
+ */
5
+ /**
6
+ * Sanitizes a string by redacting sensitive patterns.
7
+ */
8
+ declare function sanitizeContent(content: string): string;
9
+ /**
10
+ * Sanitizes HTML content by processing only text nodes.
11
+ * Matches the API of the user's legacy script.
12
+ */
13
+ declare function sanitizeDescription(html: string): {
14
+ sanitized_text: string;
15
+ };
16
+
17
+ export { sanitizeContent as default, sanitizeContent, sanitizeDescription };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Sanitizes sensitive information from content.
3
+ * Redacts passwords, connection strings, API keys, etc.
4
+ */
5
+ /**
6
+ * Sanitizes a string by redacting sensitive patterns.
7
+ */
8
+ declare function sanitizeContent(content: string): string;
9
+ /**
10
+ * Sanitizes HTML content by processing only text nodes.
11
+ * Matches the API of the user's legacy script.
12
+ */
13
+ declare function sanitizeDescription(html: string): {
14
+ sanitized_text: string;
15
+ };
16
+
17
+ export { sanitizeContent as default, sanitizeContent, sanitizeDescription };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var g=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var b=(r,e)=>{for(var o in e)g(r,o,{get:e[o],enumerable:!0})},C=(r,e,o,_)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of S(e))!R.call(r,a)&&a!==o&&g(r,a,{get:()=>e[a],enumerable:!(_=A(e,a))||_.enumerable});return r};var N=r=>C(g({},"__esModule",{value:!0}),r);var D={};b(D,{default:()=>O,sanitizeContent:()=>T,sanitizeDescription:()=>I});module.exports=N(D);var f=require("jsdom"),d={CONNECTION_STRING:/([a-z0-9+.-]+:\/\/)([^:@\s]+):([^:@\s]+)@/gi,SQL_INSERT:/\bINSERT\s+INTO\b.*?\((?:[^)]*,\s*)?\b(password|pwd|pass|passcode)\b.*?\)\s*VALUES\s*\((?:[^,']*,|[^,"]*,)*\s*['"]([^'"]+)['"]/gi,HTML_INPUT:/<input[^>]+(?:type=["']password["'](?:\s+[^>]*?)?value=["']([^"']*)["']|value=["']([^"']*)["'](?:\s+[^>]*?)?type=["']password["'])/gi,QUERY_PARAM:/([?&])(api[_-]?key|access[_-]?token|secret|password|pass|passwrod|psswrd|pw|pwd|token|key|auth[_-]?token|u|p|user|username|passcode|wifi[_-]?password|p_?w_?d|confirm[_-]?password|confirm[_-]?pwd)=([^&\s<"']+)/gi,AUTH_TOKEN:/\b(authorization|auth[_-]?token)\s*[:=]\s*(bearer|basic|token)?\s*([a-zA-Z0-9.\-_~+/]{8,})|(?:\b(bearer|basic|token)\s+([a-zA-Z0-9.\-_~+/]{8,}))/gi,JWT:/\beyJ[a-zA-Z0-9._-]{10,}\b/gi,BASE64_PASS:/cGFzc3dvcmQ9[a-zA-Z0-9+/=]+/g,USER_PASS:/\b(user(?:name)?|login)\b\s*[:=\s/]\s*([^"'\s,]+)\s*(?:and\s+)?\b(pass(?:word)?|pwd|p|p_?w_?d)\b\s*[:=\s]\s*([^"'\s<,]+)/gi,SLASH_CRED:/\b(admin|user|root|api_?user)\/([^"'\s,;]{3,})\b/gi,CURL_AUTH:/(^|\s)(-u\s+)([^:\s]+):([^:\s\\]+)/gi,ASSIGNMENT:/\b(DB[_-]?PASSWORD|JWT[_-]?SECRET|SECRET[_-]?KEY|AUTH[_-]?PASSWORD|PASSWORD|SECRET|KEY|WIFI[_-]?PASSWORD|PASSCODE|API[_-]?KEY|CONFIRM[_-]?PASSWORD|PASSWROD)\s*[:=]\s*(?:["']?)([^"'\s;<>]{3,})(?:["']?)/gi,XML_TAG:/<([^>]*password|pass|secret|token|key)>([^<]+)<\/\1>/gi,LABEL_HINT:/(?:\b|["'<])(password|pass|passwrod|psswrd|pw|pwd|api[_-]?key|access[_-]?token|auth[_-]?token|credentials|creds|secret|token|key|passcode|wifi[_-]?password|p_?w_?d|u|p|confirm[_-]?password|confirm[_-]?pwd|actual|temp|temporary|new\s+one|old\s+one|new\s+password|old\s+password)(?:\b|["'>])[^a-zA-Z0-9\s]*\s*(?:[:=\s]|was\s+something\s+like|it\s+was\s+something\s+like|was|is|like|should\s+be|actual\s+was|could\s+be|might\s+be|set\s+to|entered)(?:\s+it)?\s*[:=]?\s*(?:["']?)([^"'\s<>&,;?]+)(?:["']?)(?:\s+or\s+([^"'\s<>&,;?]+))?/gi,URL:/\bhttps?:\/\/[^\s"'<>]+/gi,EMAIL:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,MENTION:/(^|\s|[(\[])(@([a-zA-Z0-9._-]+))/g},p="[REDACTED]",w=/^(value|type|name|id|class|and|or|was|is|it|the|set|to|values|into|select|from|where|union|join|table|input|button|form|label|div|span|script|style|html|body|head|meta|link|header|footer|auth|login|signin|signout|logout|session|cookie|token|true|false|null|undefined|error|success|failed|warn|info|debug|trace|admin|user|root|for|test|testing|staging|placeholder|password|pass|pwd|psswrd|passwrod|token|key|api[_-]?key|secret|hidden|entered|shown|verified)$/i;function l(r,e,o){if(!o||o===p||o.length<1||o.includes(p)||o.includes("__PROTECTED_"))return r;let _=o.replace(/["']/g,"").trim();if(_.length<2||w.test(_)||_.toLowerCase()===e.toLowerCase())return r;let a=r.toLowerCase().indexOf(e.toLowerCase());if(a===-1)return r;let t=r.substring(a+e.length).indexOf(o);if(t===-1)return r;let n=a+e.length+t;return r.substring(0,n)+p+r.substring(n+o.length)}function L(r){return r.replace(/(?<!\w)([A-Za-z\d@$!%*#?&^()_\-+=]{7,64})(?!\w)/g,e=>{if(/^__PROTECTED_/.test(e)||e.includes(p)||w.test(e))return e;let o=/[A-Z]/.test(e),_=/[a-z]/.test(e),a=/\d/.test(e),s=/[@$!%*#?&^()_\-+=]/.test(e);return[o,_,a,s].filter(Boolean).length>=3?p:e})}function T(r){if(!r||typeof r!="string")return r;let e=r;e=e.replace(d.CONNECTION_STRING,"$1"+p+"@"),e=e.replace(d.QUERY_PARAM,"$1$2="+p),e=e.replace(d.XML_TAG,(s,t,n)=>`<${t}>${p}</${t}>`);let o=[];e=e.replace(d.URL,s=>{let t=`__PROTECTED_URL_${o.length}__`;return o.push(s),t});let _=[];e=e.replace(d.EMAIL,s=>{let t=`__PROTECTED_EMAIL_${_.length}__`;return _.push(s),t});let a=[];if(e=e.replace(d.MENTION,(s,t,n)=>{let i=`__PROTECTED_MENTION_${a.length}__`;return a.push(n),t+i}),e=e.replace(d.SQL_INSERT,(s,t,n)=>s.replace(n,p)),e=e.replace(d.HTML_INPUT,(s,t,n)=>{let i=t||n;return i?l(s,"password",i):s}),e=e.replace(d.AUTH_TOKEN,(s,t,n,i,c,u)=>{if(c&&u)return`${c} ${p}`;let E=n?`${n} `:"";return`${t}: ${E}${p}`}),e=e.replace(d.JWT,p),e=e.replace(d.BASE64_PASS,"cGFzc3dvcmQ9W1JFREFDVEVEX1BBU1NXT1JEXQ=="),e=e.replace(d.USER_PASS,(s,t,n,i,c)=>l(s,i,c)),e=e.replace(d.CURL_AUTH,"$1$2$3:"+p),e=e.replace(d.ASSIGNMENT,(s,t,n)=>l(s,t,n)),e=e.replace(d.SLASH_CRED,"$1/"+p),e=e.replace(d.LABEL_HINT,(s,t,n,i)=>{let c=l(s,t,n);return i&&(c=l(c,p,i)),c}),e.toLowerCase().includes("password")&&e.includes(",")){let s=e.split(/\r?\n/),t=-1,n=-1;for(let i=0;i<s.length;i++)if(s[i].includes(",")&&!s[i].toUpperCase().includes("VALUES")){let u=s[i].toLowerCase().split(",").findIndex(E=>E.includes("password")||E.trim()==="pwd");if(u!==-1){t=i,n=u;break}}if(t!==-1){for(let i=t+1;i<s.length;i++){let c=s[i].split(",");c.length>n&&c[n].trim().length>0&&(w.test(c[n].trim())||(c[n]=p,s[i]=c.join(",")))}e=s.join(`
2
+ `)}}return e=L(e),e=e.replace(/(\[REDACTED\]\s*){2,}/g,p+" "),o.forEach((s,t)=>{e=e.replace(`__PROTECTED_URL_${t}__`,s)}),_.forEach((s,t)=>{e=e.replace(`__PROTECTED_EMAIL_${t}__`,s)}),a.forEach((s,t)=>{e=e.replace(`__PROTECTED_MENTION_${t}__`,s)}),e}function I(r){if(!r||typeof r!="string")return{sanitized_text:""};let o=new f.JSDOM(`<body>${r}</body>`).window.document,_=a=>{a.nodeType===3?a.textContent&&(a.textContent=T(a.textContent)):a.childNodes.forEach(_)};return _(o.body),{sanitized_text:o.body.innerHTML.trim()}}var O=T;0&&(module.exports={sanitizeContent,sanitizeDescription});
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{JSDOM as T}from"jsdom";var p={CONNECTION_STRING:/([a-z0-9+.-]+:\/\/)([^:@\s]+):([^:@\s]+)@/gi,SQL_INSERT:/\bINSERT\s+INTO\b.*?\((?:[^)]*,\s*)?\b(password|pwd|pass|passcode)\b.*?\)\s*VALUES\s*\((?:[^,']*,|[^,"]*,)*\s*['"]([^'"]+)['"]/gi,HTML_INPUT:/<input[^>]+(?:type=["']password["'](?:\s+[^>]*?)?value=["']([^"']*)["']|value=["']([^"']*)["'](?:\s+[^>]*?)?type=["']password["'])/gi,QUERY_PARAM:/([?&])(api[_-]?key|access[_-]?token|secret|password|pass|passwrod|psswrd|pw|pwd|token|key|auth[_-]?token|u|p|user|username|passcode|wifi[_-]?password|p_?w_?d|confirm[_-]?password|confirm[_-]?pwd)=([^&\s<"']+)/gi,AUTH_TOKEN:/\b(authorization|auth[_-]?token)\s*[:=]\s*(bearer|basic|token)?\s*([a-zA-Z0-9.\-_~+/]{8,})|(?:\b(bearer|basic|token)\s+([a-zA-Z0-9.\-_~+/]{8,}))/gi,JWT:/\beyJ[a-zA-Z0-9._-]{10,}\b/gi,BASE64_PASS:/cGFzc3dvcmQ9[a-zA-Z0-9+/=]+/g,USER_PASS:/\b(user(?:name)?|login)\b\s*[:=\s/]\s*([^"'\s,]+)\s*(?:and\s+)?\b(pass(?:word)?|pwd|p|p_?w_?d)\b\s*[:=\s]\s*([^"'\s<,]+)/gi,SLASH_CRED:/\b(admin|user|root|api_?user)\/([^"'\s,;]{3,})\b/gi,CURL_AUTH:/(^|\s)(-u\s+)([^:\s]+):([^:\s\\]+)/gi,ASSIGNMENT:/\b(DB[_-]?PASSWORD|JWT[_-]?SECRET|SECRET[_-]?KEY|AUTH[_-]?PASSWORD|PASSWORD|SECRET|KEY|WIFI[_-]?PASSWORD|PASSCODE|API[_-]?KEY|CONFIRM[_-]?PASSWORD|PASSWROD)\s*[:=]\s*(?:["']?)([^"'\s;<>]{3,})(?:["']?)/gi,XML_TAG:/<([^>]*password|pass|secret|token|key)>([^<]+)<\/\1>/gi,LABEL_HINT:/(?:\b|["'<])(password|pass|passwrod|psswrd|pw|pwd|api[_-]?key|access[_-]?token|auth[_-]?token|credentials|creds|secret|token|key|passcode|wifi[_-]?password|p_?w_?d|u|p|confirm[_-]?password|confirm[_-]?pwd|actual|temp|temporary|new\s+one|old\s+one|new\s+password|old\s+password)(?:\b|["'>])[^a-zA-Z0-9\s]*\s*(?:[:=\s]|was\s+something\s+like|it\s+was\s+something\s+like|was|is|like|should\s+be|actual\s+was|could\s+be|might\s+be|set\s+to|entered)(?:\s+it)?\s*[:=]?\s*(?:["']?)([^"'\s<>&,;?]+)(?:["']?)(?:\s+or\s+([^"'\s<>&,;?]+))?/gi,URL:/\bhttps?:\/\/[^\s"'<>]+/gi,EMAIL:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,MENTION:/(^|\s|[(\[])(@([a-zA-Z0-9._-]+))/g},a="[REDACTED]",g=/^(value|type|name|id|class|and|or|was|is|it|the|set|to|values|into|select|from|where|union|join|table|input|button|form|label|div|span|script|style|html|body|head|meta|link|header|footer|auth|login|signin|signout|logout|session|cookie|token|true|false|null|undefined|error|success|failed|warn|info|debug|trace|admin|user|root|for|test|testing|staging|placeholder|password|pass|pwd|psswrd|passwrod|token|key|api[_-]?key|secret|hidden|entered|shown|verified)$/i;function l(n,e,i){if(!i||i===a||i.length<1||i.includes(a)||i.includes("__PROTECTED_"))return n;let c=i.replace(/["']/g,"").trim();if(c.length<2||g.test(c)||c.toLowerCase()===e.toLowerCase())return n;let d=n.toLowerCase().indexOf(e.toLowerCase());if(d===-1)return n;let t=n.substring(d+e.length).indexOf(i);if(t===-1)return n;let r=d+e.length+t;return n.substring(0,r)+a+n.substring(r+i.length)}function f(n){return n.replace(/(?<!\w)([A-Za-z\d@$!%*#?&^()_\-+=]{7,64})(?!\w)/g,e=>{if(/^__PROTECTED_/.test(e)||e.includes(a)||g.test(e))return e;let i=/[A-Z]/.test(e),c=/[a-z]/.test(e),d=/\d/.test(e),s=/[@$!%*#?&^()_\-+=]/.test(e);return[i,c,d,s].filter(Boolean).length>=3?a:e})}function w(n){if(!n||typeof n!="string")return n;let e=n;e=e.replace(p.CONNECTION_STRING,"$1"+a+"@"),e=e.replace(p.QUERY_PARAM,"$1$2="+a),e=e.replace(p.XML_TAG,(s,t,r)=>`<${t}>${a}</${t}>`);let i=[];e=e.replace(p.URL,s=>{let t=`__PROTECTED_URL_${i.length}__`;return i.push(s),t});let c=[];e=e.replace(p.EMAIL,s=>{let t=`__PROTECTED_EMAIL_${c.length}__`;return c.push(s),t});let d=[];if(e=e.replace(p.MENTION,(s,t,r)=>{let o=`__PROTECTED_MENTION_${d.length}__`;return d.push(r),t+o}),e=e.replace(p.SQL_INSERT,(s,t,r)=>s.replace(r,a)),e=e.replace(p.HTML_INPUT,(s,t,r)=>{let o=t||r;return o?l(s,"password",o):s}),e=e.replace(p.AUTH_TOKEN,(s,t,r,o,_,u)=>{if(_&&u)return`${_} ${a}`;let E=r?`${r} `:"";return`${t}: ${E}${a}`}),e=e.replace(p.JWT,a),e=e.replace(p.BASE64_PASS,"cGFzc3dvcmQ9W1JFREFDVEVEX1BBU1NXT1JEXQ=="),e=e.replace(p.USER_PASS,(s,t,r,o,_)=>l(s,o,_)),e=e.replace(p.CURL_AUTH,"$1$2$3:"+a),e=e.replace(p.ASSIGNMENT,(s,t,r)=>l(s,t,r)),e=e.replace(p.SLASH_CRED,"$1/"+a),e=e.replace(p.LABEL_HINT,(s,t,r,o)=>{let _=l(s,t,r);return o&&(_=l(_,a,o)),_}),e.toLowerCase().includes("password")&&e.includes(",")){let s=e.split(/\r?\n/),t=-1,r=-1;for(let o=0;o<s.length;o++)if(s[o].includes(",")&&!s[o].toUpperCase().includes("VALUES")){let u=s[o].toLowerCase().split(",").findIndex(E=>E.includes("password")||E.trim()==="pwd");if(u!==-1){t=o,r=u;break}}if(t!==-1){for(let o=t+1;o<s.length;o++){let _=s[o].split(",");_.length>r&&_[r].trim().length>0&&(g.test(_[r].trim())||(_[r]=a,s[o]=_.join(",")))}e=s.join(`
2
+ `)}}return e=f(e),e=e.replace(/(\[REDACTED\]\s*){2,}/g,a+" "),i.forEach((s,t)=>{e=e.replace(`__PROTECTED_URL_${t}__`,s)}),c.forEach((s,t)=>{e=e.replace(`__PROTECTED_EMAIL_${t}__`,s)}),d.forEach((s,t)=>{e=e.replace(`__PROTECTED_MENTION_${t}__`,s)}),e}function S(n){if(!n||typeof n!="string")return{sanitized_text:""};let i=new T(`<body>${n}</body>`).window.document,c=d=>{d.nodeType===3?d.textContent&&(d.textContent=w(d.textContent)):d.childNodes.forEach(c)};return c(i.body),{sanitized_text:i.body.innerHTML.trim()}}var R=w;export{R as default,w as sanitizeContent,S as sanitizeDescription};
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "sanitize-contents",
3
+ "version": "1.0.0",
4
+ "description": "A robust library to sanitize sensitive information from content.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean --minify",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest",
22
+ "lint": "eslint src/**/*.ts",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "keywords": [
26
+ "sanitize",
27
+ "redact",
28
+ "security",
29
+ "password",
30
+ "sensitive",
31
+ "content"
32
+ ],
33
+ "author": "Kishan",
34
+ "license": "ISC",
35
+ "devDependencies": {
36
+ "tsup": "^8.0.1",
37
+ "typescript": "^5.3.3",
38
+ "vitest": "^1.2.1"
39
+ },
40
+ "dependencies": {
41
+ "@types/jsdom": "^27.0.0",
42
+ "jsdom": "^27.3.0"
43
+ }
44
+ }