Skip to content

Commit a050172

Browse files
committed
move throttle, add web login
1 parent d816792 commit a050172

File tree

2 files changed

+58
-23
lines changed

2 files changed

+58
-23
lines changed

src/handlers/player.js

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ const sleep = require('sleep-promise');
66
const bcryptCompare = promisify(bcrypt.compare);
77
const bcryptHash = promisify(bcrypt.hash);
88

9+
async function throttleAttempt(queryHandler, ip) {
10+
let { attempts, lastDate } = queryHandler.getLoginAttempts(ip);
11+
12+
if (attempts >= 5) {
13+
if (Date.now() - lastDate >= 1000 * 60 * 5) {
14+
return true;
15+
} else {
16+
queryHandler.setLoginAttempts(ip, 0);
17+
attempts = 0;
18+
}
19+
} else {
20+
queryHandler.setLoginAttempts(ip, attempts + 1);
21+
}
22+
23+
await sleep(attempts * 1000);
24+
return false;
25+
}
26+
927
async function playerCount({ token }) {
1028
const queryHandler = this.server.queryHandler;
1129
const playerCount = queryHandler.getPlayerCount();
@@ -47,31 +65,22 @@ async function playerLogin({ token, username, password, ip, reconnecting }) {
4765

4866
const queryHandler = this.server.queryHandler;
4967

50-
let { attempts, lastDate } = queryHandler.getLoginAttempts(ip);
51-
52-
if (attempts >= 5) {
53-
if (Date.now() - lastDate >= 1000 * 60 * 5) {
54-
queryHandler.setLoginAttempts(ip, 0);
55-
attempts = 0;
56-
} else {
57-
message.code = 7;
58-
message.success = false;
59-
this.socket.sendMessage(message);
60-
return;
61-
}
68+
if (await throttleAttempt(queryHandler, ip)) {
69+
message.code = 7;
70+
message.success = false;
71+
return this.socket.sendMessage(message);
6272
}
6373

64-
await sleep(attempts * 1000);
65-
6674
const hash = queryHandler.getPlayerPassword(username);
6775

6876
if (!hash || !(await bcryptCompare(password, hash))) {
6977
message.code = 3;
7078
message.success = false;
71-
queryHandler.setLoginAttempts(ip, attempts + 1);
7279
return this.socket.sendMessage(message);
7380
}
7481

82+
queryHandler.setLoginAttempts(ip, 0);
83+
7584
const rounds = bcrypt.getRounds(hash);
7685
const passwordHashRounds = this.server.config.passwordHashRounds;
7786

@@ -265,10 +274,7 @@ async function playerMessage({
265274
message
266275
});
267276

268-
this.socket.sendMessage({
269-
token,
270-
success: true
271-
});
277+
this.socket.sendMessage({ token, success: true });
272278
} catch (e) {
273279
this.socket.sendMessage({
274280
token,
@@ -278,6 +284,28 @@ async function playerMessage({
278284
}
279285
}
280286

287+
async function webLogin({ token, username, password, ip }) {
288+
username = username.trim().toLowerCase();
289+
290+
const queryHandler = this.server.queryHandler;
291+
292+
if (await throttleAttempt(queryHandler, ip)) {
293+
return this.socket.sendMessage({ token, success: false });
294+
}
295+
296+
const hash = queryHandler.getPlayerPassword(username);
297+
298+
if (!hash || !(await bcryptCompare(password, hash))) {
299+
return this.socket.sendMessage({ token, success: false });
300+
}
301+
302+
queryHandler.setLoginAttempts(ip, 0);
303+
304+
const player = queryHandler.getWebPlayer(username);
305+
306+
return this.socket.sendMessage({ token, success: true, player });
307+
}
308+
281309
module.exports = {
282310
playerCount,
283311
playerGetWorlds,
@@ -287,5 +315,6 @@ module.exports = {
287315
playerOnlineCount,
288316
playerRegister,
289317
playerUpdate,
290-
playerMessage
318+
playerMessage,
319+
webLogin
291320
};

src/query-handler.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ class QueryHandler {
146146
'FROM `players` WHERE `username` = ?',
147147
searchNews:
148148
'SELECT `id`, `date`, `category`, `title`, ' +
149-
`substr(\`body\`, 0, ${SUMMARY_LENGTH}) AS \`summary\`, ` +
150-
'count(1) over() AS `total` FROM `news` WHERE ' +
149+
`trim(substr(\`body\`, 0, ${SUMMARY_LENGTH})) AS ` +
150+
'`summary`, count(1) over() AS `total` FROM `news` WHERE ' +
151151
'CASE WHEN :category > -1 THEN `category` = :category ELSE ' +
152152
'true END AND ' +
153153
'CASE WHEN LENGTH(:terms) > 2 THEN `title` LIKE :terms OR ' +
@@ -157,7 +157,9 @@ class QueryHandler {
157157
'ORDER BY `date` DESC ' +
158158
`LIMIT ${NEWS_PER_PAGE} OFFSET (:page * ${NEWS_PER_PAGE})`,
159159
getNews: 'SELECT * FROM `news` WHERE `id` = ?',
160-
getFile: 'SELECT `file` FROM `uploads` WHERE `name` = ?'
160+
getFile: 'SELECT `file` FROM `uploads` WHERE `name` = ?',
161+
getWebPlayer:
162+
'SELECT `id`, `rank` FROM `players` WHERE `username` = ?'
161163
};
162164

163165
for (const [name, statement] of Object.entries(this.statements)) {
@@ -508,6 +510,10 @@ class QueryHandler {
508510
return this.statements.getFile.pluck().get(name);
509511
}
510512

513+
getWebPlayer(username) {
514+
return this.statements.getWebPlayer.get(username);
515+
}
516+
511517
sync() {
512518
this.database.pragma('journal_mode = WAL');
513519
this.createTables();

0 commit comments

Comments
 (0)