diff --git a/routes/index.js b/routes/index.js index fc88c13..02f18ea 100644 --- a/routes/index.js +++ b/routes/index.js @@ -26,6 +26,14 @@ const fullUrl = (req, path) => ( `${req.protocol}://${req.hostname}${path ? path : req.originalUrl}` ) +/* Helper for returning syntax errors */ +const handleError = (msg) => ( + (req, res, next) => { + res.status(400) + res.render('index', { error: new Error(msg) }) + } +) + /* Open Website/Dapp in Status */ const handleSite = (req, res) => { let { url } = req.params @@ -41,14 +49,21 @@ const handleSite = (req, res) => { /* Open User Profile from Chat Key in Status */ const handleChatKey = (req, res) => { - const chatKey = req.params[0] - chatName = StatusIm.chatKeyToChatName(chatKey) + /* We accept upper case for chat keys */ + const chatKey = req.params[0].toLowerCase() + try { + chatName = StatusIm.chatKeyToChatName(chatKey) + } catch(error) { + console.error(`Failed to parse: "${req.params[0]}", Error:`, error.message) + res.render('index', { title: 'Invalid chat key format!', error }) + return + } genPage(res, { title: `Join ${chatName} in Status`, info: `Chat and transact with ${chatKey} in Status.`, copyTarget: chatKey, headerName: chatName, - path: fullUrl(req), + path: fullUrl(req, `/${chatKey}`), }) } @@ -59,7 +74,7 @@ const handleEnsName = (req, res) => { username = utils.normalizeEns(req.params[0]) } catch(error) { /* ENS names have the widest regex: .+ */ console.error(`Failed to parse: "${req.params[0]}", Error:`, error.message) - res.render('index', { title: 'Invalid Username Format!', error }) + res.render('index', { title: 'Invalid username format!', error }) return } genPage(res, { @@ -99,11 +114,13 @@ router.get('/browse/:url(*)', handleSite) /* Legacy */ router.get(/^\/(0[xX]04[0-9a-fA-F]{128})$/, handleChatKey) router.get(/^\/user\/(0[xX]04[0-9a-fA-F]{128})$/, handleChatKey) /* Legacy */ +router.get(/^\/@.*[A-Z]+.*$/, handleError('Upper case ENS names are invalid')) router.get(/^\/@(.+)$/, handleEnsName) router.get(/^\/user\/(.+)$/, handleEnsName) /* Legacy */ router.get(/^\/([a-z0-9-]+)$/, handlePublicChannel) -router.get(/^\/chat\/public\/([a-z0-9-]+)$/, handlePublicChannel) +router.get(/^\/chat\/public\/([a-z0-9-]+)$/, handlePublicChannel) /* Legacy */ +router.get(/^\/([a-zA-Z0-9-]+)$/, handleError('Upper case channel names are invalid')) /* Catchall for everything else */ router.get('*', (req, res, next) => { diff --git a/tests/main.js b/tests/main.js index 73e5d31..65326a8 100644 --- a/tests/main.js +++ b/tests/main.js @@ -15,14 +15,16 @@ const get = (path) => ( srv.get(path).set('Host', host) ) -test('test chat routes', t => { +test('test browser routes', t => { t.test('/b/ens.domains', async t => { const res = await get('/b/ens.domains') t.equal(res.statusCode, 200, 'returns 200') t.ok(res.text.includes(`href="http://${host}/b/ens.domains"`), 'contains link') t.ok(res.text.includes('Browse to ens.domains in Status'), 'contains text') }) +}) +test('test user ens routes', t => { t.test('/@jakubgs.eth', async t => { const res = await get('/@jakubgs.eth') t.equal(res.statusCode, 200, 'returns 200') @@ -30,6 +32,14 @@ test('test chat routes', t => { t.ok(res.text.includes('Chat and transact with @jakubgs.eth in Status.'), 'contains prompt') }) + t.test('/@jAkuBgs.eth.eth', async t => { /* we don't allow uppercase */ + const res = await get('/@jAkuBgs.eth') + t.equal(res.statusCode, 400, 'returns 400') + t.ok(res.text.includes('Upper case ENS names are invalid'), 'contains error') + }) +}) + +test('test chat key routes', t => { t.test(`/0x04${chatKey.substr(0,8)}...`, async t => { const res = await get(`/0x04${chatKey}`) t.equal(res.statusCode, 200, 'returns 200') @@ -38,12 +48,28 @@ test('test chat routes', t => { t.ok(res.text.includes(chatName), 'contains chat name') }) + t.test(`/0x04${chatKey.substr(0,8).toUpperCase()}...`, async t => { /* convert upper to lowe case */ + const res = await get(`/0x04${chatKey.toUpperCase()}`) + t.equal(res.statusCode, 200, 'returns 200') + t.ok(res.text.includes(`href="http://${host}/0x04${chatKey}"`), 'contains link') + t.ok(res.text.includes(`Chat and transact with 0x04${chatKey} in Status.`), 'contains prompt') + t.ok(res.text.includes(chatName), 'contains chat name') + }) +}) + +test('test public channel routes', t => { t.test('/status-test', async t => { const res = await get('/status-test') t.equal(res.statusCode, 200, 'returns 200') t.ok(res.text.includes(`href="http://${host}/status-test"`), 'contains link') t.ok(res.text.includes('Join public channel #status-test on Status.'), 'contains prompt') }) + + t.test('/staTus-TesT', async t => { /* we don't allow uppercase */ + const res = await get('/staTus-TesT') + t.equal(res.statusCode, 400, 'returns 400') + t.ok(res.text.includes('Upper case channel names are invalid'), 'contains error') + }) }) test('test other routes', t => { diff --git a/views/index.ejs b/views/index.ejs index c6be4fd..1aec855 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,7 +1,11 @@ + <%if (locals.error) { %> + <%= error.message %> + <% } else { %> <%= title %> + <% } %> <% if (locals.path) { %>