mirror of
https://github.com/MaciejkaG/statki.git
synced 2024-11-30 03:42:55 +01:00
Finishing touches to the new login
This commit is contained in:
parent
260383cd11
commit
fc01f72fa4
126
index.js
126
index.js
@ -95,7 +95,10 @@ app.get('/privacy', (req, res) => {
|
||||
app.get('/', async (req, res) => {
|
||||
let login = loginState(req);
|
||||
|
||||
if (login != 2) {
|
||||
if (login == 0) {
|
||||
req.session.userAgent = req.get('user-agent');
|
||||
req.session.loggedIn = 0;
|
||||
|
||||
const locale = new Lang(req.acceptsLanguages());
|
||||
|
||||
res.render('landing', {
|
||||
@ -104,6 +107,8 @@ app.get('/', async (req, res) => {
|
||||
}
|
||||
});
|
||||
// res.redirect('/login');
|
||||
} else if (login != 2) {
|
||||
res.redirect("/login");
|
||||
} else if (req.session.nickname == null) {
|
||||
auth.getLanguage(req.session.userId).then(language => {
|
||||
var locale;
|
||||
@ -359,18 +364,111 @@ io.on('connection', async (socket) => {
|
||||
const req = socket.request;
|
||||
const session = req.session;
|
||||
socket.session = session;
|
||||
// if (session.loginState != 2) {
|
||||
// socket.on('email login', (email, callback) => {
|
||||
// callback(session.nickname);
|
||||
// });
|
||||
// }
|
||||
|
||||
if (!await GInfo.isPlayerInGame(socket)) {
|
||||
if (session.nickname == null) {
|
||||
socket.disconnect();
|
||||
if (!session.loggedIn) {
|
||||
socket.on('email login', (email, callback) => {
|
||||
let login = socket.request.session.loggedIn;
|
||||
|
||||
if (login == 0 && email != null && validateEmail(email)) {
|
||||
if (checkFlag('authless')) {
|
||||
auth.loginAuthless(email).then(async result => {
|
||||
req.session.reload((err) => {
|
||||
if (err) return socket.disconnect();
|
||||
|
||||
req.session.userId = result.uid;
|
||||
req.session.loggedIn = 2;
|
||||
req.session.save();
|
||||
});
|
||||
|
||||
callback({ status: "ok", next: "done" });
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const locale = new Lang(session.langs);
|
||||
|
||||
auth.startVerification(email, getIPSocket(socket), socket.client.request.headers["user-agent"], locale.lang).then(async result => {
|
||||
if (result.status === 1 || result.status === -1) {
|
||||
req.session.reload((err) => {
|
||||
if (err) return socket.disconnect();
|
||||
|
||||
req.session.userId = result.uid;
|
||||
req.session.loggedIn = 1;
|
||||
req.session.save();
|
||||
});
|
||||
|
||||
callback({ status: "ok", next: "auth" });
|
||||
} else {
|
||||
callback({ status: "SrvErr", error: locale.t("landing.Server error") });
|
||||
}
|
||||
}).catch((err) => {
|
||||
const locale = new Lang(session.langs);
|
||||
|
||||
callback({ success: false, error: locale.t("landing.Unknown error") });
|
||||
throw err;
|
||||
});
|
||||
} else {
|
||||
const locale = new Lang(session.langs);
|
||||
|
||||
auth.loginAuthless(email).then(async result => {
|
||||
req.session.reload((err) => {
|
||||
if (err) return socket.disconnect();
|
||||
|
||||
req.session.userId = result.uid;
|
||||
req.session.loggedIn = 2;
|
||||
req.session.save();
|
||||
});
|
||||
|
||||
callback({ success: false, error: locale.t("landing.Wrong email address") });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('email auth', async (code, callback) => {
|
||||
let login = socket.request.session.loggedIn;
|
||||
|
||||
if (login == 1 && code != null && code.length <= 10 && code.length >= 8) {
|
||||
let finishResult = await auth.finishVerification(req.session.userId, code);
|
||||
if (finishResult) {
|
||||
req.session.reload((err) => {
|
||||
if (err) return socket.disconnect();
|
||||
|
||||
req.session.loggedIn = 2;
|
||||
req.session.save();
|
||||
});
|
||||
|
||||
callback({ status: "ok", next: "done" });
|
||||
} else {
|
||||
const locale = new Lang(session.langs);
|
||||
|
||||
callback({ success: false, error: locale.t("landing.Wrong authorisation code") });
|
||||
}
|
||||
} else {
|
||||
const locale = new Lang(session.langs);
|
||||
|
||||
callback({ success: false, error: locale.t("landing.Wrong authorisation code") });
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('disconnecting', () => {
|
||||
if (socket.request.session.loggedIn == 1) {
|
||||
req.session.reload((err) => {
|
||||
if (err) return socket.disconnect();
|
||||
|
||||
req.session.loggedIn = 0;
|
||||
req.session.save();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!await GInfo.isPlayerInGame(socket) || session.nickname != null) {
|
||||
// if (session.nickname == null) {
|
||||
// socket.disconnect();
|
||||
// return;
|
||||
// }
|
||||
|
||||
socket.on('whats my nick', (callback) => {
|
||||
callback(session.nickname);
|
||||
});
|
||||
@ -529,7 +627,7 @@ io.on('connection', async (socket) => {
|
||||
io.to(socket.rooms[1]).emit("player left");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
} else if (session.nickname != null) {
|
||||
const playerGame = await GInfo.getPlayerGameData(socket);
|
||||
|
||||
if (playerGame.data.state === 'pregame') {
|
||||
@ -784,6 +882,14 @@ function getIP(req) {
|
||||
}
|
||||
}
|
||||
|
||||
function getIPSocket(socket) {
|
||||
if (checkFlag("cloudflare_mode")) {
|
||||
return socket.client.request.headers['cf-connecting-ip'];
|
||||
} else {
|
||||
return socket.client.request.headers['x-forwarded-for'] || socket.handshake.address;
|
||||
}
|
||||
}
|
||||
|
||||
function checkFlag(key) {
|
||||
if (flags) {
|
||||
return flags.includes(key);
|
||||
|
14
lang/en.json
14
lang/en.json
@ -9,11 +9,23 @@
|
||||
"Connection error": "Connection error"
|
||||
},
|
||||
|
||||
"email": {
|
||||
"This is your Statki authorisation code": "%s is your Statki authorisation code"
|
||||
},
|
||||
|
||||
"landing": {
|
||||
"The #1 online multiplayer battleships game": "The #1 online multiplayer battleships game",
|
||||
"SCROLL DOWN": "SCROLL DOWN",
|
||||
|
||||
"Privacy policy": "Privacy policy"
|
||||
"Privacy policy": "Privacy policy",
|
||||
|
||||
"Server error": "Server error",
|
||||
"Unkown error": "Unknown error",
|
||||
"Wrong email address": "Wrong e-mail address",
|
||||
"Wrong authorisation code": "Wrong authorisation code",
|
||||
|
||||
"E-mail address is required": "E-mail address is required!",
|
||||
"Auth code is required": "Auth code is required"
|
||||
},
|
||||
|
||||
"menu": {
|
||||
|
14
lang/pl.json
14
lang/pl.json
@ -9,11 +9,23 @@
|
||||
"Connection error": "Błąd połączenia"
|
||||
},
|
||||
|
||||
"email": {
|
||||
"This is your Statki authorisation code": "%s to twój kod autoryzacyjny do statków"
|
||||
},
|
||||
|
||||
"landing": {
|
||||
"The #1 online multiplayer battleships game": "Najlepsza wielosobowa gra w statki",
|
||||
"SCROLL DOWN": "SCROLLUJ W DÓŁ",
|
||||
|
||||
"Privacy policy": "Polityka prywatności"
|
||||
"Privacy policy": "Polityka prywatności",
|
||||
|
||||
"Server error": "Bład serwera",
|
||||
"Unkown error": "Nieznany błąd",
|
||||
"Wrong email address": "Niepoprawny adres e-mail",
|
||||
"Wrong authorisation code": "Niepoprawny kod autoryzacji",
|
||||
|
||||
"E-mail address is required": "Adres e-mail jest wymagany!",
|
||||
"Auth code is required": "Kod autoryzacji jest wymagany!"
|
||||
},
|
||||
|
||||
"menu": {
|
||||
|
@ -4,6 +4,8 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 2rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
@ -11,6 +13,8 @@
|
||||
align-items: center;
|
||||
transform: translateY(-3rem);
|
||||
font-size: 1.25em;
|
||||
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.landing p {
|
||||
@ -41,7 +45,7 @@
|
||||
|
||||
z-index: 1;
|
||||
|
||||
transition: translate 1.5s ease-in-out;
|
||||
transition: translate 1s ease-in-out;
|
||||
}
|
||||
|
||||
.bgShip#bgs1 {
|
||||
@ -114,12 +118,21 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 5;
|
||||
transition: all 0.5s 0.3s ease, top 0.6s ease-in-out;
|
||||
transition: all 0.5s 0.3s, transform 0.5s 0.2s, opacity 0.5s 0.2s, top 0.6s ease-in-out;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
backdrop-filter: blur(0px);
|
||||
}
|
||||
|
||||
body.closed .loginContainer {
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
body.closed .landing {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.loginContainer.active {
|
||||
top: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
@ -249,8 +262,10 @@
|
||||
/* margin: 0; */
|
||||
left: 50vw;
|
||||
transform: translateX(-50%);
|
||||
width: 50%;
|
||||
z-index: 50;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
|
||||
@ -263,3 +278,14 @@
|
||||
.footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 820px) {
|
||||
.bgShip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer {
|
||||
bottom: 15px;
|
||||
width: 90%;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
}
|
||||
|
||||
.bshipstoast {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
backdrop-filter: blur(15px);
|
||||
color: white;
|
||||
padding: 0.75rem 1rem;
|
||||
|
@ -2,8 +2,12 @@ String.prototype.replaceAt = function (index, replacement) {
|
||||
return this.substring(0, index) + replacement + this.substring(index + replacement.length);
|
||||
}
|
||||
|
||||
const socket = io();
|
||||
|
||||
const charset = ["0", "1", "!", "@", "#", "$", "%", "&"];
|
||||
|
||||
const initialContent = $("#scrolldowntext").html();
|
||||
|
||||
setInterval(() => {
|
||||
var content = $("#scrolldowntext").html();
|
||||
const len = content.length;
|
||||
@ -22,6 +26,11 @@ setInterval(() => {
|
||||
setTimeout(() => {
|
||||
content = content.replaceAt(i, previousChar);
|
||||
$("#scrolldowntext").html(content);
|
||||
|
||||
if (i == len - 1) {
|
||||
content = initialContent;
|
||||
$("#scrolldowntext").html(initialContent);
|
||||
}
|
||||
}, duration * len + duration * i);
|
||||
}, duration * i);
|
||||
}
|
||||
@ -30,6 +39,30 @@ setInterval(() => {
|
||||
document.addEventListener("wheel", (event) => {
|
||||
if (event.deltaY > 0) {
|
||||
$(".loginContainer").addClass("active");
|
||||
animateShips();
|
||||
} else if (event.deltaY < 0) {
|
||||
$(".loginContainer").removeClass("active");
|
||||
}
|
||||
});
|
||||
|
||||
let touchStart = 0;
|
||||
|
||||
window.addEventListener("touchstart", function (event) {
|
||||
touchStart = event.touches[0].clientY;
|
||||
});
|
||||
|
||||
window.addEventListener("touchend", function (event) {
|
||||
touchEnd = event.changedTouches[0].clientY;
|
||||
|
||||
if (touchStart - touchEnd > 50) {
|
||||
$(".loginContainer").addClass("active");
|
||||
animateShips();
|
||||
} else if (touchStart - touchEnd < -50) {
|
||||
$(".loginContainer").removeClass("active");
|
||||
}
|
||||
});
|
||||
|
||||
function animateShips() {
|
||||
setTimeout(() => {
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
setTimeout(() => {
|
||||
@ -43,20 +76,118 @@ document.addEventListener("wheel", (event) => {
|
||||
$(field).css("scale", "1");
|
||||
}
|
||||
});
|
||||
} else if (event.deltaY < 0) {
|
||||
$(".loginContainer").removeClass("active");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
switchView("loginView");
|
||||
|
||||
const form = document.getElementById('loginForm');
|
||||
form.addEventListener('submit', (e) => {
|
||||
const loginForm = document.getElementById('loginForm');
|
||||
const emailInput = document.getElementById('email');
|
||||
|
||||
loginForm.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
console.log("a");
|
||||
if (emailInput.value) {
|
||||
lockUI(true);
|
||||
console.log("Logging in with e-mail:", emailInput.value);
|
||||
socket.emit("email login", emailInput.value, (response) => {
|
||||
console.log(response);
|
||||
switch (response.status) {
|
||||
case "ok":
|
||||
console.log("Logged in.");
|
||||
|
||||
console.log(response);
|
||||
|
||||
if (response.next === "done") {
|
||||
console.log("No authorisation required.");
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
switchView("authView");
|
||||
progressParalax();
|
||||
lockUI(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
Toastify({
|
||||
text: response.error,
|
||||
duration: 5000,
|
||||
newWindow: true,
|
||||
gravity: "bottom",
|
||||
position: "right",
|
||||
stopOnFocus: true,
|
||||
className: "bshipstoast",
|
||||
}).showToast();
|
||||
|
||||
lockUI(false);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
emailInput.value = '';
|
||||
} else {
|
||||
Toastify({
|
||||
text: window.locale["E-mail address is required"],
|
||||
duration: 5000,
|
||||
newWindow: true,
|
||||
gravity: "bottom",
|
||||
position: "right",
|
||||
stopOnFocus: true,
|
||||
className: "bshipstoast",
|
||||
}).showToast();
|
||||
}
|
||||
});
|
||||
|
||||
const authForm = document.getElementById('authForm');
|
||||
const codeInput = document.getElementById('authcode');
|
||||
|
||||
authForm.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (codeInput.value) {
|
||||
lockUI(true);
|
||||
console.log("Logging in with e-mail:", codeInput.value);
|
||||
socket.emit("email auth", codeInput.value, (response) => {
|
||||
switch (response.status) {
|
||||
case "ok":
|
||||
console.log("Authorised.");
|
||||
lockUI(false);
|
||||
|
||||
$("body").addClass("closed");
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 700);
|
||||
break;
|
||||
|
||||
default:
|
||||
Toastify({
|
||||
text: response.error,
|
||||
duration: 5000,
|
||||
newWindow: true,
|
||||
gravity: "bottom",
|
||||
position: "right",
|
||||
stopOnFocus: true,
|
||||
className: "bshipstoast",
|
||||
}).showToast();
|
||||
|
||||
lockUI(false);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
emailInput.value = '';
|
||||
} else {
|
||||
Toastify({
|
||||
text: window.locale["Auth code is required"],
|
||||
duration: 5000,
|
||||
newWindow: true,
|
||||
gravity: "bottom",
|
||||
position: "right",
|
||||
stopOnFocus: true,
|
||||
className: "bshipstoast",
|
||||
}).showToast();
|
||||
}
|
||||
});
|
||||
|
||||
var parallaxTranslateX = 0;
|
||||
|
@ -1,3 +1,5 @@
|
||||
switchView("mainMenuView");
|
||||
|
||||
const socket = io();
|
||||
|
||||
// Handling server-sent events
|
||||
|
@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
|
||||
import geoip from 'geoip-lite';
|
||||
|
||||
import mysql from 'mysql';
|
||||
import readline from "node:readline";
|
||||
import { Lang } from './localisation.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@ -105,6 +105,8 @@ export class MailAuth {
|
||||
startVerification(email, ip, agent, langId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const conn = mysql.createConnection(this.mysqlOptions);
|
||||
const lang = new Lang([langId]);
|
||||
|
||||
conn.query(`SELECT user_id, nickname FROM accounts WHERE email = ${conn.escape(email)}`, async (error, response) => {
|
||||
if (error) { reject(error); conn.end(); return; }
|
||||
if (response.length !== 0) {
|
||||
@ -138,13 +140,18 @@ export class MailAuth {
|
||||
|
||||
const lookup = geoip.lookup(ip);
|
||||
|
||||
const lookupData = `User-Agent: ${agent}\nAdres IP: ${ip}\nKraj: ${lookup.country}\nRegion: ${lookup.region}\nMiasto: ${lookup.city}`;
|
||||
var lookupData;
|
||||
if (lookup) {
|
||||
lookupData = `User-Agent: ${agent}\nAdres IP: ${ip}\nKraj: ${lookup.country}\nRegion: ${lookup.region}\nMiasto: ${lookup.city}`;
|
||||
} else {
|
||||
lookupData = `IP lookup failed`;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.mail.sendMail({
|
||||
from: this.mailFrom,
|
||||
to: email,
|
||||
subject: `${authCode} to twój kod autoryzacji do Statków`,
|
||||
subject: lang.t('email.This is your Statki authorisation code').replace("%s", authCode),
|
||||
html: html.replace("{{ CODE }}", authCode).replace("{{ LOOKUP }}", lookupData),
|
||||
});
|
||||
} catch (e) {
|
||||
@ -173,13 +180,18 @@ export class MailAuth {
|
||||
|
||||
const lookup = geoip.lookup(ip);
|
||||
|
||||
const lookupData = `User-Agent: ${agent}\nIP address: ${ip}\nCountry: ${lookup.country}\nRegion: ${lookup.region}\nCity: ${lookup.city}`;
|
||||
var lookupData;
|
||||
if (lookup) {
|
||||
lookupData = `User-Agent: ${agent}\nAdres IP: ${ip}\nKraj: ${lookup.country}\nRegion: ${lookup.region}\nMiasto: ${lookup.city}`;
|
||||
} else {
|
||||
lookupData = `IP lookup failed`;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.mail.sendMail({
|
||||
from: this.mailFrom,
|
||||
to: email,
|
||||
subject: `${authCode} to twój kod logowania do Statków`,
|
||||
subject: lang.t('email.This is your Statki authorisation code').replace("%s", authCode),
|
||||
html: html.replace("{{ NICKNAME }}", row.nickname).replace("{{ CODE }}", authCode).replace("{{ LOOKUP }}", lookupData),
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
<div>
|
||||
<form action="#" method="post" id="loginForm">
|
||||
<input type="email" name="email" placeholder="{{ t 'login.E-mail address' }}"
|
||||
style="font-size: 1rem;">
|
||||
style="font-size: 1rem;" id="email">
|
||||
<input type="submit" value="{{ t 'login.Proceed' }}">
|
||||
</form>
|
||||
</div>
|
||||
@ -55,9 +55,9 @@
|
||||
<div class="modes">
|
||||
<div>
|
||||
<p>{{ t 'auth.Enter the code sent to your e-mail box' }}</p>
|
||||
<form action="/api/auth" method="post">
|
||||
<form action="/api/auth" method="post" id="authForm">
|
||||
<input type="text" name="code" placeholder="{{ t 'auth.Code' }}" style="font-size: 1rem;"
|
||||
minlength="8" maxlength="10" autocomplete="off">
|
||||
minlength="8" maxlength="10" autocomplete="off" id="authcode">
|
||||
<input type="submit" value="{{ t 'auth.Login' }}">
|
||||
</form>
|
||||
</div>
|
||||
@ -83,6 +83,9 @@
|
||||
"Disconnected": "{{ t 'errors.Disconnected' }}",
|
||||
"Try to refresh the page if this error reoccurs": "{{ t 'errors.Try to refresh the page if this error reoccurs' }}",
|
||||
"Connection error": "{{ t 'errors.Connection error' }}",
|
||||
|
||||
"E-mail address is required": "{{ t 'landing.E-mail address is required' }}",
|
||||
"Auth code is required": "{{ t 'landing.Auth code is required' }}",
|
||||
};
|
||||
</script>
|
||||
<script src="/assets/js/spa_lib.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user