From ac8bc0ba43c5bed891e999c57fd51787f0db4c6d Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Sat, 20 Jan 2024 23:49:46 +0000 Subject: [PATCH 1/4] feat: add support for OpenSearch browser hinting. Signed-off-by: Andy Piper --- package.json | 6 +++-- server.js | 4 +++ src/pages/layouts/main.hbs | 1 + src/routes/index.js | 2 ++ src/routes/opensearch.js | 53 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/routes/opensearch.js diff --git a/package.json b/package.json index c3f5cd7..590a109 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "sqlite": "^5.0.1", "sqlite3": "^5.1.5", "string-strip-html": "^13.4.2", - "escape-html": "^1.0.3" + "escape-html": "^1.0.3", + "xml2js": "^0.6.2" }, "engines": { "node": ">=16.x" @@ -43,7 +44,8 @@ "fediverse", "express", "activitypub", - "mastodon" + "mastodon", + "bookmarks" ], "devDependencies": { "eslint": "^8.43.0", diff --git a/server.js b/server.js index c2d7137..e75268a 100644 --- a/server.js +++ b/server.js @@ -73,6 +73,9 @@ const hbs = create({ projectUrl() { return `https://${app.get('domain')}`; }, + searchUrl() { + return `https://${app.get('domain')}/opensearch.xml`; + }, glitchProjectName() { return process.env.PROJECT_DOMAIN; }, @@ -125,5 +128,6 @@ app.use('/', routes.core); app.use('/api/inbox', cors(), routes.inbox); app.use('/.well-known/nodeinfo', routes.nodeinfo); app.use('/nodeinfo/2.0', routes.nodeinfo); +app.use('/opensearch.xml', routes.opensearch); app.listen(PORT, () => console.log(`App listening on port ${PORT}`)); diff --git a/src/pages/layouts/main.hbs b/src/pages/layouts/main.hbs index 7e060ea..8b7f468 100644 --- a/src/pages/layouts/main.hbs +++ b/src/pages/layouts/main.hbs @@ -11,6 +11,7 @@ {{title}} | {{siteName}} + diff --git a/src/routes/index.js b/src/routes/index.js index 70e0b6d..71c9b69 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -8,6 +8,7 @@ import message from './activitypub/message.js'; import user from './activitypub/user.js'; import webfinger from './activitypub/webfinger.js'; import nodeinfo from './activitypub/nodeinfo.js'; +import opensearch from './opensearch.js'; export default { admin, @@ -20,4 +21,5 @@ export default { user, webfinger, nodeinfo, + opensearch, }; diff --git a/src/routes/opensearch.js b/src/routes/opensearch.js new file mode 100644 index 0000000..661841a --- /dev/null +++ b/src/routes/opensearch.js @@ -0,0 +1,53 @@ +import express from 'express'; +import xml2js from 'xml2js'; + +const router = express.Router(); + +router.get('/', async (req, res) => { + const domain = req.app.get('domain'); + const searchUrl = `https://${domain}/search`; + + var obj = { + OpenSearchDescription: { + $: { + xmlns: 'http://a9.com/-/spec/opensearch/1.1/', + 'xmlns:moz': 'http://www.mozilla.org/2006/browser/search/', + }, + ShortName: 'Postmarks', + Description: 'Search your Postmarks', + InputEncoding: 'UTF-8', + Image: { + $: { + width: '16', + height: '16', + type: 'image/png', + }, + _: 'https://cdn.glitch.global/8eaf209c-2fa9-4353-9b99-e8d8f3a5f8d4/postmarks-favicon.ico?v=1693611323474', + }, + Url: { + $: { + type: 'text/html', + method: 'get', + template: `${searchUrl}?query={searchTerms}&ref=opensearch`, + }, + }, + 'moz:SearchForm': { + _: `${searchUrl}`, + }, + Query: { + $: { + role: 'example', + searchTerms: 'postmarks', + }, + }, + }, + }; + + var builder = new xml2js.Builder({headless: true}); + var xml = builder.buildObject(obj); + + res.header('Content-Type', 'application/opensearchdescription+xml'); + res.status(200).send(xml); +}); + +export default router; From 8cfacab232284f10e24fdf02a1fbcb0240e63fdf Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Sun, 21 Jan 2024 00:13:35 +0000 Subject: [PATCH 2/4] sync package-lock Signed-off-by: Andy Piper --- package-lock.json | 48 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44cf298..0113c3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "requires": true, "packages": { "": { - "name": "postmarks", "version": "0.0.1", "license": "MIT", "dependencies": { @@ -26,7 +25,8 @@ "open-graph-scraper": "^5.2.3", "sqlite": "^5.0.1", "sqlite3": "^5.1.5", - "string-strip-html": "^13.4.2" + "string-strip-html": "^13.4.2", + "xml2js": "^0.6.2" }, "devDependencies": { "eslint": "^8.43.0", @@ -5371,6 +5371,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -6161,6 +6166,26 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -10010,6 +10035,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -10599,6 +10629,20 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", From 183b1acd79c0c226425e8d45c4f5ecfb8a5fb23c Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Sun, 21 Jan 2024 00:18:31 +0000 Subject: [PATCH 3/4] fix linting --- src/routes/opensearch.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/opensearch.js b/src/routes/opensearch.js index 661841a..0432509 100644 --- a/src/routes/opensearch.js +++ b/src/routes/opensearch.js @@ -7,7 +7,7 @@ router.get('/', async (req, res) => { const domain = req.app.get('domain'); const searchUrl = `https://${domain}/search`; - var obj = { + let obj = { OpenSearchDescription: { $: { xmlns: 'http://a9.com/-/spec/opensearch/1.1/', @@ -43,8 +43,8 @@ router.get('/', async (req, res) => { }, }; - var builder = new xml2js.Builder({headless: true}); - var xml = builder.buildObject(obj); + const builder = new xml2js.Builder({ headless: true }); + const xml = builder.buildObject(obj); res.header('Content-Type', 'application/opensearchdescription+xml'); res.status(200).send(xml); From ac341cc3e90808fd5c0f63ee2457f318418f55e7 Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Sun, 21 Jan 2024 00:19:38 +0000 Subject: [PATCH 4/4] let -> const --- src/routes/opensearch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/opensearch.js b/src/routes/opensearch.js index 0432509..983b84a 100644 --- a/src/routes/opensearch.js +++ b/src/routes/opensearch.js @@ -7,7 +7,7 @@ router.get('/', async (req, res) => { const domain = req.app.get('domain'); const searchUrl = `https://${domain}/search`; - let obj = { + const obj = { OpenSearchDescription: { $: { xmlns: 'http://a9.com/-/spec/opensearch/1.1/',