URL shortener

This commit is contained in:
Evert Prants 2020-01-06 22:05:28 +02:00
parent b69184eaea
commit 20593c5ecc
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
2 changed files with 68 additions and 0 deletions

View File

@ -5,6 +5,7 @@ const fsa = require('fs')
const fs = fsa.promises const fs = fsa.promises
const sqlite = require('sqlite') const sqlite = require('sqlite')
const crypto = require('crypto') const crypto = require('crypto')
const URL = require('url')
const router = express.Router() const router = express.Router()
const cfgLoader = require(path.join('..', '..', 'config-loader'))(path.join(__dirname, 'config.json'), { const cfgLoader = require(path.join('..', '..', 'config-loader'))(path.join(__dirname, 'config.json'), {
@ -12,6 +13,10 @@ const cfgLoader = require(path.join('..', '..', 'config-loader'))(path.join(__di
root: './files', root: './files',
expiry: 2246400, expiry: 2246400,
gateway: 'https://distributed.icynet.eu', gateway: 'https://distributed.icynet.eu',
shortener: {
url: 'https://go.lunasqu.ee',
bytes: 2,
},
tokens: {} tokens: {}
}) })
@ -155,6 +160,58 @@ async function init () {
res.send(uploadedFiles.join('\n')) res.send(uploadedFiles.join('\n'))
}) })
router.post('/shorten', async (req, res) => {
let ip = req.ip
let url = req.body.url
// Simple URL validator
try {
let a = new URL(url)
if (a.protocol.indexOf('http') !== 0 || a.protocol.indexOf('ftp') !== -1) {
throw new Error('Unsupported protocol')
}
} catch (e) {
throw new Error('Invalid URL!')
}
let db = await dbPromise
// Get a hash that isnt in use
let use
for (let i = 0; i < 8; i++) {
let add = Math.floor(i / 2)
let hash = crypto.randomBytes((config.shortener.bytes || 2) + add).toString('hex')
let exists = await db.get('SELECT timeat FROM Short WHERE hash = ?', hash)
if (!exists) {
use = hash
break
}
}
if (!use) throw new Error('Server could not find a proper hash for some reason')
await db.run('INSERT INTO Short (url,hash,timeat,ip) VALUES (?,?,?,?)', url, use, Date.now(), ip)
let ua = req.get('User-Agent')
let reqRaw = false
if (!reqRaw && ua && (ua.match(/curl\//i) != null || ua.match(/wget\//i) != null)) reqRaw = true
let resp = config.shortener.url + '/' + use
if (!reqRaw) resp = '<a href="' + resp + '" rel="nofollow">' + resp + '</a>'
res.send(resp)
})
router.get('/shorten/:hash', async (req, res) => {
let hash = req.params.hash
let db = await dbPromise
let get = await db.get('SELECT url FROM Short WHERE hash = ?', hash)
if (!get) throw new Error('No such hash exists in the database.')
res.redirect(get.url)
})
router.get('/shorten', (req, res) => {
res.send('<h1>Basic URL Shortener</h1><form action=""><input type="url" name="url" placeholder="URL to shorten"/><input type="submit" value="Go!"></form>')
})
return router return router
} }

View File

@ -0,0 +1,11 @@
-- Up
CREATE TABLE Short (
url TEXT,
hash TEXT,
timeat TEXT,
ip TEXT
);
-- Down
DROP TABLE Short;