From 567a75309f69d495ff55a1dc6b43a4774c69fe31 Mon Sep 17 00:00:00 2001 From: cel Date: Fri, 27 Nov 2020 12:18:06 -0500 Subject: Add mentions for ssb URIs --- lib/serve.js | 42 ++---------------------------------------- lib/util.js | 37 +++++++++++++++++++++++++++++++++++++ vendor/ssb-mentions.js | 6 ++++++ 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/lib/serve.js b/lib/serve.js index 67b57c7..50bfff2 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -25,15 +25,12 @@ var split = require('pull-split') var utf8 = require('pull-utf8-decoder') var webresolve = require('ssb-web-resolver') var Url = require('url') -var Base64URL = require('base64-url') module.exports = Serve var hlCssDir = path.join(require.resolve('highlight.js'), '../../styles') -var ssbURIRegex = /^(ssb:(message|blob|feed)([:\/])([^:?]*?)([:/])([^?]*)(\\?.*)?)$/ var urlIdRegex = /^(?:\/+(([%&@]|%25|%26)(?:[A-Za-z0-9\/+]|%2[Ff]|%2[Bb]){43}(?:=|%3D)\.(?:sha256|ed25519))([^?]*)?|(\/.*?))(?:\?(.*))?$/ -var gitSsbRepoIdRegex = /^ssb:\/\/(%[A-Za-z0-9\/+]{43}=\.sha256)(\?.*)?$/ function ctype(name) { switch (name && /[^.\/]*$/.exec(name)[0] || 'html') { @@ -451,41 +448,6 @@ Serve.prototype.publishMayRedirect = function (content, cb) { } } -Serve.prototype.translateFromGitSsbRepoId = function (url) { - var m = gitSsbRepoIdRegex.exec(url) - if (!m) return - var id = m[1] - var qs = m[2] || '' - return id + qs -} - -Serve.prototype.translateFromURI = function (url) { - var m = ssbURIRegex.exec(url) - if (!m) return this.translateFromGitSsbRepoId(url) - var uri = m[1] - var prefix = m[2] - var separator = m[3] - var format = m[4] - var separator2 = m[5] - var hash = m[6] - var qs = m[7] || '' - if (separator !== separator2) return - hash = Base64URL.unescape(hash) - if (separator === '/') { - // ssb-custom-uri - try { hash = decodeURIComponent(hash) } - catch(e) {} - } - var sigil - switch (prefix) { - case 'message': sigil = '%'; break - case 'blob': sigil = '&'; break - case 'feed': sigil = '@'; break - default: return - } - return sigil + hash + '.' + format + qs -} - Serve.prototype.handle = function () { var m = urlIdRegex.exec(this.req.url) this.query = m[5] ? qs.parse(m[5]) : {} @@ -538,7 +500,7 @@ Serve.prototype.redirect = function (dest) { Serve.prototype.path = function (url) { if (url.substr(0, 5) === '/ssb:') { - var link = this.translateFromURI(url.substr(1)) + var link = u.translateFromURI(url.substr(1)) if (link) return this.redirect(this.app.render.toUrl(link)) } var m @@ -774,7 +736,7 @@ Serve.prototype.search = function (ext) { var maybeId = searchQ.substr(6) if (u.isRef(maybeId)) searchQ = maybeId } - var link = this.translateFromURI(searchQ) + var link = u.translateFromURI(searchQ) if (link) return self.redirect(self.app.render.toUrl(link)) if (u.isRef(searchQ) || searchQ[0] === '#') { diff --git a/lib/util.js b/lib/util.js index 2fa5c63..e62bde9 100644 --- a/lib/util.js +++ b/lib/util.js @@ -8,6 +8,8 @@ u.ssbRefRegex = /((?:@|%|&|ssb:\/\/%)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g u.ssbRefRegexOnly = /^(?:@|%|&|ssb:\/\/%)[A-Za-z0-9\/+]{43}=\.[\w\d]+$/ u.ssbRefEncRegex = /((?:ssb:\/\/)?(?:[@%&]|%26|%40|%25)(?:[A-Za-z0-9\/+]|%2[fF]|%2[bB]){43}(?:=|%3[dD])\.[\w\d]+)/g u.channelRegex = /^#[^\s#]+$/ +u.ssbURIRegex = /^(ssb:(message|blob|feed)([:\/])([^:?]*?)([:/])([^?]*)(\\?.*)?)$/ +u.gitSsbRepoIdRegex = /^ssb:\/\/(%[A-Za-z0-9\/+]{43}=\.sha256)(\?.*)?$/ u.isRef = function (str) { if (!str) return false @@ -292,3 +294,38 @@ u.extractHostPort = function (id, addr) { } return addr } + +u.translateFromGitSsbRepoId = function (url) { + var m = u.gitSsbRepoIdRegex.exec(url) + if (!m) return + var id = m[1] + var qs = m[2] || '' + return id + qs +} + +u.translateFromURI = function (url) { + var m = u.ssbURIRegex.exec(url) + if (!m) return u.translateFromGitSsbRepoId(url) + var uri = m[1] + var prefix = m[2] + var separator = m[3] + var format = m[4] + var separator2 = m[5] + var hash = m[6] + var qs = m[7] || '' + if (separator !== separator2) return + hash = b64url.unescape(hash) + if (separator === '/') { + // ssb-custom-uri + try { hash = decodeURIComponent(hash) } + catch(e) {} + } + var sigil + switch (prefix) { + case 'message': sigil = '%'; break + case 'blob': sigil = '&'; break + case 'feed': sigil = '@'; break + default: return + } + return sigil + hash + '.' + format + qs +} diff --git a/vendor/ssb-mentions.js b/vendor/ssb-mentions.js index b01bf9a..37e7678 100644 --- a/vendor/ssb-mentions.js +++ b/vendor/ssb-mentions.js @@ -2,6 +2,7 @@ ssb-mentions Copyright (c) 2016 Dominic Tarr +Copyright (c) 2020 Charles Lehner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and @@ -27,6 +28,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. var ref = require('ssb-ref') var marked = require('./ssb-marked') +var u = require('../lib/util') function noop(){} var onLink = noop var extractor = new marked.Renderer() @@ -91,6 +93,10 @@ module.exports = function (text, opts) { var emoji = opts && opts.emoji var a = [] links(text, function (link) { + if (link.target && typeof link.target === 'string' + && link.target.substr(0, 4) === 'ssb:') { + link.target = u.translateFromURI(link.target) || link.target + } var result = link.target && ref.parseLink(link.target) if (result) { result.name = link.label && link.label.replace(/^@/, '') -- cgit v1.2.3