diff --git a/services/suggest.integration.js b/services/suggest.integration.js index 8f6532ae44..f3c0c82fd9 100644 --- a/services/suggest.integration.js +++ b/services/suggest.integration.js @@ -101,12 +101,11 @@ describe('GitHub badge suggestions', function() { link: 'https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2Fatom%2Fatom', example: { - pattern: '/twitter/url/:protocol(https|http)/:hostAndPath+', - namedParams: { - protocol: 'https', - hostAndPath: 'github.com/atom/atom', + pattern: '/twitter/url', + namedParams: {}, + queryParams: { + url: 'https://github.com/atom/atom', }, - queryParams: {}, }, preview: { style: 'social', @@ -173,12 +172,11 @@ describe('GitHub badge suggestions', function() { link: 'https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2Fbadges%2Fnot-a-real-project', example: { - pattern: '/twitter/url/:protocol(https|http)/:hostAndPath+', - namedParams: { - protocol: 'https', - hostAndPath: 'github.com/badges/not-a-real-project', + pattern: '/twitter/url', + namedParams: {}, + queryParams: { + url: 'https://github.com/badges/not-a-real-project', }, - queryParams: {}, }, preview: { style: 'social', diff --git a/services/suggest.js b/services/suggest.js index 812df9a7e9..dd8ebc988e 100644 --- a/services/suggest.js +++ b/services/suggest.js @@ -23,9 +23,9 @@ function twitterPage(url) { url.href )}`, example: { - pattern: '/twitter/url/:protocol(https|http)/:hostAndPath+', - namedParams: { protocol: `${schema}`, hostAndPath: `${host}${path}` }, - queryParams: {}, + pattern: '/twitter/url', + namedParams: {}, + queryParams: { url: `${schema}://${host}${path}` }, }, preview: { style: 'social', diff --git a/services/suggest.spec.js b/services/suggest.spec.js index 51549bf5ca..bc27a1f40e 100644 --- a/services/suggest.spec.js +++ b/services/suggest.spec.js @@ -160,12 +160,11 @@ describe('Badge suggestions', function() { link: 'https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2Fatom%2Fatom', example: { - pattern: '/twitter/url/:protocol(https|http)/:hostAndPath+', - namedParams: { - protocol: 'https', - hostAndPath: 'github.com/atom/atom', + pattern: '/twitter/url', + namedParams: {}, + queryParams: { + url: 'https://github.com/atom/atom', }, - queryParams: {}, }, preview: { style: 'social', diff --git a/services/twitter/twitter-redirect.service.js b/services/twitter/twitter-redirect.service.js new file mode 100644 index 0000000000..b7cacce786 --- /dev/null +++ b/services/twitter/twitter-redirect.service.js @@ -0,0 +1,19 @@ +'use strict' + +const { redirector } = require('..') + +module.exports = [ + redirector({ + category: 'social', + name: 'TwitterUrlRedirect', + route: { + base: 'twitter/url', + pattern: ':protocol(https|http)/:hostAndPath+', + }, + transformPath: () => `/twitter/url`, + transformQueryParams: ({ protocol, hostAndPath }) => ({ + url: `${protocol}://${hostAndPath}`, + }), + dateAdded: new Date('2019-09-17'), + }), +] diff --git a/services/twitter/twitter-redirect.tester.js b/services/twitter/twitter-redirect.tester.js new file mode 100644 index 0000000000..895e1ae9f5 --- /dev/null +++ b/services/twitter/twitter-redirect.tester.js @@ -0,0 +1,19 @@ +'use strict' + +const { ServiceTester } = require('../tester') + +const t = (module.exports = new ServiceTester({ + id: 'TwitterUrlRedirect', + title: 'TwitterUrlRedirect', + pathPrefix: '/twitter/url', +})) + +t.create('twitter') + .get('/https/shields.io.svg', { + followRedirect: false, + }) + .expectStatus(301) + .expectHeader( + 'Location', + `/twitter/url.svg?url=${encodeURIComponent('https://shields.io')}` + ) diff --git a/services/twitter/twitter.service.js b/services/twitter/twitter.service.js index af2bef9589..bffa45acc1 100644 --- a/services/twitter/twitter.service.js +++ b/services/twitter/twitter.service.js @@ -2,8 +2,13 @@ const Joi = require('@hapi/joi') const { metric } = require('../text-formatters') +const { optionalUrl } = require('../validators') const { BaseService, BaseJsonService, NotFound } = require('..') +const queryParamSchema = Joi.object({ + url: optionalUrl.required(), +}).required() + class TwitterUrl extends BaseService { static get category() { return 'social' @@ -11,10 +16,9 @@ class TwitterUrl extends BaseService { static get route() { return { - base: 'twitter/url', - // Do not base new services on this route pattern. - // See https://github.com/badges/shields/issues/3714 - pattern: ':protocol(https|http)/:hostAndPath+', + base: 'twitter', + pattern: 'url', + queryParamSchema, } } @@ -22,9 +26,9 @@ class TwitterUrl extends BaseService { return [ { title: 'Twitter URL', - namedParams: { - protocol: 'http', - hostAndPath: 'shields.io', + namedParams: {}, + queryParams: { + url: 'https://shields.io', }, // hard code the static preview // because link[] is not allowed in examples @@ -43,8 +47,8 @@ class TwitterUrl extends BaseService { } } - async handle({ protocol, hostAndPath }) { - const page = encodeURIComponent(`${protocol}://${hostAndPath}`) + async handle(_routeParams, { url }) { + const page = encodeURIComponent(`${url}`) return { label: 'tweet', message: '', diff --git a/services/twitter/twitter.tester.js b/services/twitter/twitter.tester.js index 84eea58f19..50941c9838 100644 --- a/services/twitter/twitter.tester.js +++ b/services/twitter/twitter.tester.js @@ -34,7 +34,7 @@ t.create('Invalid Username Specified (only spaces)') }) t.create('URL') - .get('/url/https/shields.io.json') + .get('/url.json?url=https://shields.io') .expectBadge({ label: 'tweet', message: '',