Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| db03373892 | |||
| 267ecaa705 | |||
| 3a8cfd39ed | |||
| b157ef18ff | |||
| 500035284f | |||
| c5360a70d6 | |||
| cf4c8a0f99 | |||
| 21527d8931 | |||
| a54e802942 | |||
| f8abd9110d | |||
| 406345ada1 | |||
| d79a70d66f | |||
| cec30620ec | |||
| 763efb75bf |
+2
-1
@@ -1,4 +1,5 @@
|
||||
FROM node:18
|
||||
|
||||
FROM node:18-bullseye-slim
|
||||
WORKDIR "/app"
|
||||
COPY package*.json ./
|
||||
RUN npm install --production
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2021 Kayne Ruse, KR Game Studios
|
||||
Copyright (c) 2021-2023 Kayne Ruse, KR Game Studios
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@ networks:
|
||||
`;
|
||||
|
||||
const dockerfile = `
|
||||
FROM node:18
|
||||
FROM node:18-bullseye-slim
|
||||
WORKDIR "/app"
|
||||
COPY package*.json ./
|
||||
RUN npm install --production
|
||||
|
||||
Generated
+1398
-1439
File diff suppressed because it is too large
Load Diff
+7
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "auth-server",
|
||||
"version": "1.6.4",
|
||||
"version": "1.7.5",
|
||||
"description": "An API centric auth server. Uses Sequelize and mariaDB by default.",
|
||||
"main": "server/server.js",
|
||||
"scripts": {
|
||||
@@ -24,14 +24,14 @@
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"express": "^4.18.2",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mariadb": "^3.0.2",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"mariadb": "^3.1.1",
|
||||
"node-cron": "^3.0.2",
|
||||
"node-fetch": "^2.6.7",
|
||||
"nodemailer": "^6.8.0",
|
||||
"sequelize": "^6.25.5"
|
||||
"node-fetch": "^2.6.9",
|
||||
"nodemailer": "^6.9.1",
|
||||
"sequelize": "^6.31.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^2.0.20"
|
||||
"nodemon": "^2.0.22"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,13 @@ const route = async (req, res) => {
|
||||
return res.status(401).send(validateErr);
|
||||
}
|
||||
|
||||
//script throttle
|
||||
const throttle = await checkThrottle(req.body.email);
|
||||
if (throttle) {
|
||||
console.warn(`Spam attack detected: ${req.body.email} (${req.body.username})`);
|
||||
return res.status(401).send(throttle);
|
||||
}
|
||||
|
||||
//generate the password hash
|
||||
const hash = await bcrypt.hash(req.body.password, await bcrypt.genSalt(11));
|
||||
|
||||
@@ -83,6 +90,10 @@ const validateDetails = async (body) => {
|
||||
return 'Missing password';
|
||||
}
|
||||
|
||||
if (typeof body.password != "string") {
|
||||
return 'Invalid password';
|
||||
}
|
||||
|
||||
if (body.password.length < 8) {
|
||||
return 'Password too short';
|
||||
}
|
||||
@@ -90,6 +101,25 @@ const validateDetails = async (body) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const checkThrottle = async (email) => {
|
||||
//check email delay
|
||||
const prev = await pendingSignups.findOne({
|
||||
where: {
|
||||
email: email,
|
||||
}
|
||||
});
|
||||
|
||||
const DateOffset = ( offset ) => { //Thanks, SO!
|
||||
return new Date( +new Date + offset );
|
||||
}
|
||||
|
||||
if (!!prev && prev.updatedAt > DateOffset( -5000 )) {
|
||||
return "An unknown error occurred";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const registerPendingSignup = async (body, hash, token) => {
|
||||
const record = await pendingSignups.upsert({
|
||||
email: body.email,
|
||||
|
||||
@@ -9,6 +9,12 @@ const TokenProvider = props => {
|
||||
//state to be used
|
||||
const [accessToken, setAccessToken] = useState('');
|
||||
|
||||
//force a logout under certain conditions
|
||||
const forceLogout = () => {
|
||||
localStorage.removeItem("accessToken");
|
||||
setAccessToken("");
|
||||
};
|
||||
|
||||
//make the access token persist between reloads
|
||||
useEffect(() => {
|
||||
setAccessToken(localStorage.getItem("accessToken") || '');
|
||||
@@ -19,6 +25,11 @@ const TokenProvider = props => {
|
||||
localStorage.setItem("accessToken", accessToken);
|
||||
}, [accessToken]);
|
||||
|
||||
//force a logout if refresh token is too old
|
||||
if (accessToken && (new Date(Date.now() - 60 * 60 * 24 * 30 * 1000).getTime() > decode(accessToken).exp * 1000)) {
|
||||
forceLogout();
|
||||
}
|
||||
|
||||
//wrap the default fetch function
|
||||
const tokenFetch = async (url, options) => {
|
||||
//use this?
|
||||
@@ -47,6 +58,9 @@ const TokenProvider = props => {
|
||||
|
||||
//any errors, throw them
|
||||
if (!response.ok) {
|
||||
if (response.status == 403) {
|
||||
forceLogout();
|
||||
}
|
||||
throw `${response.status}: ${await response.text()}`;
|
||||
}
|
||||
|
||||
@@ -82,6 +96,9 @@ const TokenProvider = props => {
|
||||
|
||||
//any errors, throw them
|
||||
if (!response.ok) {
|
||||
if (response.status == 403) {
|
||||
forceLogout();
|
||||
}
|
||||
throw `${response.status}: ${await response.text()}`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user