openvibers/openvibe.community Commits
A paste link that picked up trailing punctuation (a full stop, a bracket, Markdown's **) redirects to the paste instead of answering Paste not found (#146)
Changes
@@@ -359,6 +359,23 @@ async function createApp(opts = {}) {// Old Live-style /pastes/<slug> links and bare slugs land on the paste page.app.get('/pastes/:slug', (req, res) => res.redirect(301, `/p/${encodeURIComponent(req.params.slug)}`));++ // A paste link copied out of a chat or a document often carries what followed it: a full stop, a bracket, Markdown's++ // ** around it. Characters no slug can hold are dropped from its end with a redirect, not answered "Paste not found".++ app.get(/^\/p\/[^/]+(?:\/(?:raw|screenshot|download))?\/?$/, (req, res, next) => {++ const [, , raw, rest = ''] = req.path.match(/^\/(p)\/([^/]+)((?:\/[a-z]+)?)\/?$/) || [];++ let seg;++ try {++ seg = decodeURIComponent(raw || '');++ } catch {++ return next();++ }++ if (SLUG_RE.test(seg)) return next();++ const clean = seg.replace(/[^A-Za-z0-9_-]+$/, '');++ if (!SLUG_RE.test(clean)) return next();++ const q = req.originalUrl.indexOf('?');++ res.redirect(301, `/p/${clean}${rest}${q >= 0 ? req.originalUrl.slice(q) : ''}`);++ });++app.get('/p/:slug', withUser, wrap(async (req, res) => {const { slug } = req.params;if (!SLUG_RE.test(slug)) return html(res, pages.errorPage({ status: 404, title: 'Paste not found', message: 'That link does not point at a paste.' }), 404);@@@ -93,6 +93,25 @@ const { boot, check, done } = require('./helpers/app');assert.ok(!lang.text.includes(`href="/p/${js}"`));});++ await check('a link that picked up trailing punctuation (**, a full stop, a bracket) redirects to the paste', async () => {++ for (const [path, to] of [++ [`/p/${js}**`, `/p/${js}`],++ [`/p/${js}.`, `/p/${js}`],++ [`/p/${js})`, `/p/${js}`],++ [`/p/${js}%2A%2A`, `/p/${js}`],++ [`/p/${js}),/raw?dl=1`, `/p/${js}/raw?dl=1`],++ [`/p/${js}./download`, `/p/${js}/download`],++ ]) {++ const r = await t.get(path);++ assert.strictEqual(r.status, 301, path);++ assert.strictEqual(r.headers.get('location'), to, path);++ }++ // Nothing left to point at, or junk in the middle: still "Paste not found".++ assert.strictEqual((await t.get('/p/**')).status, 404);++ assert.strictEqual((await t.get(`/p/${js.slice(0, 4)}*${js.slice(4)}`)).status, 404);++ assert.strictEqual((await t.get(`/p/${js}`)).status, 200);++ });++await check('/my lists the signed-in person\'s pastes, private and unlisted included', async () => {const mine = await t.get('/my', { cookies: [`ov_token=${token}`] });assert.strictEqual(mine.status, 200);
@@ -359,6 +359,23 @@ async function createApp(opts = {}) {
@@ -359,6 +359,23 @@ async function createApp(opts = {}) {
// Old Live-style /pastes/<slug> links and bare slugs land on the paste page.
// Old Live-style /pastes/<slug> links and bare slugs land on the paste page.
app.get('/pastes/:slug', (req, res) => res.redirect(301, `/p/${encodeURIComponent(req.params.slug)}`));
app.get('/pastes/:slug', (req, res) => res.redirect(301, `/p/${encodeURIComponent(req.params.slug)}`));
+ // A paste link copied out of a chat or a document often carries what followed it: a full stop, a bracket, Markdown's
+ // ** around it. Characters no slug can hold are dropped from its end with a redirect, not answered "Paste not found".
+ app.get(/^\/p\/[^/]+(?:\/(?:raw|screenshot|download))?\/?$/, (req, res, next) => {
+ const [, , raw, rest = ''] = req.path.match(/^\/(p)\/([^/]+)((?:\/[a-z]+)?)\/?$/) || [];
+ let seg;
+ try {
+ seg = decodeURIComponent(raw || '');
+ } catch {
+ return next();
+ }
+ if (SLUG_RE.test(seg)) return next();
+ const clean = seg.replace(/[^A-Za-z0-9_-]+$/, '');
+ if (!SLUG_RE.test(clean)) return next();
+ const q = req.originalUrl.indexOf('?');
+ res.redirect(301, `/p/${clean}${rest}${q >= 0 ? req.originalUrl.slice(q) : ''}`);
+ });
+
app.get('/p/:slug', withUser, wrap(async (req, res) => {
app.get('/p/:slug', withUser, wrap(async (req, res) => {
const { slug } = req.params;
const { slug } = req.params;
if (!SLUG_RE.test(slug)) return html(res, pages.errorPage({ status: 404, title: 'Paste not found', message: 'That link does not point at a paste.' }), 404);
if (!SLUG_RE.test(slug)) return html(res, pages.errorPage({ status: 404, title: 'Paste not found', message: 'That link does not point at a paste.' }), 404);
@@ -93,6 +93,25 @@ const { boot, check, done } = require('./helpers/app');
@@ -93,6 +93,25 @@ const { boot, check, done } = require('./helpers/app');
assert.ok(!lang.text.includes(`href="/p/${js}"`));
assert.ok(!lang.text.includes(`href="/p/${js}"`));
});
});
+ await check('a link that picked up trailing punctuation (**, a full stop, a bracket) redirects to the paste', async () => {
+ for (const [path, to] of [
+ [`/p/${js}**`, `/p/${js}`],
+ [`/p/${js}.`, `/p/${js}`],
+ [`/p/${js})`, `/p/${js}`],
+ [`/p/${js}%2A%2A`, `/p/${js}`],
+ [`/p/${js}),/raw?dl=1`, `/p/${js}/raw?dl=1`],
+ [`/p/${js}./download`, `/p/${js}/download`],
+ ]) {
+ const r = await t.get(path);
+ assert.strictEqual(r.status, 301, path);
+ assert.strictEqual(r.headers.get('location'), to, path);
+ }
+ // Nothing left to point at, or junk in the middle: still "Paste not found".
+ assert.strictEqual((await t.get('/p/**')).status, 404);
+ assert.strictEqual((await t.get(`/p/${js.slice(0, 4)}*${js.slice(4)}`)).status, 404);
+ assert.strictEqual((await t.get(`/p/${js}`)).status, 200);
+ });
+
await check('/my lists the signed-in person\'s pastes, private and unlisted included', async () => {
await check('/my lists the signed-in person\'s pastes, private and unlisted included', async () => {
const mine = await t.get('/my', { cookies: [`ov_token=${token}`] });
const mine = await t.get('/my', { cookies: [`ov_token=${token}`] });
assert.strictEqual(mine.status, 200);
assert.strictEqual(mine.status, 200);