Compare commits

..

No commits in common. "b787e79a00cdea3bc4239451871b9cd6a51f70af" and "260383cd11f343507cb0ba47b8977b346edc57bf" have entirely different histories.

11 changed files with 47 additions and 392 deletions

130
index.js
View File

@ -95,10 +95,7 @@ app.get('/privacy', (req, res) => {
app.get('/', async (req, res) => {
let login = loginState(req);
if (login == 0) {
req.session.userAgent = req.get('user-agent');
req.session.loggedIn = 0;
if (login != 2) {
const locale = new Lang(req.acceptsLanguages());
res.render('landing', {
@ -107,8 +104,6 @@ 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;
@ -364,111 +359,18 @@ 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 (!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" });
});
if (!await GInfo.isPlayerInGame(socket)) {
if (session.nickname == null) {
socket.disconnect();
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);
});
@ -622,16 +524,12 @@ io.on('connection', async (socket) => {
}
});
socket.on('logout', () => {
session.destroy();
});
socket.on('disconnecting', () => {
if (bships.isPlayerInRoom(socket)) {
io.to(socket.rooms[1]).emit("player left");
}
});
} else if (session.nickname != null) {
} else {
const playerGame = await GInfo.getPlayerGameData(socket);
if (playerGame.data.state === 'pregame') {
@ -886,14 +784,6 @@ 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);

View File

@ -9,23 +9,11 @@
"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",
"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"
"Privacy policy": "Privacy policy"
},
"menu": {
@ -77,8 +65,7 @@
"No matches played": "No matches played"
},
"Settings": {
"General": "General",
"Log out": "Log out"
"General": "General"
},
"General": {
"Unknown error occured": "Unknown error occured",

View File

@ -9,23 +9,11 @@
"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",
"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!"
"Privacy policy": "Polityka prywatności"
},
"menu": {
@ -78,8 +66,7 @@
"No matches played": "Nie zagrano żadnych meczy"
},
"Settings": {
"General": "Ogólne",
"Log out": "Wyloguj się"
"General": "Ogólne"
},
"General": {
"Unknown error occured": "Wystąpił nieznany błąd",

View File

@ -4,8 +4,6 @@
position: absolute;
top: 0;
left: 0;
padding: 2rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
text-align: center;
@ -13,8 +11,6 @@
align-items: center;
transform: translateY(-3rem);
font-size: 1.25em;
transition: opacity 0.3s;
}
.landing p {
@ -45,7 +41,7 @@
z-index: 1;
transition: translate 1s ease-in-out;
transition: translate 1.5s ease-in-out;
}
.bgShip#bgs1 {
@ -118,21 +114,12 @@
width: 100%;
height: 100%;
z-index: 5;
transition: all 0.5s 0.3s, transform 0.5s 0.2s, opacity 0.5s 0.2s, top 0.6s ease-in-out;
transition: all 0.5s 0.3s ease, 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);
@ -262,10 +249,8 @@ body.closed .landing {
/* margin: 0; */
left: 50vw;
transform: translateX(-50%);
width: 50%;
z-index: 50;
font-size: 16px;
text-align: center;
font-family: 'Roboto Mono', monospace;
}
@ -278,14 +263,3 @@ body.closed .landing {
.footer a:hover {
text-decoration: underline;
}
@media only screen and (max-width: 820px) {
.bgShip {
display: none;
}
.footer {
bottom: 15px;
width: 90%;
}
}

View File

@ -14,7 +14,7 @@
}
.bshipstoast {
background: rgba(0, 0, 0, 0.6);
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(15px);
color: white;
padding: 0.75rem 1rem;
@ -338,26 +338,3 @@ nav span:hover {
outline: none;
margin-left: 2rem;
}
#settingsView a {
text-decoration: none;
color: var(--dynamic);
transition: opacity 0.3s;
}
#settingsView a:hover {
opacity: 0.6;
text-decoration: underline;
}
#logout {
color: var(--danger);
cursor: pointer;
transition: opacity 0.3s;
}
#logout:hover {
opacity: 0.6;
}

View File

