Index: pages/api/auth/[...nextauth].js
===================================================================
--- pages/api/auth/[...nextauth].js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
+++ pages/api/auth/[...nextauth].js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -0,0 +1,12 @@
+import NextAuth from 'next-auth'
+import GoogleProvider from 'next-auth/providers/google'
+
+export default NextAuth({
+    providers: [
+        GoogleProvider({
+            clientId: process.env.GOOGLE_CLIENT_ID,
+            clientSecret: process.env.GOOGLE_CLIENT_SECRET
+        })
+    ],
+    secret: process.env.NEXT_SECRET,
+})
Index: pages/api/blackjack/index.js
===================================================================
--- pages/api/blackjack/index.js	(revision faff3347934f6f886535c1e4519dcea679db385d)
+++ pages/api/blackjack/index.js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -142,4 +142,5 @@
         });
 
+        rooms[session_id].finished = new Date().toGMTString();
         saveGameInHistory('blackjack', rooms[session_id], rooms[session_id].username);
 
@@ -204,4 +205,5 @@
           });
           
+          rooms[session_id].finished = new Date().toGMTString();
           saveGameInHistory('blackjack', rooms[session_id], rooms[session_id].username);
         }
Index: pages/api/poker/gameStates.js
===================================================================
--- pages/api/poker/gameStates.js	(revision faff3347934f6f886535c1e4519dcea679db385d)
+++ pages/api/poker/gameStates.js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -33,5 +33,5 @@
     id: '',
     table: '',
-    credits: 0,
+    credits: -1,
     status: '_1_just_entered',
     displayName: '',
@@ -76,5 +76,5 @@
             table: tableId,
             username: username,
-            credits: 0,
+            credits: -1,
             status: '_1_just_entered',
             displayName: playerName,
Index: pages/api/poker/index.js
===================================================================
--- pages/api/poker/index.js	(revision faff3347934f6f886535c1e4519dcea679db385d)
+++ pages/api/poker/index.js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -212,5 +212,5 @@
                             table: req.query.tableId,
                             username: req.query.username,
-                            credits: 0,
+                            credits: -1,
                             status: '_1_just_entered',
                             displayName: req.query.displayName,
Index: pages/api/poker/tableSpecific.js
===================================================================
--- pages/api/poker/tableSpecific.js	(revision faff3347934f6f886535c1e4519dcea679db385d)
+++ pages/api/poker/tableSpecific.js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -210,4 +210,5 @@
             player.wonAmount = winnings;
 
+            table.finished = new Date().toGMTString();
             saveGameInHistory('poker', table, player.username)
         })
Index: pages/api/postgre/index.js
===================================================================
--- pages/api/postgre/index.js	(revision faff3347934f6f886535c1e4519dcea679db385d)
+++ pages/api/postgre/index.js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -15,4 +15,6 @@
   connectionString: `postgres://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}/${process.env.POSTGRES_DB}`
 });
+
+let LAST_LOGIN_REQUEST = Date.now();
 
 export default function handler(req, res) {
@@ -216,7 +218,7 @@
               res.json({
                 success: true,
-                blackjack: JSON.parse(blackjackHistory.history ?? "[]"),
-                roulette: JSON.parse(rouletteHistory.history ?? "[]"),
-                poker: JSON.parse(pokerHistory.history ?? "[]"),
+                blackjack: JSON.parse(blackjackHistory.history ?? "[]").reverse(),
+                roulette: JSON.parse(rouletteHistory.history ?? "[]").reverse(),
+                poker: JSON.parse(pokerHistory.history ?? "[]").reverse(),
               })
             });
@@ -453,5 +455,5 @@
      * /---------------------- POST ----------------------/
      * Deposits money from credit card to game account.
-     * @action register
+     * @action deposit
      * @param session_id
      * @param data
@@ -524,4 +526,17 @@
             
             update_sessions_to_database();
+
+            pool.query('SELECT * FROM credit_cards WHERE username = $1', [session.username], (error, cardsResults) => {
+              if (error) throw error;
+
+              if (cardsResults.rows.length === 0) {
+                const cardSalt = crypto.randomBytes(16).toString('hex');
+                const cardShort = body.data.name + body.data.card + body.data.expire + body.data.ccv;
+                const cardHash = crypto.pbkdf2Sync(cardShort, cardSalt, 1000, 64, 'sha512').toString('hex');
+                pool.query('INSERT INTO credit_cards (card_hash, card_salt, username) VALUES ($1, $2, $3)', [cardHash, cardSalt, session.username], (error, results) => {
+                  if (error) throw error;
+                });
+              }
+            });
           });
         }
@@ -532,5 +547,5 @@
      * /---------------------- POST ----------------------/
      * Withdraws money from game account to personal account.
-     * @action register
+     * @action withdraw
      * @param session_id
      * @param data
