source: pages/api/postgre/index.js@ ebf5e04

main
Last change on this file since ebf5e04 was ebf5e04, checked in by anastasovv <simon@…>, 2 years ago

Code cleanings

  • Property mode set to 100644
File size: 13.7 KB
Line 
1import { v4 as uuidv4 } from 'uuid';
2
3import axios from 'axios';
4
5require('dotenv').config();
6
7const crypto = require('crypto');
8
9const Pool = require('pg').Pool
10const pool = new Pool({
11 connectionString: `postgres://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}/${process.env.POSTGRES_DB}`
12});
13
14const sessions = []
15// example session = { id, displayName, username, credits, lastActivity }
16
17export default function handler(req, res) {
18 /**
19 * GET method
20 */
21 if (req.method === 'GET') {
22 /**
23 * /---------------------- GET ----------------------/
24 * If the player won credits, update them in the database.
25 * Also, update the stats in the database.
26 * @action give_credits
27 * @param session_id
28 * @param credits
29 */
30 if (req.query?.action === 'add_credits' && req.query?.session_id && req.query?.credits) {
31 const session_id = req.query.session_id
32 const session = sessions.find(session => session.id === session_id)
33
34 if (session) {
35 session.lastActivity = Date.now();
36
37 if (parseInt(req.query.credits) > 0) {
38 session.credits = session.credits + parseInt(req.query.credits)
39
40 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
41 if (error) throw error;
42 });
43 }
44
45 if (req.query?.dont_update_stats) {
46 // continue
47 } else {
48 pool.query('SELECT * FROM stats WHERE username = $1', [session.username], (error, results) => {
49 if (error) throw error;
50
51 if (results.rows.length > 0) {
52 const stats = results.rows[0]
53
54 if (parseInt(req.query.credits) > 0) {
55 pool.query('UPDATE stats SET money_earned = $1 WHERE username = $2', [parseInt(stats.money_earned) + parseInt(req.query.credits), session.username], (error, results) => {
56 if (error) throw error;
57 });
58 }
59
60 if (req.query?.game === 'blackjack') {
61 if (req.query?.outcome === 'player_busted' || req.query?.outcome === 'player_lost') {
62 pool.query('UPDATE stats SET blackjack_games = $1 WHERE username = $2', [parseInt(stats.blackjack_games) + 1, session.username], (error, results) => {
63 if (error) throw error;
64 });
65 }
66 else if (req.query?.outcome === 'dealer_busted' || req.query?.outcome === 'player_won') {
67 pool.query('UPDATE stats SET blackjack_games = $1, blackjack_won_games = $2 WHERE username = $3', [parseInt(stats.blackjack_games) + 1, parseInt(stats.blackjack_won_games) + 1, session.username], (error, results) => {
68 if (error) throw error;
69 });
70 }
71 }
72 }
73 });
74 }
75
76 res.json({
77 success: true,
78 credits: session.credits,
79 })
80
81 return ;
82 }
83
84 res.json({
85 success: false,
86 })
87 }
88
89 /**
90 * /---------------------- GET ----------------------/
91 * The player lost credits, update this in the database.
92 * @action take_credits
93 * @param session_id
94 * @param credits
95 */
96 if (req.query?.action === 'take_credits' && req.query?.session_id && req.query?.credits) {
97 const session_id = req.query.session_id
98 const session = sessions.find(session => session.id === session_id)
99
100 if (session) {
101 session.lastActivity = Date.now();
102
103 session.credits = session.credits - parseInt(req.query.credits)
104
105 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
106 if (error) throw error;
107 });
108
109 pool.query('SELECT * FROM stats WHERE username = $1', [session.username], (error, results) => {
110 if (error) throw error;
111
112 if (results.rows.length > 0) {
113 const stats = results.rows[0]
114
115 pool.query('UPDATE stats SET money_bet = $1 WHERE username = $2', [parseInt(stats.money_bet) + parseInt(req.query.credits), session.username], (error, results) => {
116 if (error) throw error;
117 });
118 }
119 });
120
121 res.json({
122 success: true,
123 credits: session.credits,
124 })
125 return ;
126 }
127
128 res.json({
129 success: false,
130 })
131 }
132
133 /**
134 * /---------------------- GET ----------------------/
135 * Get stats for the player, so we can display them in the front end.
136 * @action get_stats
137 * @param session_id
138 */
139 if (req.query?.action === 'get_stats' && req.query?.session_id) {
140 const session_id = req.query.session_id
141 const session = sessions.find(session => session.id === session_id)
142
143 if (session) {
144 session.lastActivity = Date.now();
145
146 pool.query('SELECT * FROM stats WHERE username = $1', [session.username], (error, results) => {
147 if (error) throw error;
148
149 if (results.rows.length > 0) {
150 res.json({
151 success: true,
152 stats: results.rows[0],
153 })
154 }
155 else {
156 res.json({
157 success: false,
158 })
159 }
160 });
161
162 return ;
163 }
164
165 res.json({
166 success: false,
167 })
168 }
169
170 /**
171 * /---------------------- GET ----------------------/
172 * Returns the player's room, if the player was in one.
173 * Same as the one below, but this one is used in a game-specific context.
174 * @action get_player_info_on_enter
175 * @param session_id
176 */
177 if (req.query?.action === 'get_player_info_on_enter' && req.query?.session_id) {
178 const session_id = req.query.session_id
179 const session = sessions.find(session => session.id === session_id)
180
181 if (session) {
182 res.json({
183 success: true,
184 displayName: session.displayName,
185 session_id: session.id,
186 credits: session.credits,
187 })
188 return ;
189 }
190
191 res.json({
192 success: false,
193 })
194 }
195
196 /**
197 * /---------------------- GET ----------------------/
198 * Returns the player's room, if the player was in one.
199 * Same as the one above, but this one is used in a general context.
200 * @action check_if_logged_in
201 * @param session_id
202 */
203 if (req.query?.action === 'check_if_logged_in' && req.query?.session_id) {
204 const session_id = req.query.session_id
205 const session = sessions.find(session => session.id === session_id)
206
207 if (session) {
208 res.json({
209 success: true,
210 displayName: session.displayName,
211 session_id: session.id,
212 credits: session.credits,
213 })
214 return ;
215 }
216
217 res.json({
218 success: false,
219 })
220 }
221
222 /**
223 * /---------------------- GET ----------------------/
224 * Takes the credits in the player's session, and updates the database.
225 * Logs the player out and kills the session.
226 * @action logout
227 * @param session_id
228 */
229 if (req.query?.action === 'logout' && req.query?.session_id) {
230 const session_id = req.query.session_id
231 const session = sessions.find(session => session.id === session_id)
232
233 if (session) {
234 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
235 if (error) throw error;
236 });
237
238 sessions.splice(sessions.indexOf(session), 1);
239
240 axios.get(`${process.env.HOME_URL}/api/blackjack/?action=remove_room&session_id=${session_id}`);
241 }
242
243 res.json({
244 success: true,
245 message: 'Successfully logged out',
246 })
247 }
248 }
249
250 /**
251 * POST method
252 */
253 if (req.method === 'POST') {
254 const { body } = req;
255
256 /**
257 * /---------------------- POST ----------------------/
258 * Checks if the entered account info is good, and registers a new user in the database if so.
259 * @action register
260 * @param username
261 * @param displayName
262 * @param password
263 */
264 if (body?.action === 'register') {
265 // checks
266 if (body?.username == "undefined" || body?.username == "null" || body?.username == "") {
267 res.json({
268 success: false,
269 message: 'Username is required',
270 });
271 return ;
272 }
273 if (/[^a-zA-Z]/g.test(body?.username)) {
274 res.json({
275 success: false,
276 message: 'Username must contain only letters',
277 })
278 return ;
279 }
280 if (body?.displayName == "undefined" || body?.displayName == "null" || body?.displayName == "") {
281 res.json({
282 success: false,
283 message: 'Display name is required',
284 });
285 return ;
286 }
287 if (body?.displayName?.toLowerCase() === "guest") {
288 res.json({
289 success: false,
290 message: 'Display name cannot be guest',
291 });
292 return ;
293 }
294 if (body?.password == "undefined" || body?.password == "null" || body?.password == "") {
295 res.json({
296 success: false,
297 message: 'Password is required',
298 });
299 return ;
300 }
301
302 // everything's okay
303 body.username = body.username.toLowerCase()
304
305 // hash password
306 const salt = crypto.randomBytes(16).toString('hex');
307 const hashedPassword = crypto.pbkdf2Sync(body.password, salt, 1000, 64, 'sha512').toString('hex');
308
309 // check if user already exists
310 pool.query('SELECT * FROM users WHERE username = $1', [body.username], (error, results) => {
311 if (error) throw error;
312
313 if (results.rows.length > 0) {
314 res.json({
315 success: false,
316 message: 'Username already exists',
317 });
318 return ;
319 }
320
321 // store user in database
322 pool.query('INSERT INTO users (username, password, salt) VALUES ($1, $2, $3)', [body.username, hashedPassword, salt], (error, usersResults) => {
323 if (error) throw error;
324
325 pool.query('INSERT INTO players (username, display_name, credits) VALUES ($1, $2, $3)', [body.username, body.displayName, 1000], (error, playersResults) => {
326 if (error) throw error;
327
328 pool.query('INSERT INTO stats (username, blackjack_games, roulette_games, poker_games, blackjack_won_games, roulette_won_games, poker_won_games, money_bet, money_earned) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)', [body.username, 0, 0, 0, 0, 0, 0, 0, 0], (error, statsResults) => {
329 if (error) throw error;
330
331 res.json({
332 success: true,
333 message: 'Registration successful',
334 });
335 return ;
336 });
337 });
338 });
339 });
340 }
341
342 /**
343 * /---------------------- POST ----------------------/
344 * Checks if the entered account info is good, and logs the user in if so.
345 * @action login
346 * @param username
347 * @param password
348 */
349 if (body?.action === 'login') {
350 // checks
351 if (body?.username == "undefined" || body?.username == "null" || body?.username == "") {
352 res.json({
353 success: false,
354 message: 'Username is required',
355 });
356 return ;
357 }
358 if (/[^a-zA-Z]/g.test(body?.username)) {
359 res.json({
360 success: false,
361 message: 'Username must contain only letters',
362 })
363 return ;
364 }
365 if (body?.password == "undefined" || body?.password == "null" || body?.password == "") {
366 res.json({
367 success: false,
368 message: 'Password is required',
369 });
370 return ;
371 }
372
373 // everything's okay
374 body.username = body.username.toLowerCase();
375
376 // check if user exists
377 pool.query('SELECT * FROM users WHERE username = $1', [body.username], (error, usersResults) => {
378 if (error) throw error;
379
380 if (usersResults.rows.length === 0) {
381 res.json({
382 success: false,
383 message: 'User does not exist. Try Registering instead.',
384 });
385 return ;
386 }
387 else {
388 if (usersResults.rows.length > 0) {
389 const user = usersResults.rows[0];
390 const salt = user.salt;
391 const hashedPassword = crypto.pbkdf2Sync(body.password, salt, 1000, 64, 'sha512').toString('hex');
392
393 if (hashedPassword === user.password) {
394 pool.query('SELECT * FROM players WHERE username = $1', [body.username], (error, playersResults) => {
395 if (playersResults.rows.length > 0) {
396 let session = sessions.find(session => session.username === playersResults.rows[0].username)
397
398 if (session) {
399 // Already logged in
400 res.json({
401 success: false,
402 message: 'You are already logged in',
403 })
404 }
405 else {
406 // create a session
407 session = {
408 id: uuidv4(),
409 displayName: playersResults.rows[0].display_name,
410 username: playersResults.rows[0].username,
411 credits: playersResults.rows[0].credits,
412 lastActivity: Date.now(),
413 }
414
415 sessions.push(session);
416
417 res.json({
418 success: true,
419 message: 'Login successful',
420 session: session,
421 })
422 }
423
424 return ;
425 }
426 });
427 }
428 else {
429 res.json({
430 success: false,
431 message: 'Username and password do not match.',
432 });
433 }
434 }
435 }
436 });
437 }
438 }
439}
Note: See TracBrowser for help on using the repository browser.