commit
76acc9e661
8 changed files with 192 additions and 30 deletions
65
index.js
65
index.js
|
@ -35,6 +35,10 @@ const speechPassport = require('./server/speechPassport');
|
|||
const {
|
||||
details: { port: PORT },
|
||||
auth: { sessionKey },
|
||||
startup: {
|
||||
performChecks,
|
||||
performUpdates,
|
||||
},
|
||||
} = require('@config/siteConfig');
|
||||
|
||||
function Server () {
|
||||
|
@ -97,31 +101,70 @@ function Server () {
|
|||
/* create server */
|
||||
this.server = http.Server(this.app);
|
||||
};
|
||||
this.startServerListening = () => {
|
||||
logger.info(`Starting server on ${PORT}...`);
|
||||
return new Promise((resolve, reject) => {
|
||||
this.server.listen(PORT, () => {
|
||||
logger.info(`Server is listening on PORT ${PORT}`);
|
||||
resolve();
|
||||
})
|
||||
});
|
||||
};
|
||||
this.syncDatabase = () => {
|
||||
logger.info(`Syncing database...`);
|
||||
return createDatabaseIfNotExists()
|
||||
.then(() => {
|
||||
db.sequelize.sync();
|
||||
})
|
||||
};
|
||||
this.performChecks = () => {
|
||||
if (!performChecks) {
|
||||
return;
|
||||
}
|
||||
logger.info(`Performing checks...`);
|
||||
return Promise.all([
|
||||
getWalletBalance(),
|
||||
])
|
||||
.then(([walletBalance]) => {
|
||||
logger.info('Starting LBC balance:', walletBalance);
|
||||
})
|
||||
};
|
||||
this.performUpdates = () => {
|
||||
if (!performUpdates) {
|
||||
return;
|
||||
}
|
||||
logger.info(`Peforming updates...`);
|
||||
return Promise.all([
|
||||
[],
|
||||
db.Tor.refreshTable(),
|
||||
])
|
||||
.then(([updatedBlockedList, updatedTorList]) => {
|
||||
logger.info('Blocked list updated, length:', updatedBlockedList.length);
|
||||
logger.info('Tor list updated, length:', updatedTorList.length);
|
||||
})
|
||||
};
|
||||
this.start = () => {
|
||||
this.initialize();
|
||||
this.createApp();
|
||||
this.createServer();
|
||||
/* start the server */
|
||||
logger.info('getting LBC balance & syncing database...');
|
||||
Promise.all([
|
||||
this.syncDatabase(),
|
||||
getWalletBalance(),
|
||||
])
|
||||
.then(([syncResult, walletBalance]) => {
|
||||
logger.info('starting LBC balance:', walletBalance);
|
||||
return this.server.listen(PORT, () => {
|
||||
logger.info(`Server is listening on PORT ${PORT}`);
|
||||
})
|
||||
this.syncDatabase()
|
||||
.then(() => {
|
||||
return this.startServerListening();
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.all([
|
||||
this.performChecks(),
|
||||
this.performUpdates(),
|
||||
])
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('Spee.ch startup is complete');
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.code === 'ECONNREFUSED') {
|
||||
return logger.error('Connection refused. The daemon may not be running.')
|
||||
} else if (error.code === 'EADDRINUSE') {
|
||||
return logger.error('Server could not start listening. The port is already in use.');
|
||||
} else if (error.message) {
|
||||
logger.error(error.message);
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ const authenticateUser = require('./authentication.js');
|
|||
|
||||
*/
|
||||
|
||||
const claimPublish = ({ body, files, headers, ip, originalUrl, user }, res) => {
|
||||
const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res) => {
|
||||
// logging
|
||||
logger.info('PUBLISH REQUEST:', {
|
||||
logger.info('Publish request:', {
|
||||
ip,
|
||||
headers,
|
||||
body,
|
||||
|
|
25
server/controllers/api/tor/index.js
Normal file
25
server/controllers/api/tor/index.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const logger = require('winston');
|
||||
const db = require('../../../models');
|
||||
|
||||
/*
|
||||
|
||||
Route to update and return tor exit nodes that can connect to this ip address
|
||||
|
||||
*/
|
||||
|
||||
const getTorList = (req, res) => {
|
||||
db.Tor.refreshTable()
|
||||
.then( result => {
|
||||
logger.debug('number of records', result.length);
|
||||
res.status(200).json(result);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error,
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = getTorList;
|
32
server/middleware/torCheckMiddleware.js
Normal file
32
server/middleware/torCheckMiddleware.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
const logger = require('winston');
|
||||
const db = require('../models');
|
||||
|
||||
const torCheck = (req, res, next) => {
|
||||
const { ip } = req;
|
||||
logger.debug(`tor check for: ${ip}`);
|
||||
return db.Tor.findAll(
|
||||
{
|
||||
where: {
|
||||
address: ip,
|
||||
},
|
||||
raw: true,
|
||||
})
|
||||
.then(result => {
|
||||
logger.debug('tor check results:', result);
|
||||
if (result.length >= 1) {
|
||||
logger.info('Tor request blocked:', ip);
|
||||
const failureResponse = {
|
||||
success: false,
|
||||
message: 'Unfortunately this api route is not currently available for tor users. We are working on a solution that will allow tor users to use this endpoint in the future.',
|
||||
};
|
||||
res.status(403).json(failureResponse);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = torCheck;
|
|
@ -8,6 +8,7 @@ const File = require('./file.js');
|
|||
const Request = require('./request.js');
|
||||
const User = require('./user.js');
|
||||
const Blocked = require('./blocked.js');
|
||||
const Tor = require('./tor.js');
|
||||
|
||||
const {database, username, password} = require('@config/mysqlConfig');
|
||||
if (!database || !username || !password) {
|
||||
|
@ -50,6 +51,7 @@ db['File'] = sequelize.import('File', File);
|
|||
db['Request'] = sequelize.import('Request', Request);
|
||||
db['User'] = sequelize.import('User', User);
|
||||
db['Blocked'] = sequelize.import('Blocked', Blocked);
|
||||
db['Tor'] = sequelize.import('Tor', Tor);
|
||||
|
||||
// run model.association for each model in the db object that has an association
|
||||
logger.info('associating db models...');
|
||||
|
|
56
server/models/tor.js
Normal file
56
server/models/tor.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
const { details: { ipAddress } } = require('@config/siteConfig');
|
||||
|
||||
module.exports = (sequelize, { STRING }) => {
|
||||
const Tor = sequelize.define(
|
||||
'Tor',
|
||||
{
|
||||
address: {
|
||||
type : STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
fingerprint: {
|
||||
type : STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
}
|
||||
);
|
||||
|
||||
Tor.refreshTable = function () {
|
||||
let torList = [];
|
||||
return fetch(`https://check.torproject.org/api/bulk?ip=${ipAddress}&port=80`)
|
||||
.then(response => {
|
||||
return response.json();
|
||||
})
|
||||
.then(jsonResponse => {
|
||||
for (let i = 0; i < jsonResponse.length; i++) {
|
||||
torList.push({
|
||||
address : jsonResponse[i].Address,
|
||||
fingerprint: jsonResponse[i].Fingerprint,
|
||||
});
|
||||
}
|
||||
// clear the table
|
||||
return this.destroy({
|
||||
truncate: true,
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
// fill the table
|
||||
return this.bulkCreate(torList);
|
||||
})
|
||||
.then(() => {
|
||||
// return the new table
|
||||
return this.findAll({
|
||||
attributes: ['address', 'fingerprint'],
|
||||
raw : true,
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
return Tor;
|
||||
};
|
|
@ -14,29 +14,33 @@ const claimShortId = require('../../controllers/api/claim/shortId');
|
|||
const fileAvailability = require('../../controllers/api/file/availability');
|
||||
const userPassword = require('../../controllers/api/user/password');
|
||||
const publishingConfig = require('../../controllers/api/config/site/publishing');
|
||||
const getTorList = require('../../controllers/api/tor');
|
||||
|
||||
const multipartMiddleware = require('../utils/multipartMiddleware');
|
||||
const multipartMiddleware = require('../../middleware/multipartMiddleware');
|
||||
const torCheckMiddleware = require('../../middleware/torCheckMiddleware');
|
||||
|
||||
module.exports = (app) => {
|
||||
// channel routes
|
||||
app.get('/api/channel/availability/:name', channelAvailability);
|
||||
app.get('/api/channel/short-id/:longId/:name', channelShortId);
|
||||
app.get('/api/channel/data/:channelName/:channelClaimId', channelData);
|
||||
app.get('/api/channel/claims/:channelName/:channelClaimId/:page', channelClaims);
|
||||
app.get('/api/channel/availability/:name', torCheckMiddleware, channelAvailability);
|
||||
app.get('/api/channel/short-id/:longId/:name', torCheckMiddleware, channelShortId);
|
||||
app.get('/api/channel/data/:channelName/:channelClaimId', torCheckMiddleware, channelData);
|
||||
app.get('/api/channel/claims/:channelName/:channelClaimId/:page', torCheckMiddleware, channelClaims);
|
||||
// claim routes
|
||||
app.get('/api/claim/availability/:name', claimAvailability);
|
||||
app.get('/api/claim/blocked-list/', claimBlockedList);
|
||||
app.get('/api/claim/data/:claimName/:claimId', claimData);
|
||||
app.get('/api/claim/get/:name/:claimId', claimGet);
|
||||
app.get('/api/claim/list/:name', claimList);
|
||||
app.post('/api/claim/long-id', claimLongId); // should be a get
|
||||
app.post('/api/claim/publish', multipartMiddleware, claimPublish);
|
||||
app.get('/api/claim/resolve/:name/:claimId', claimResolve);
|
||||
app.get('/api/claim/short-id/:longId/:name', claimShortId);
|
||||
app.get('/api/claim/availability/:name', torCheckMiddleware, claimAvailability);
|
||||
app.get('/api/claim/blocked-list/', torCheckMiddleware, claimBlockedList);
|
||||
app.get('/api/claim/data/:claimName/:claimId', torCheckMiddleware, claimData);
|
||||
app.get('/api/claim/get/:name/:claimId', torCheckMiddleware, claimGet);
|
||||
app.get('/api/claim/list/:name', torCheckMiddleware, claimList);
|
||||
app.post('/api/claim/long-id', torCheckMiddleware, claimLongId); // note: should be a 'get'
|
||||
app.post('/api/claim/publish', torCheckMiddleware, multipartMiddleware, claimPublish);
|
||||
app.get('/api/claim/resolve/:name/:claimId', torCheckMiddleware, claimResolve);
|
||||
app.get('/api/claim/short-id/:longId/:name', torCheckMiddleware, claimShortId);
|
||||
// file routes
|
||||
app.get('/api/file/availability/:name/:claimId', fileAvailability);
|
||||
app.get('/api/file/availability/:name/:claimId', torCheckMiddleware, fileAvailability);
|
||||
// user routes
|
||||
app.put('/api/user/password/', userPassword);
|
||||
app.put('/api/user/password/', torCheckMiddleware, userPassword);
|
||||
// configs
|
||||
app.get('/api/config/site/publishing', publishingConfig);
|
||||
app.get('/api/config/site/publishing', torCheckMiddleware, publishingConfig);
|
||||
// tor
|
||||
app.get('/api/tor', torCheckMiddleware, getTorList);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue