Sanitize rather than strip html

This commit is contained in:
Jon Staab
2024-06-11 12:41:56 -07:00
parent 289d2fb8f9
commit 9c9e483f01
6 changed files with 35 additions and 39 deletions
+1
View File
@@ -7,4 +7,5 @@ This is a monorepo which is split into several different packages:
- [@welshman/lib](./packages/lib) - generic utility functions. - [@welshman/lib](./packages/lib) - generic utility functions.
- [@welshman/util](./packages/util) - various nostr-specific utilities. - [@welshman/util](./packages/util) - various nostr-specific utilities.
- [@welshman/net](./packages/net) - framework for interacting with relays. - [@welshman/net](./packages/net) - framework for interacting with relays.
- [@welshman/content](./packages/content) - utilities for parsing and rendering notes.
- [@welshman/feeds](./packages/feeds) - an interpreter for custom nostr feeds. - [@welshman/feeds](./packages/feeds) - an interpreter for custom nostr feeds.
+6 -31
View File
@@ -4,7 +4,6 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "welshman",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
] ]
@@ -115,6 +114,11 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/@braintree/sanitize-url": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.0.2.tgz",
"integrity": "sha512-NVf/1YycDMs6+FxS0Tb/W8MjJRDQdXF+tBfDtZ5UZeiRUkTmwKc4vmYCKZTyymfJk1gnMsauvZSX/HiV9jOABw=="
},
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0", "version": "4.4.0",
"dev": true, "dev": true,
@@ -324,12 +328,6 @@
"version": "3.0.3", "version": "3.0.3",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/insane": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/insane/-/insane-1.0.0.tgz",
"integrity": "sha512-9FNbmwdaQezEszc5B/w4kRSpMJMOVj+gX7CKSbBCFO4WPiUqKO3HJlUNXzjtus0w5tF2BOJoKTbyps/Envlg/Q==",
"dev": true
},
"node_modules/@types/json-schema": { "node_modules/@types/json-schema": {
"version": "7.0.15", "version": "7.0.15",
"dev": true, "dev": true,
@@ -673,11 +671,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/assignment": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/assignment/-/assignment-2.0.0.tgz",
"integrity": "sha512-naMULXjtgCs9SVUEtyvJNt68aF18em7/W+dhbR59kbz9cXWPEvUkCun2tqlgqRPSqZaKPpqLc5ZnwL8jVmJRvw=="
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"dev": true, "dev": true,
@@ -1556,14 +1549,6 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/he": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/he/-/he-0.5.0.tgz",
"integrity": "sha512-DoufbNNOFzwRPy8uecq+j+VCPQ+JyDelHTmSgygrA5TsR8Cbw4Qcir5sGtWiusB4BdT89nmlaVDhSJOqC/33vw==",
"bin": {
"he": "bin/he"
}
},
"node_modules/hosted-git-info": { "node_modules/hosted-git-info": {
"version": "4.1.0", "version": "4.1.0",
"dev": true, "dev": true,
@@ -1670,15 +1655,6 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/insane": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/insane/-/insane-2.6.2.tgz",
"integrity": "sha512-BqEL1CJsjJi+/C/zKZxv31zs3r6zkLH5Nz1WMFb7UBX2KHY2yXDpbFTSEmNHzomBbGDysIfkTX55A0mQZ2CQiw==",
"dependencies": {
"assignment": "2.0.0",
"he": "0.5.0"
}
},
"node_modules/is-arrayish": { "node_modules/is-arrayish": {
"version": "0.2.1", "version": "0.2.1",
"dev": true, "dev": true,
@@ -3100,11 +3076,10 @@
"version": "0.0.4", "version": "0.0.4",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"insane": "^2.6.2", "@braintree/sanitize-url": "^7.0.2",
"nostr-tools": "^2.7.0" "nostr-tools": "^2.7.0"
}, },
"devDependencies": { "devDependencies": {
"@types/insane": "^1.0.0",
"gts": "^5.0.1", "gts": "^5.0.1",
"tsc-multi": "^1.1.0", "tsc-multi": "^1.1.0",
"typescript": "~5.1.6" "typescript": "~5.1.6"
+8
View File
@@ -1,3 +1,11 @@
# @welshman/content [![version](https://badgen.net/npm/v/@welshman/content)](https://npmjs.com/package/@welshman/content) # @welshman/content [![version](https://badgen.net/npm/v/@welshman/content)](https://npmjs.com/package/@welshman/content)
Utilities for parsing note content. Utilities for parsing note content.
```typescript
import {truncate, parse, render} from '@welshman/content'
const content = "Hello<br>from https://coracle.tools! <script>alert('evil')</script>"
const html = truncate(parse({content})).map(render).join("")
// =>
```
+18 -5
View File
@@ -1,5 +1,5 @@
import {nip19} from "nostr-tools" import {nip19} from "nostr-tools"
import insane from 'insane' import {sanitizeUrl} from '@braintree/sanitize-url'
const last = <T>(xs: T[], ...args: unknown[]) => xs[xs.length - 1] const last = <T>(xs: T[], ...args: unknown[]) => xs[xs.length - 1]
@@ -431,12 +431,25 @@ export class HTML {
toString = () => this.value toString = () => this.value
static useSafely = (value: string) => new HTML(insane(value))
static useDangerously = (value: string) => new HTML(value) static useDangerously = (value: string) => new HTML(value)
static buildLink = (href: string, display: string) => static useSafely = (value: string) => {
HTML.useSafely(`<a href=${href} target="_blank">${display}</a>`) const element = document.createElement('div')
element.innerText = value
return new HTML(element.innerHTML)
}
static buildLink = (href: string, display: string) => {
const element = document.createElement('a')
element.href = sanitizeUrl(href)
element.target = "_blank"
element.innerText = display
return HTML.useDangerously(element.outerHTML)
}
static buildEntityLink = (entity: string, options: RenderOptions) => static buildEntityLink = (entity: string, options: RenderOptions) =>
HTML.buildLink(options.entityBaseUrl + entity, entity.slice(0, 16) + '…') HTML.buildLink(options.entityBaseUrl + entity, entity.slice(0, 16) + '…')
+1 -2
View File
@@ -26,13 +26,12 @@
"fix": "gts fix" "fix": "gts fix"
}, },
"devDependencies": { "devDependencies": {
"@types/insane": "^1.0.0",
"gts": "^5.0.1", "gts": "^5.0.1",
"tsc-multi": "^1.1.0", "tsc-multi": "^1.1.0",
"typescript": "~5.1.6" "typescript": "~5.1.6"
}, },
"dependencies": { "dependencies": {
"insane": "^2.6.2", "@braintree/sanitize-url": "^7.0.2",
"nostr-tools": "^2.7.0" "nostr-tools": "^2.7.0"
} }
} }
+1 -1
View File
@@ -64,7 +64,7 @@ export class FeedLoader<E extends TrustedEvent> {
} }
} }
async _getRequestLoader({relays, filters}: RequestItem, {useWindowing, onEvent, onExhausted}: LoadOpts<E>) { async _getRequestLoader({relays, filters}: RequestItem, {useWindowing = true, onEvent, onExhausted}: LoadOpts<E>) {
// Make sure we have some kind of filter to send if we've been given an empty one, as happens with relay feeds // Make sure we have some kind of filter to send if we've been given an empty one, as happens with relay feeds
if (!filters || filters.length === 0) { if (!filters || filters.length === 0) {
filters = [{}] filters = [{}]