Add banning URLs API and check for banned domains and hosts
This commit is contained in:
parent
82a561bd4c
commit
eb99fc5e4a
@ -1,5 +1,7 @@
|
||||
const urlRegex = require('url-regex');
|
||||
const URL = require('url');
|
||||
const dns = require('dns');
|
||||
const { promisify } = require('util');
|
||||
const generate = require('nanoid/generate');
|
||||
const useragent = require('useragent');
|
||||
const geoip = require('geoip-lite');
|
||||
@ -17,8 +19,13 @@ const {
|
||||
getUrls,
|
||||
setCustomDomain,
|
||||
urlCountFromDate,
|
||||
banUrl,
|
||||
getBannedDomain,
|
||||
getBannedHost,
|
||||
} = require('../db/url');
|
||||
|
||||
const dnsLookup = promisify(dns.lookup);
|
||||
|
||||
const { addProtocol, generateShortUrl } = require('../utils');
|
||||
const config = require('../config');
|
||||
|
||||
@ -72,6 +79,22 @@ exports.urlShortener = async ({ body, user }, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// If domain or host is banned
|
||||
const domain = URL.parse(body.target).hostname;
|
||||
const isDomainBanned = await getBannedDomain(domain);
|
||||
|
||||
let isHostBanned;
|
||||
try {
|
||||
const dnsRes = await dnsLookup(domain);
|
||||
isHostBanned = await getBannedHost(dnsRes && dnsRes.address);
|
||||
} catch (error) {
|
||||
isHostBanned = null;
|
||||
}
|
||||
|
||||
if (isDomainBanned || isHostBanned) {
|
||||
return res.status(400).json({ error: 'URL is containing malware/scam.' });
|
||||
}
|
||||
|
||||
// Create new URL
|
||||
const id = (user && body.customurl) || (await generateId());
|
||||
const target = addProtocol(body.target);
|
||||
@ -104,12 +127,20 @@ exports.goToUrl = async (req, res, next) => {
|
||||
botList.some(bot => agent.source.toLowerCase().includes(bot)) || agent.family === 'Other';
|
||||
if (!urls && !urls.length) return next();
|
||||
const url = urls.find(item => (domain ? item.domain === domain : !item.domain));
|
||||
|
||||
if (!url) return next();
|
||||
|
||||
if (url.banned) {
|
||||
return res.redirect('/banned');
|
||||
}
|
||||
|
||||
const doesRequestInfo = /.*\+$/gi.test(reqestedId);
|
||||
if (doesRequestInfo && !url.password) {
|
||||
req.urlTarget = url.target;
|
||||
req.pageType = 'info';
|
||||
return next();
|
||||
}
|
||||
|
||||
if (url.password && !req.body.password) {
|
||||
req.protectedUrl = id;
|
||||
req.pageType = 'password';
|
||||
@ -194,3 +225,35 @@ exports.getStats = async ({ query: { id, domain }, user }, res) => {
|
||||
if (!stats) return res.status(400).json({ error: 'Could not get the short URL stats.' });
|
||||
return res.status(200).json(stats);
|
||||
};
|
||||
|
||||
exports.ban = async ({ body }, res) => {
|
||||
if (!body.id) return res.status(400).json({ error: 'No id has been provided.' });
|
||||
|
||||
const urls = await findUrl({ id: body.id });
|
||||
const [url] = urls.filter(item => !item.domain);
|
||||
|
||||
if (!url) return res.status(400).json({ error: "Couldn't find the URL." });
|
||||
|
||||
if (url.banned) return res.status(200).json({ message: 'URL was banned already' });
|
||||
|
||||
const domain = URL.parse(url.target).hostname;
|
||||
|
||||
let host;
|
||||
if (body.host) {
|
||||
try {
|
||||
const dnsRes = await dnsLookup(domain);
|
||||
host = dnsRes && dnsRes.address;
|
||||
} catch (error) {
|
||||
host = null;
|
||||
}
|
||||
}
|
||||
|
||||
await banUrl({
|
||||
domain: body.domain && domain,
|
||||
host,
|
||||
id: body.id,
|
||||
user: body.user,
|
||||
});
|
||||
|
||||
return res.status(200).json({ message: 'URL has been banned successfully' });
|
||||
};
|
||||
|
@ -434,3 +434,49 @@ exports.urlCountFromDate = ({ date, email }) =>
|
||||
})
|
||||
.catch(err => reject(err));
|
||||
});
|
||||
|
||||
exports.banUrl = async ({ id, domain, host, user }) => {
|
||||
const session = driver.session();
|
||||
const userQuery = user
|
||||
? 'OPTIONAL MATCH (u:USER)-[:CREATED]->(l) SET u.banned = true WITH u ' +
|
||||
'OPTIONAL MATCH (u)-[:CREATED]->(ls:URL) SET ls.banned = true'
|
||||
: '';
|
||||
const domainQuery = domain
|
||||
? 'MERGE (d:DOMAIN { name: $domain }) ON CREATE SET d.banned = true'
|
||||
: '';
|
||||
const hostQuery = host ? 'MERGE (h:HOST { name: $host }) ON CREATE SET h.banned = true' : '';
|
||||
await session.writeTransaction(tx =>
|
||||
tx.run(
|
||||
'MATCH (l:URL { id: $id }) WHERE NOT (l)-[:USES]->(:DOMAIN) ' +
|
||||
`SET l.banned = true WITH l ${userQuery} ${domainQuery} ${hostQuery}`,
|
||||
{
|
||||
id,
|
||||
domain,
|
||||
host,
|
||||
}
|
||||
)
|
||||
);
|
||||
session.close();
|
||||
};
|
||||
|
||||
exports.getBannedDomain = async (domain = '') => {
|
||||
const session = driver.session();
|
||||
const { records } = await session.readTransaction(tx =>
|
||||
tx.run('MATCH (d:DOMAIN { name: $domain, banned: true }) RETURN d', {
|
||||
domain,
|
||||
})
|
||||
);
|
||||
session.close();
|
||||
return records.length > 0;
|
||||
};
|
||||
|
||||
exports.getBannedHost = async (host = '') => {
|
||||
const session = driver.session();
|
||||
const { records } = await session.readTransaction(tx =>
|
||||
tx.run('MATCH (h:HOST { name: $host, banned: true }) RETURN h', {
|
||||
host,
|
||||
})
|
||||
);
|
||||
session.close();
|
||||
return records.length > 0;
|
||||
};
|
||||
|
@ -78,6 +78,7 @@ app.prepare().then(() => {
|
||||
server.get('/stats', (req, res) => app.render(req, res, '/stats', req.query));
|
||||
server.get('/terms', (req, res) => app.render(req, res, '/terms'));
|
||||
server.get('/report', (req, res) => app.render(req, res, '/report'));
|
||||
server.get('/banned', (req, res) => app.render(req, res, '/banned'));
|
||||
server.get('/reset-password/:resetPasswordToken?', catchErrors(auth.resetPassword), (req, res) =>
|
||||
app.render(req, res, '/reset-password', req.user)
|
||||
);
|
||||
@ -111,6 +112,13 @@ app.prepare().then(() => {
|
||||
server.delete('/api/url/customdomain', auth.authJwt, catchErrors(url.deleteCustomDomain));
|
||||
server.get('/api/url/stats', auth.authApikey, auth.authJwt, catchErrors(url.getStats));
|
||||
server.post('/api/url/requesturl', catchErrors(url.goToUrl));
|
||||
server.post(
|
||||
'/api/url/admin/ban',
|
||||
auth.authApikey,
|
||||
auth.authJwt,
|
||||
auth.authAdmin,
|
||||
catchErrors(url.ban)
|
||||
);
|
||||
server.get('/:id', catchErrors(url.goToUrl), (req, res) => {
|
||||
switch (req.pageType) {
|
||||
case 'password':
|
||||
|
Loading…
x
Reference in New Issue
Block a user