return cross-shard requests only to shard that requested
make api/banme POST request
This commit is contained in:
parent
279819eac0
commit
2707fb6123
|
@ -56,7 +56,7 @@ const RegUser = sequelize.define('User', {
|
||||||
},
|
},
|
||||||
|
|
||||||
discordid: {
|
discordid: {
|
||||||
type: DataTypes.CHAR(18),
|
type: DataTypes.CHAR(20),
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,21 @@ import { banIP } from '../../data/sql/Ban';
|
||||||
import { getIPv6Subnet, getIPFromRequest } from '../../utils/ip';
|
import { getIPv6Subnet, getIPFromRequest } from '../../utils/ip';
|
||||||
|
|
||||||
async function banme(req, res) {
|
async function banme(req, res) {
|
||||||
const { code } = req.query;
|
const { code } = req.body;
|
||||||
|
|
||||||
|
const ip = getIPFromRequest(req);
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
logger.info(`AUTOBAN ${code} - ${ip} of user ${req.user.id} with ua "${req.headers['user-agent']}"`);
|
||||||
|
|
||||||
let reason = 'AUTOBAN';
|
let reason = 'AUTOBAN';
|
||||||
if (code === '1') {
|
let expires = 0;
|
||||||
|
if (code === 1) {
|
||||||
reason = 'Userscript Bot';
|
reason = 'Userscript Bot';
|
||||||
} else if (code === '2') {
|
expires = Date.now() + 1000 * 3600 * 24 * 7;
|
||||||
|
/*
|
||||||
|
* ignore it for now to collect data manually
|
||||||
|
*
|
||||||
|
} else if (code === 2) {
|
||||||
const ua = req.headers['user-agent'];
|
const ua = req.headers['user-agent'];
|
||||||
if (ua && (ua.includes('Android') || ua.includes('iPhone'))) {
|
if (ua && (ua.includes('Android') || ua.includes('iPhone'))) {
|
||||||
res.json({
|
res.json({
|
||||||
|
@ -20,14 +30,18 @@ async function banme(req, res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reason = 'Captcha Solving Script';
|
reason = 'Captcha Solving Script';
|
||||||
|
expires = Date.now() + 1000 * 3600 * 24 * 3;
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
res.json({
|
||||||
|
status: 'nope',
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const ip = getIPFromRequest(req);
|
|
||||||
// eslint-disable-next-line max-len
|
|
||||||
logger.info(`AUTOBAN ${code}${ip} of user ${req.user.id} with ua "${req.headers['user-agent']}"`);
|
|
||||||
await banIP(
|
await banIP(
|
||||||
getIPv6Subnet(ip),
|
getIPv6Subnet(ip),
|
||||||
reason,
|
reason,
|
||||||
0,
|
expires,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
res.json({
|
res.json({
|
||||||
|
|
|
@ -98,7 +98,7 @@ router.get('/chathistory', chatHistory);
|
||||||
|
|
||||||
router.get('/me', me);
|
router.get('/me', me);
|
||||||
|
|
||||||
router.get('/banme', banme);
|
router.post('/banme', banme);
|
||||||
|
|
||||||
router.use('/auth', auth);
|
router.use('/auth', auth);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,17 @@ class MessageBroker extends SocketEvents {
|
||||||
super();
|
super();
|
||||||
this.isCluster = true;
|
this.isCluster = true;
|
||||||
this.thisShard = SHARD_NAME;
|
this.thisShard = SHARD_NAME;
|
||||||
|
/*
|
||||||
|
* currently running cross-shard requests,
|
||||||
|
* are tracked in order to only send them to receiving
|
||||||
|
* shard
|
||||||
|
* [{
|
||||||
|
* id: request id,
|
||||||
|
* shard: requesting shard name,
|
||||||
|
* ts: timestamp of request,
|
||||||
|
* },...]
|
||||||
|
*/
|
||||||
|
this.csReq = [];
|
||||||
/*
|
/*
|
||||||
* all other shards
|
* all other shards
|
||||||
*/
|
*/
|
||||||
|
@ -95,22 +106,16 @@ class MessageBroker extends SocketEvents {
|
||||||
const key = message.slice(message.indexOf(':') + 1, comma);
|
const key = message.slice(message.indexOf(':') + 1, comma);
|
||||||
console.log('CLUSTER: Broadcast', key);
|
console.log('CLUSTER: Broadcast', key);
|
||||||
const val = JSON.parse(message.slice(comma + 1));
|
const val = JSON.parse(message.slice(comma + 1));
|
||||||
/*
|
|
||||||
if (key.startsWith('req:')) {
|
if (key.startsWith('req:')) {
|
||||||
try {
|
// cross-shard requests
|
||||||
const shard = message.slice(0, message.indexOf(':'));
|
const shard = message.slice(0, message.indexOf(':'));
|
||||||
const chan = val.shift();
|
const id = val[0];
|
||||||
const ret = await super.req(key.slice(4), ...val);
|
this.csReq.push({
|
||||||
this.publisher.publish(
|
id,
|
||||||
`${LISTEN_PREFIX}:${shard}`,
|
shard,
|
||||||
`res:${chan},${JSON.stringify([ret])}`,
|
ts: Date.now(),
|
||||||
);
|
});
|
||||||
} catch {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
super.emit(key, ...val);
|
super.emit(key, ...val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +150,7 @@ class MessageBroker extends SocketEvents {
|
||||||
try {
|
try {
|
||||||
const comma = message.indexOf(',');
|
const comma = message.indexOf(',');
|
||||||
const key = message.slice(0, comma);
|
const key = message.slice(0, comma);
|
||||||
|
console.log(`CLUSTER shard listener got ${key}`);
|
||||||
const val = JSON.parse(message.slice(comma + 1));
|
const val = JSON.parse(message.slice(comma + 1));
|
||||||
super.emit(key, ...val);
|
super.emit(key, ...val);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -188,13 +194,14 @@ class MessageBroker extends SocketEvents {
|
||||||
const callback = (retn) => {
|
const callback = (retn) => {
|
||||||
amountOtherShards -= 1;
|
amountOtherShards -= 1;
|
||||||
ret = combineObjects(ret, retn);
|
ret = combineObjects(ret, retn);
|
||||||
// eslint-disable-next-line
|
|
||||||
console.log(`CLUSTER got res:${type} from shard, ${amountOtherShards} still left`);
|
|
||||||
if (amountOtherShards <= 0) {
|
if (amountOtherShards <= 0) {
|
||||||
console.log(`CLUSTER res:${type} finished`);
|
console.log(`CLUSTER res:${chan}:${type} finished`);
|
||||||
this.off(chankey, callback);
|
this.off(chankey, callback);
|
||||||
clearTimeout(id);
|
clearTimeout(id);
|
||||||
resolve(ret);
|
resolve(ret);
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.log(`CLUSTER got res:${chan}:${type} from shard, ${amountOtherShards} still left`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
id = setTimeout(() => {
|
id = setTimeout(() => {
|
||||||
|
@ -202,7 +209,7 @@ class MessageBroker extends SocketEvents {
|
||||||
if (ret) {
|
if (ret) {
|
||||||
resolve(ret);
|
resolve(ret);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error(`Timeout on req ${type}`));
|
reject(new Error(`CLUSTER Timeout on wait for res:${chan}:${type}`));
|
||||||
}
|
}
|
||||||
}, 45000);
|
}, 45000);
|
||||||
this.on(chankey, callback);
|
this.on(chankey, callback);
|
||||||
|
@ -210,6 +217,22 @@ class MessageBroker extends SocketEvents {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res(chan, ret) {
|
||||||
|
// only response to requesting shard
|
||||||
|
const csre = this.csReq.find((r) => r.id === chan);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.log(`CLUSTER send res:${chan} to shard ${csre && csre.shard}`);
|
||||||
|
if (csre) {
|
||||||
|
this.publisher.publish(
|
||||||
|
`${LISTEN_PREFIX}:${csre.shard}`,
|
||||||
|
`res:${chan},${JSON.stringify([ret])}`,
|
||||||
|
);
|
||||||
|
this.csReq = this.csReq.filter((r) => r.id !== chan);
|
||||||
|
} else {
|
||||||
|
super.emit(`res:${chan}`, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateShardOnlineCounter(shard, cnt) {
|
updateShardOnlineCounter(shard, cnt) {
|
||||||
const shardCounter = this.shardOnlineCounters.find(
|
const shardCounter = this.shardOnlineCounters.find(
|
||||||
(c) => c[0] === shard,
|
(c) => c[0] === shard,
|
||||||
|
@ -347,7 +370,7 @@ class MessageBroker extends SocketEvents {
|
||||||
|
|
||||||
checkHealth() {
|
checkHealth() {
|
||||||
// remove disconnected shards
|
// remove disconnected shards
|
||||||
const threshold = Date.now() - 30000;
|
let threshold = Date.now() - 30000;
|
||||||
const { shards } = this;
|
const { shards } = this;
|
||||||
Object.keys(shards).forEach((shard) => {
|
Object.keys(shards).forEach((shard) => {
|
||||||
if (shards[shard] < threshold) {
|
if (shards[shard] < threshold) {
|
||||||
|
@ -364,6 +387,9 @@ class MessageBroker extends SocketEvents {
|
||||||
});
|
});
|
||||||
// send keep alive to others
|
// send keep alive to others
|
||||||
this.publisher.publish(BROADCAST_CHAN, this.thisShard);
|
this.publisher.publish(BROADCAST_CHAN, this.thisShard);
|
||||||
|
// clean up dead shard requests
|
||||||
|
threshold -= 30000;
|
||||||
|
this.csReq = this.csReq.filter((r) => r.ts > threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,14 @@ class SocketEvents extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res(chan, ret) {
|
||||||
|
this.emit(`res:${chan}`, ret);
|
||||||
|
}
|
||||||
|
|
||||||
onReq(type, cb) {
|
onReq(type, cb) {
|
||||||
this.on(`req:${type}`, async (chan, ...args) => {
|
this.on(`req:${type}`, async (chan, ...args) => {
|
||||||
const ret = await cb(...args);
|
const ret = await cb(...args);
|
||||||
this.emit(`res:${chan}`, ret);
|
this.res(chan, ret);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -348,7 +348,8 @@ export function requestIID() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestBanMe(code) {
|
export function requestBanMe(code) {
|
||||||
return makeAPIGETRequest(
|
return makeAPIPOSTRequest(
|
||||||
`/api/banme?code=${code}`,
|
'/api/banme',
|
||||||
|
{ code },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user