partly finished translation (not yet implemented)

This commit is contained in:
Maciej Gomoła 2024-03-26 12:41:28 +01:00
parent b987611ec8
commit 2e3a46b7e1
10 changed files with 496 additions and 18 deletions

View File

@ -15,12 +15,15 @@ import { MailAuth } from './utils/auth.js';
import { rateLimit } from 'express-rate-limit';
import { RedisStore as LimiterRedisStore } from 'rate-limit-redis';
import SessionRedisStore from 'connect-redis';
import { I18n } from 'i18n';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const flags = process.env.flags.split(",");
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
@ -34,6 +37,11 @@ const redis = createClient();
redis.on('error', err => console.log('Redis Client Error', err));
await redis.connect();
const i18n = new I18n({
locales: ['en', 'pl'],
directory: path.join(__dirname, 'lang')
});
const limiter = rateLimit({
windowMs: 40 * 1000,
limit: 500,
@ -72,7 +80,7 @@ const sessionMiddleware = session({
saveUninitialized: true,
rolling: true,
cookie: {
secure: process.env.cookie_secure === "true" ? true : false,
secure: checkFlag("cookie_secure"),
maxAge: 3 * 24 * 60 * 60 * 1000,
},
});
@ -137,13 +145,17 @@ app.post('/api/login', (req, res) => {
if (login == 2) {
res.redirect('/');
} else if (login == 0 && req.body.email != null && validateEmail(req.body.email)) {
auth.startVerification(req.body.email).then(result => {
if (result.status === 1) {
if (checkFlag('authless')) {
auth.loginAuthless(req.body.email).then(async result => {
req.session.userId = result.uid;
req.session.loggedIn = 2;
res.redirect('/');
});
req.session.loggedIn = 1;
res.redirect('/auth');
} else if (result.status === -1) {
return;
}
auth.startVerification(req.body.email, getIP(req, req.get('User-Agent'))).then(async result => {
if (result.status === 1 || result.status === -1) {
req.session.userId = result.uid;
req.session.loggedIn = 1;
@ -151,6 +163,14 @@ app.post('/api/login', (req, res) => {
} else {
res.sendStatus(500);
}
}).catch((err) => {
res.render("error", {
helpers: {
error: "Wystąpił nieznany błąd logowania",
fallback: "/login"
}
});
throw err;
});
} else {
res.render("error", {
@ -550,3 +570,15 @@ function validateEmail(email) {
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
);
};
function getIP(req) {
if (checkFlag("cloudflare_mode")) {
return req.headers['cf-connecting-ip'];
} else {
return req.headers['x-forwarded-for'] || req.socket.remoteAddress;
}
}
function checkFlag(key) {
return flags.includes(key);
}

65
lang/en.json Normal file
View File

@ -0,0 +1,65 @@
{
"errors": {
"Reonnecting...": "Reconnecting...",
"Reconnected": "Reconnected",
"Reconnection error occured": "Reconnection error occured",
"Reconection failed": "Reconnection failed",
"Disconnected": "Disconnected",
"Try to refresh the page if this error reoccurs": "Try to refresh the page if this error reoccurs",
"Connection error": "Connection error"
},
"menu": {
"navbar": {
"Main menu": "Main menu",
"Profile": "Profile"
},
"index": {
"Select game mode": "Select game mode",
"PvP": "PvP",
"Play against another player": "Play against another player",
"Vs. AI": "Vs. AI",
"Play against the computer": "Play against the computer"
},
"PvP": {
"PvP": "PvP",
"Create": "Create",
"Create your own room": "Create your own room",
"Join": "Join",
"Join a room by a code": "Join a room by a code"
},
"PvP/Create": {
"PvP / Create": "PvP / Create",
"Room code:": "Room code:",
"Waiting for an opponent": "Waiting for an opponent",
"Leave the room": "Leave the room"
},
"PvP/Join": {
"PvP / Join": "PvP / Join",
"Room code": "Room code",
"Join": "Join"
},
"PvP/Prepairing": {
"PvP / Loading": "PvP / Loading",
"Wait...": "Wait...",
"You will be redirected soon": "You will be redirected soon",
"Opponent:": "Opponent"
},
"Profile": {
"Loading...": "Loading...",
"Player since: ": "Player since: ",
"Victory": "Victory",
"Defeat": "Defeat",
"Click to view match statistics": "Click to view match statistics",
"matches played this month": "matches played this month",
"total matches played": "total matches played",
"winrate": "winrate",
"No matches played": "No matches played"
},
"General": {
"Unknown error occured": "Unknown error occured",
"Status:": "Status:"
}
}
}

0
lang/pl.json Normal file
View File

336
package-lock.json generated
View File

@ -15,6 +15,8 @@
"express-handlebars": "^7.1.2",
"express-rate-limit": "^7.2.0",
"express-session": "^1.18.0",
"geoip-lite": "^1.4.10",
"i18n": "^0.15.1",
"mysql": "^2.18.1",
"nodemailer": "^6.9.12",
"rate-limit-redis": "^4.2.0",
@ -40,6 +42,45 @@
"node": ">=12"
}
},
"node_modules/@messageformat/core": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.3.0.tgz",
"integrity": "sha512-YcXd3remTDdeMxAlbvW6oV9d/01/DZ8DHUFwSttO3LMzIZj3iO0NRw+u1xlsNNORFI+u0EQzD52ZX3+Udi0T3g==",
"dependencies": {
"@messageformat/date-skeleton": "^1.0.0",
"@messageformat/number-skeleton": "^1.0.0",
"@messageformat/parser": "^5.1.0",
"@messageformat/runtime": "^3.0.1",
"make-plural": "^7.0.0",
"safe-identifier": "^0.4.1"
}
},
"node_modules/@messageformat/date-skeleton": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.0.1.tgz",
"integrity": "sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg=="
},
"node_modules/@messageformat/number-skeleton": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz",
"integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg=="
},
"node_modules/@messageformat/parser": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.0.tgz",
"integrity": "sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ==",
"dependencies": {
"moo": "^0.5.1"
}
},
"node_modules/@messageformat/runtime": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz",
"integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==",
"dependencies": {
"make-plural": "^7.0.0"
}
},
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -167,6 +208,14 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/async": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dependencies": {
"lodash": "^4.17.14"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -224,6 +273,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/boolean": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="
},
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@ -232,6 +286,14 @@
"balanced-match": "^1.0.0"
}
},
"node_modules/buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"engines": {
"node": "*"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -258,6 +320,35 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chalk/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
@ -282,6 +373,11 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/connect-redis": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.1.tgz",
@ -631,6 +727,25 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/fast-printf": {
"version": "1.6.9",
"resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.9.tgz",
"integrity": "sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==",
"dependencies": {
"boolean": "^3.1.4"
},
"engines": {
"node": ">=10.0"
}
},
"node_modules/fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"dependencies": {
"pend": "~1.2.0"
}
},
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
@ -692,6 +807,11 @@
"node": ">= 0.6"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@ -708,6 +828,23 @@
"node": ">= 4"
}
},
"node_modules/geoip-lite": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/geoip-lite/-/geoip-lite-1.4.10.tgz",
"integrity": "sha512-4N69uhpS3KFd97m00wiFEefwa+L+HT5xZbzPhwu+sDawStg6UN/dPwWtUfkQuZkGIY1Cj7wDVp80IsqNtGMi2w==",
"dependencies": {
"async": "2.1 - 2.6.4",
"chalk": "4.1 - 4.1.2",
"iconv-lite": "0.4.13 - 0.6.3",
"ip-address": "5.8.9 - 5.9.4",
"lazy": "1.0.11",
"rimraf": "2.5.2 - 2.7.1",
"yauzl": "2.9.2 - 2.10.0"
},
"engines": {
"node": ">=10.3.0"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
@ -783,6 +920,14 @@
"uglify-js": "^3.1.4"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
@ -842,6 +987,25 @@
"node": ">= 0.8"
}
},
"node_modules/i18n": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/i18n/-/i18n-0.15.1.tgz",
"integrity": "sha512-yue187t8MqUPMHdKjiZGrX+L+xcUsDClGO0Cz4loaKUOK9WrGw5pgan4bv130utOwX7fHE9w2iUeHFalVQWkXA==",
"dependencies": {
"@messageformat/core": "^3.0.0",
"debug": "^4.3.3",
"fast-printf": "^1.6.9",
"make-plural": "^7.0.0",
"math-interval-parser": "^2.0.1",
"mustache": "^4.2.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/mashpie"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -853,11 +1017,33 @@
"node": ">=0.10.0"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ip-address": {
"version": "5.9.4",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-5.9.4.tgz",
"integrity": "sha512-dHkI3/YNJq4b/qQaz+c8LuarD3pY24JqZWfjB8aZx1gtpc2MDILu9L9jpZe1sHpzo/yWFweQVn+U//FhazUxmw==",
"dependencies": {
"jsbn": "1.1.0",
"lodash": "^4.17.15",
"sprintf-js": "1.1.2"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@ -901,6 +1087,24 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
},
"node_modules/lazy": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz",
"integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==",
"engines": {
"node": ">=0.2.0"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lru-cache": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz",
@ -909,6 +1113,19 @@
"node": "14 || >=16.14"
}
},
"node_modules/make-plural": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz",
"integrity": "sha512-/K3BC0KIsO+WK2i94LkMPv3wslMrazrQhfi5We9fMbLlLjzoOSJWr7TAdupLlDWaJcWxwoNosBkhFDejiu5VDw=="
},
"node_modules/math-interval-parser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz",
"integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -990,11 +1207,24 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/moo": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
"bin": {
"mustache": "bin/mustache"
}
},
"node_modules/mysql": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
@ -1070,6 +1300,14 @@
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@ -1078,6 +1316,14 @@
"node": ">= 0.8"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@ -1106,6 +1352,11 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -1210,6 +1461,56 @@
"@redis/time-series": "1.0.5"
}
},
"node_modules/rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
}
},
"node_modules/rimraf/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/rimraf/node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -1229,6 +1530,11 @@
}
]
},
"node_modules/safe-identifier": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz",
"integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w=="
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@ -1402,6 +1708,11 @@
"node": ">=0.10.0"
}
},
"node_modules/sprintf-js": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
},
"node_modules/sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
@ -1519,6 +1830,17 @@
"node": ">=8"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@ -1716,6 +2038,11 @@
"node": ">=8"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
@ -1740,6 +2067,15 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"dependencies": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
}
}
}