@ -2,12 +2,8 @@ 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;
@ -26,11 +22,6 @@ 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);
}
@ -39,30 +30,6 @@ 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(() => {
@ -76,122 +43,20 @@ function animateShips() {
$(field).css("scale", "1");
}
});
}
switchView("loginView");
const loginForm = document.getElementById('loginForm');
const emailInput = document.getElementById('email');
loginForm.addEventListener('submit', (e) => {
e.preventDefault();
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.");
$("body").addClass("closed");
setTimeout(() => {
window.location.reload();
}, 700);
return;
}
lockUI(false);
switchView("authView");
progressParalax();
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();
} else if (event.deltaY < 0) {
$(".loginContainer").removeClass("active");
}
});
const authForm = document.getElementById('authForm');
const codeInput = document.getElementById('authcode');
switchView("loginView");
authForm.addEventListener('submit', (e) => {
const form = document.getElementById('loginForm');
form.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();
}
console.log("a");
switchView("authView");
progressParalax();
});
var parallaxTranslateX = 0;

View File

@ -1,5 +1,3 @@
switchView("mainMenuView");
const socket = io();
// Handling server-sent events
@ -144,12 +142,6 @@ $("#pvpMenuButton").on("click", function () {
switchView('pvpMenuView');
});
$("#logout").on("click", function() {
lockUI(true);
socket.emit("logout");
window.location.reload();
});
const form = document.getElementById('pvpJoinForm');
const input = document.getElementById('pvpJoinCode');

View File

@ -23,10 +23,10 @@ function switchView(viewContainerId, useReplaceState=false) {
function lockUI(doLock) {
if (doLock) {
$("body").css("pointer-events", "none");
$(".container").css("opacity", "0.4");
$("body").css("opacity", "0.4");
} else {
$("body").css("pointer-events", "inherit");
$(".container").css("opacity", "1");
$("body").css("opacity", "1");
}
}

View File

@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
import geoip from 'geoip-lite';
import mysql from 'mysql';
import { Lang } from './localisation.js';
import readline from "node:readline";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@ -105,8 +105,6 @@ 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) {
@ -140,18 +138,13 @@ export class MailAuth {
const lookup = geoip.lookup(ip);
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`;
}
const lookupData = `User-Agent: ${agent}\nAdres IP: ${ip}\nKraj: ${lookup.country}\nRegion: ${lookup.region}\nMiasto: ${lookup.city}`;
try {
await this.mail.sendMail({
from: this.mailFrom,
to: email,
subject: lang.t('email.This is your Statki authorisation code').replace("%s", authCode),
subject: `${authCode} to twój kod autoryzacji do Statków`,
html: html.replace("{{ CODE }}", authCode).replace("{{ LOOKUP }}", lookupData),
});
} catch (e) {
@ -180,18 +173,13 @@ export class MailAuth {
const lookup = geoip.lookup(ip);
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`;
}
const lookupData = `User-Agent: ${agent}\nIP address: ${ip}\nCountry: ${lookup.country}\nRegion: ${lookup.region}\nCity: ${lookup.city}`;
try {
await this.mail.sendMail({
from: this.mailFrom,
to: email,
subject: lang.t('email.This is your Statki authorisation code').replace("%s", authCode),
subject: `${authCode} to twój kod logowania do Statków`,
html: html.replace("{{ NICKNAME }}", row.nickname).replace("{{ CODE }}", authCode).replace("{{ LOOKUP }}", lookupData),
});
} catch (e) {

View File

@ -100,8 +100,6 @@
<select name="language" id="languages">
</select>
<h3><a href="/privacy" target="_blank">{{ t 'landing.Privacy policy' }}</a></h3>
<h3 id="logout">{{ t 'menu.Settings.Log out' }}</h3>
</div>
</div>

View File

@ -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;" id="email">
style="font-size: 1rem;">
<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" id="authForm">
<form action="/api/auth" method="post">
<input type="text" name="code" placeholder="{{ t 'auth.Code' }}" style="font-size: 1rem;"
minlength="8" maxlength="10" autocomplete="off" id="authcode">
minlength="8" maxlength="10" autocomplete="off">
<input type="submit" value="{{ t 'auth.Login' }}">
</form>
</div>
@ -83,9 +83,6 @@
"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>