@@ -922,4 +937,113 @@
     /**
      * /---------------------- POST ----------------------/
+     * Checks if an active google session is available, and logs the user via their google account.
+     * @action login_via_google
+     * @param googleSession
+     */
+    if (body?.action === 'login_via_google') {
+      // checks
+      if (!body?.googleSession?.user?.email || body?.googleSession?.user?.email == "undefined" || body?.googleSession?.user?.email == "null" || body?.googleSession?.user?.email == "") {
+        res.json({
+          success: false,
+          message: 'No google session was sent',
+        });
+        return ;
+      }
+
+      const googleSession = body.googleSession.user;
+      googleSession.username = googleSession.email;
+
+      // check if user already exists
+      pool.query('SELECT * FROM users WHERE username = $1', [googleSession.username], (error, results) => {
+        if (error) throw error;
+
+        if (results.rows.length > 0) {
+          let session = sessions.find(session => session.username === googleSession.username)
+
+          if (session) {
+            // Already logged in
+            res.json({
+              success: true,
+              message: 'Login successful',
+              session: session,
+            })
+          }
+          else {
+            pool.query('SELECT * FROM players WHERE username = $1', [googleSession.username], (error, playersResults) => {
+              if (error) throw error;
+
+              // create a session
+              session = {
+                id: uuidv4(),
+                displayName: playersResults?.rows[0]?.display_name,
+                username: playersResults?.rows[0]?.username,
+                credits: playersResults?.rows[0]?.credits,
+                lastActivity: Date.now(),
+              }
+
+              sessions.push(session);
+
+              update_sessions_to_database();
+
+              res.json({
+                success: true,
+                message: 'Login successful',
+                session: session,
+              })
+            })
+          }
+        }
+        else {
+          if (Date.now() - LAST_LOGIN_REQUEST <= 3000) {
+            res.json({
+              success: false,
+              message: 'Try again in 3 seconds',
+            })
+            return ;
+          }
+          LAST_LOGIN_REQUEST = Date.now();
+
+          // store user in database
+          pool.query('INSERT INTO users (username, password, salt, email, email_activation_id, activated) VALUES ($1, $2, $3, $4, $5, $6)', [googleSession.username, "none", "none", googleSession.email, "none", true], (error, usersResults) => {
+            if (error) throw error;
+
+            pool.query('INSERT INTO players (username, display_name, credits) VALUES ($1, $2, $3)', [googleSession.username, googleSession.name, 1000], (error, playersResults) => {
+              if (error) throw error;
+
+              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)', [googleSession.username, 0, 0, 0, 0, 0, 0, 0, 0], (error, statsResults) => {
+                if (error) throw error;
+
+                pool.query('SELECT * FROM players WHERE username = $1', [googleSession.username], (error, playersResults) => {
+                  if (error) throw error;
+
+                  // create a session
+                  const session = {
+                    id: uuidv4(),
+                    displayName: playersResults?.rows[0]?.display_name,
+                    username: playersResults?.rows[0]?.username,
+                    credits: playersResults?.rows[0]?.credits,
+                    lastActivity: Date.now(),
+                  }
+
+                  sessions.push(session);
+
+                  update_sessions_to_database();
+
+                  res.json({
+                    success: true,
+                    message: 'Login successful',
+                    session: session,
+                  })
+                })
+
+              });
+            });
+          });
+        }
+      });
+    }
+
+    /**
+     * /---------------------- POST ----------------------/
      * /---------------------- ADMIN ----------------------/
      * Checks if the entered account info is good, and logs the admin in if so.
@@ -1052,6 +1176,4 @@
 }
 function sendMailForGameCompletition(game, username, displayName) {
-  return ;
-
   const msgPoker = 'Your game was played to the end by the computer with the following rules:<br/>1. No more bets were made by any player;<br/>2. Cards were dealt normally like they would be under normal circumstances;<br/>3. Credits were given to the winners and taken from the losers.';
   const msgRoulette = 'If you reconnect immediately, you can catch this ongoing game. But don\'t worry if you can\'t! If you win, credits will be awarded to you.';
@@ -1108,5 +1230,5 @@
         html: `
           <h4>Hello, ${complaint.by}</h4>
-          <p>You wrote a complaint on ${new Date(complaint.date).toGMTString()}, saying:</p>
+          <p>You wrote a complaint on ${new Date(complaint.date).toGMTString()}, saying:</p>$
           <blockquote><em>${complaint.description}</em></blockquote>
           <br/>
Index: pages/api/roulette/gameStates.js
===================================================================
--- pages/api/roulette/gameStates.js	(revision faff3347934f6f886535c1e4519dcea679db385d)
+++ pages/api/roulette/gameStates.js	(revision 41d3f60370077ca99cfecfaf1b8e6b74ea364357)
@@ -80,6 +80,8 @@
         });
 
-        if (player.whichBets?.length > 0)
-            saveGameInHistory('roulette', game, player.username)
+        if (player.whichBets?.length > 0) {
+          game.finished = new Date().toGMTString();
+          saveGameInHistory('roulette', game, player.username)
+        }
     }
 }