View File

@ -25,6 +25,8 @@
"express-handlebars": "^7.1.2",
"express-rate-limit": "^7.2.0",
"express-session": "^1.18.0",
"geoip-lite": "^1.4.10",
"i18n": "^0.15.1",
"mysql": "^2.18.1",
"nodemailer": "^6.9.12",
"rate-limit-redis": "^4.2.0",

View File

@ -43,10 +43,10 @@ socket.emit("my profile", (profile) => {
for (let i = 0; i < matchHistory.length; i++) {
const match = matchHistory[i];
let date = new Date(match.date).toLocaleDateString("pl-PL", options);
let date = new Date(match.date).toLocaleDateString(undefined, options);
const minutes = Math.floor(match.duration / 60).toLocaleString('pl-PL', { minimumIntegerDigits: 2, useGrouping: false });
const seconds = (match.duration - minutes * 60).toLocaleString('pl-PL', { minimumIntegerDigits: 2, useGrouping: false });
const seconds = (match.duration - minutes * 60).toLocaleString(undefined, { minimumIntegerDigits: 2, useGrouping: false });
const minutes = Math.floor(match.duration / 60).toLocaleString(undefined, { minimumIntegerDigits: 2, useGrouping: false });
const duration = `${minutes}:${seconds}`;
@ -54,7 +54,7 @@ socket.emit("my profile", (profile) => {
}
if (matchHistoryDOM === "") {
matchHistoryDOM = "<h2>Brak zagranych meczów</h2>";
matchHistoryDOM = `<h2>${locale["No matches played"]}</h2>`;
}
$(".matchList").html(matchHistoryDOM);
@ -84,7 +84,7 @@ $("#createGameButton").on("click", function () {
break;
default:
alert(`Wystąpił nieznany problem\nStatus: ${response.status}`);
alert(`${locale["Unknown error occured"]}\n${locale["Status:"]} ${response.status}`);
lockUI(false);
break;
}
@ -122,7 +122,7 @@ form.addEventListener('submit', (e) => {
// break;
default:
alert(`Wystąpił nieznany problem\nStatus: ${response.status}`);
alert(`${locale["Unknown error occured"]}\n${locale["Status:"]} ${response.status}`);
lockUI(false);
switchView("mainMenuView");
break;

View File

@ -1,8 +1,8 @@
import nodemailer from 'nodemailer';
import uuid4 from 'uuid4';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import geoip from 'geoip-lite';
import mysql from 'mysql';
import readline from "node:readline";
@ -60,7 +60,35 @@ export class MailAuth {
await this.redis.set(`loginTimer:${tId}`, -lastUpdate);
}
startVerification(email) {
loginAuthless(email) {
return new Promise((resolve, reject) => {
const conn = mysql.createConnection(this.mysqlOptions);
conn.query(`SELECT user_id, nickname FROM accounts WHERE email = ${conn.escape(email)}`, async (error, response) => {
if (error) { reject(error); return; }
if (response.length === 0 || response[0].nickname == null) {
if (response.length === 0) {
conn.query(`INSERT INTO accounts(email) VALUES (${conn.escape(email)});`, (error) => { if (error) reject(error) });
}
conn.query(`SELECT user_id FROM accounts WHERE email = ${conn.escape(email)}`, async (error, response) => {
if (error) reject(error);
const row = response[0];
resolve({ status: 1, uid: row.user_id });
});
return;
}
const row = response[0];
resolve({ status: 1, uid: row.user_id });
});
});
}
startVerification(email, ip, agent) {
return new Promise((resolve, reject) => {
const conn = mysql.createConnection(this.mysqlOptions);
conn.query(`SELECT user_id, nickname FROM accounts WHERE email = ${conn.escape(email)}`, async (error, response) => {
@ -68,7 +96,7 @@ export class MailAuth {
if (response.length !== 0) {
let timer = await this.redis.get(`loginTimer:${response[0].user_id}`);
if (timer && timer > 0) {
resolve({ status: -1, uid: response[0].user_id });
resolve({ status: -1, uid: response[0].user_id, });
return;
}
}
@ -104,7 +132,7 @@ export class MailAuth {
reject(e);
}
resolve({ status: 1, uid: row.user_id });
resolve({ status: 1, uid: row.user_id, code: authCode });
});
return;
@ -123,11 +151,15 @@ export class MailAuth {
authCode = authCode.slice(0, 4) + " " + authCode.slice(4);
const lookup = geoip.lookup(ip);
const lookupData = `User-Agent: ${agent}\nAdres IP: ${ip}\nKraj: ${lookup.country}\nRegion: ${lookup.region}\nMiasto: ${lookup.city}`
await this.mail.sendMail({
from: this.mailFrom,
to: email,
subject: `${authCode} to twój kod logowania do Statków`,
html: html.replace("{{ NICKNAME }}", row.nickname).replace("{{ CODE }}", authCode),
html: html.replace("{{ NICKNAME }}", row.nickname).replace("{{ CODE }}", authCode).replace("{{ LOOKUP }}", lookupData),
});
resolve({ status: 1, uid: row.user_id });

View File

@ -19,6 +19,9 @@
{{ CODE }}
</div>
<p>Powyższy kod wygasa po 10 minutach</p>
<p>Poniżej znajdują się informacje o logującym się urządzeniu*</p>
<pre style="text-align: left;">{{ LOOKUP }}</pre>
<p style="font-size: 12px;">* Dane lokalizacyjne mogą mijać się z prawdą. Traktuj je z dystansem</p>
</div>
<p style="color:white;margin-bottom: 20px;margin-top: 20px;text-align: center;"><a href="https://maciejka.xyz/"
style="text-decoration: none;color:white;">Copyright © 2024 MCJK</a> | <a

View File

@ -19,6 +19,9 @@
{{ CODE }}
</div>
<p>Powyższy kod wygasa po 10 minutach</p>
<p>Poniżej znajdują się informacje o logującym się urządzeniu*</p>
<pre style="text-align: left;">{{ LOOKUP }}</pre>
<p style="font-size: 12px;">* Dane lokalizacyjne mogą mijać się z prawdą. Traktuj je z dystansem</p>
</div>
<p style="color:white;margin-bottom: 20px;margin-top: 20px;text-align: center;"><a href="https://maciejka.xyz/"
style="text-decoration: none;color:white;">Copyright © 2024 MCJK</a> | <a

View File

@ -39,7 +39,7 @@
<div class="modes">
<div>
<h2>Kod pokoju:</h2>
<input type="text" maxlength="6" readonly value="123456" id="createGameCode">
<input type="text" maxlength="6" readonly value="-" id="createGameCode">
<h3>Oczekiwanie na gracza...</h3>
<button id="leaveGameButton">Opuść pokój</button>
</div>
@ -102,6 +102,11 @@
</div>
</div>
<script>
locale = {
"Unknown error occured": "{{ __('Profile.') }}"
}
</script>
<script src="/assets/js/spa_lib.js"></script>
<script src="/assets/js/socket.js"></script>
<script src="/assets/js/socket-err-handler.js"></script>