diff --git a/applications/distrib-ipfs/.gitignore b/applications/distrib-ipfs/.gitignore deleted file mode 100644 index 98e6ef6..0000000 --- a/applications/distrib-ipfs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.db diff --git a/applications/distrib-ipfs/index.js b/applications/distrib-ipfs/index.js deleted file mode 100644 index 031db3e..0000000 --- a/applications/distrib-ipfs/index.js +++ /dev/null @@ -1,50 +0,0 @@ -const express = require('express') -const path = require('path') -const sqlite = require('sqlite') -const crypto = require('crypto') - -const router = express.Router() -const cfgLoader = require(path.join('..', '..', 'config-loader'))(path.join(__dirname, 'config.json'), { - database: 'shortened.db', - gateway: 'https://distributed.icynet.eu', - tokens: {} -}) - -async function init () { - let config = await cfgLoader - - const dbPromise = Promise.resolve() - .then(() => sqlite.open(path.join(__dirname, config.database), { Promise, cache: true })) - .then(db => db.migrate({ migrationsPath: path.join(__dirname, 'migrations') })) - - router.get('/:hash', async (req, res, next) => { - if (!req.params.hash) return res.status(400).send('Invalid request') - - let db = await dbPromise - let translation = await db.get('SELECT * FROM Translation WHERE translation = ?', req.params.hash) - if (!translation) return res.status(404).end() - - res.header('Cache-Control', 'max-age=' + 7 * 24 * 60 * 60 * 1000) - res.redirect(config.gateway + '/ipfs/' + translation.file_hash) - }) - - router.post('/publish', async (req, res, next) => { - let token = req.header('token') || req.body.token - if (!token || !config.tokens[token]) return res.status(402).send('Forbidden') - - let baseurl = config.tokens[token] - let hash = req.query.hash || req.body.hash - let filename = req.query.filename || req.body.filename - if (!hash) return res.status(400).send('Invalid request: missing IPFS hash') - if (!filename) filename = crypto.randomBytes(8).toString('hex') - - let db = await dbPromise - await db.run('INSERT INTO Translation (translation,file_hash,timeat) VALUES (?,?,?)', filename, hash, new Date()) - - res.send(baseurl + filename) - }) - - return router -} - -module.exports = init diff --git a/applications/tempfiles/index.js b/applications/tempfiles/index.js index 443a121..7bfd0f7 100644 --- a/applications/tempfiles/index.js +++ b/applications/tempfiles/index.js @@ -4,13 +4,14 @@ const path = require('path') const fsa = require('fs') const fs = fsa.promises const sqlite = require('sqlite') +const crypto = require('crypto') const router = express.Router() const cfgLoader = require(path.join('..', '..', 'config-loader'))(path.join(__dirname, 'config.json'), { database: 'index.db', root: './files', expiry: 2246400, - baseurl: 'https://i.lunasqu.ee/', + gateway: 'https://distributed.icynet.eu', tokens: {} }) @@ -23,10 +24,33 @@ function asyncForm (req, form) { }) } +async function clearDatabase (config, dbPromise) { + let db = await dbPromise + let files = await db.all('SELECT * FROM File WHERE upload < ?', new Date() - (config.expiry * 1000)) + if (files.length > 0) { + for (let i in files) { + let f = files[i] + try { + await fs.unlink(path.join(config.root, f.path)) + } catch (e) {} + await db.run('DELETE FROM File WHERE path = ?', f.path) + } + } + + // IPFS hashes + let hashes = await db.all('SELECT * FROM Translation WHERE timeat < ?', new Date() - (config.expiry * 1000)) + if (hashes.length > 0) { + for (let i in hashes) { + await db.run('DELETE FROM Translation WHERE file_hash = ?', hashes[i].file_hash) + } + } + + console.log('Database was cleared of %d files and %d IPFS hashes.', files.length, hashes.length) +} + async function init () { let config = await cfgLoader let root = path.resolve(config.root) - let baseurl = config.baseurl await fs.access(root, fsa.constants.F_OK) @@ -34,14 +58,22 @@ async function init () { .then(() => sqlite.open(path.join(__dirname, config.database), { Promise, cache: true })) .then(db => db.migrate({ migrationsPath: path.join(__dirname, 'migrations') })) + await clearDatabase(config, dbPromise) + router.get('/:hash', async (req, res, next) => { if (!req.params.hash) return res.status(400).send('Invalid request') let db = await dbPromise let file = await db.get('SELECT * FROM File WHERE path = ?', req.params.hash) - if (!file) return res.status(404).end() + let translation = await db.get('SELECT * FROM Translation WHERE translation = ?', req.params.hash) + if (!file && !translation) return res.status(404).end() res.header('Cache-Control', 'max-age=' + 7 * 24 * 60 * 60 * 1000) + + if (translation) { + return res.redirect(config.gateway + '/ipfs/' + translation.file_hash) + } + res.sendFile(path.join(root, file.path)) }) @@ -49,6 +81,19 @@ async function init () { let ip = req.ip let token = req.header('token') || req.body.token if (!token || !config.tokens[token]) return res.status(402).send('Forbidden') + let baseurl = config.tokens[token] + + // Handle IPFS hash + let hash = req.query.hash || req.body.hash + if (hash) { + let filename = req.query.filename || req.body.filename + if (!filename) filename = crypto.randomBytes(8).toString('hex') + + let db = await dbPromise + await db.run('INSERT INTO Translation (translation,file_hash,timeat) VALUES (?,?,?)', filename, hash, new Date()) + + return res.send(baseurl + filename) + } // Handle multipart data let form = new multiparty.Form() diff --git a/applications/distrib-ipfs/migrations/001-initial.sql b/applications/tempfiles/migrations/002-ipfs.sql similarity index 100% rename from applications/distrib-ipfs/migrations/001-initial.sql rename to applications/tempfiles/migrations/002-ipfs.sql