Skip to content

Commit

Permalink
dv 10002, upd iapi, utils
Browse files Browse the repository at this point in the history
  • Loading branch information
SorenEricMent committed Jul 11, 2022
1 parent b9eafab commit 35fd966
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 43 deletions.
108 changes: 74 additions & 34 deletions modules/iapi.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { generateNewToken, blake2bHash } from "./utils.mjs";
import {
generateNewToken, blake2bHash,
strASCIIOnly, strStrictLegal, basicPasswordRequirement, isValidEmail
} from "./utils.mjs";

Object.prototype.p = Object.prototype.hasOwnProperty;

class IAPI {
constructor(mysql, redis, siteConfig, log, salt) {
Expand All @@ -8,8 +13,31 @@ class IAPI {
this.log = log;
this.salt = salt;
}
userLogin(username, password) {
IP(req) {
if(this.siteConfig.ip_detect_method == "connection"){
return req.connection.remoteAddress;
}else if(this.siteConfig.ip_detect_method == "header"){
//Default header X-Forwarded-From.
if(req.headers.p(this.siteConfig.ip_detect_header)){
return req.headers[this.siteConfig.ip_detect_header];
}else{
this.log("error", "IAPI", "Dictated IP detection method is header, but header is not found");
if(req.headers.p("x-forwarded-for")){
return req.headers["x-forwarded-for"];
}else{
return req.connection.remoteAddress;
}
}
}else{
this.log("error", "IAPI", "Dictated IP detection method is not found");
return req.connection.remoteAddress;
}
}
userLogin(req, username, password) {
let connIP = this.IP(req);
let userAgent = req.headers['user-agent'];
return new Promise((resolve, reject) => {
password = blake2bHash(this.salt + password);
this.mysql.query(
"SELECT * FROM users WHERE username = ?",
[username],
Expand All @@ -24,9 +52,11 @@ class IAPI {
} else {
let user = results[0];
if (user.password === password) {
let newToken = generateNewToken(this.salt, username);

this.log("debug", "IAPI", "User logged in: " + username);
resolve({
"uid":user
"uid": user
});
} else {
this.log("debug", "IAPI", "Wrong password");
Expand All @@ -38,42 +68,52 @@ class IAPI {
);
});
}
userRegister(username, nickname, email, password) {
password = blake2bHash(password, this.salt);
userRegister(req, username, password, email, nickname) {
let connIP = this.IP(req);
let userAgent = req.headers['user-agent'];
return new Promise((resolve, reject) => {
this.mysql.query(
"SELECT * FROM users WHERE username = ?",
[username],
(err, results) => {
if (err) {
this.log("debug", "IAPI", "Failed to query database");
reject(err);
} else {
if (results.length === 0) {
this.mysql.query(
"INSERT INTO users (username, nickname, email, password, avatar, about, statistics, permissions, preferences) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
[username, nickname, email, password, "", "", "{}", "{}", "{}"],
(err, results) => {
if (err) {
this.log("debug", "IAPI", "Failed to insert user");
reject(err);
} else {
this.log("debug", "IAPI", "User registered: " + username);
resolve({
"uid":results.insertId
});
}
}
);
if (!basicPasswordRequirement(password)) {
reject("Password does not meet basic requirements(> 8 characters, contains at least one number, one letter)");
}else if (!strStrictLegal(username)) {
reject("Username does not meet strict legal requirements(only letters, numbers, and underscores)");
}else if (!isValidEmail(email)) {
reject("Email is not valid");
}else{
password = blake2bHash(this.salt + password);
this.mysql.query(
"SELECT * FROM users WHERE username = ?",
[username],
(err, results) => {
if (err) {
this.log("debug", "IAPI", "Failed to query database");
reject(err);
} else {
this.log("debug", "IAPI", "User already exists: " + username);
reject("User already exists");
if (results.length === 0) {
this.mysql.query(
"INSERT INTO users (username, nickname, email, password, avatar, about, statistics, permissions, preferences) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
[username, nickname, email, password, "", "", "{}", "{}", "{}"],
(err, results) => {
if (err) {
this.log("debug", "IAPI", "Failed to insert user");
reject(err);
} else {
this.log("debug", "IAPI", "User registered: " + username);
resolve({
"uid": results.insertId
});
}
}
);
} else {
this.log("debug", "IAPI", "User already exists: " + username);
reject("User already exists");
}
}
}
}
);
);
}
});
}
}

export {IAPI};
export { IAPI };
26 changes: 20 additions & 6 deletions modules/router.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {default as express} from "express";
import { version } from "./utils.mjs";
import { version, isAllString } from "./utils.mjs";
import { IAPI } from "./iapi.mjs";
import { default as fs } from "fs";
import { fileURLToPath } from "url";
import { join } from "path";
import { default as bodyParser } from "body-parser";

Object.prototype.p = Object.prototype.hasOwnProperty;

function initializeRouter(mysqlConnection, redisConnection, siteConfig, log, salt){
const iapi = new IAPI(mysqlConnection, redisConnection, siteConfig, log, salt);
let blorumRouter = express();
Expand Down Expand Up @@ -79,25 +81,37 @@ function initializeRouter(mysqlConnection, redisConnection, siteConfig, log, sal
);

blorumRouter.post('/user/login', function (req, res) {
console.log(req,res);
let b = req.body
if(b.p("username") && b.p("password")){
if(isAllString(b.username, b.password)){
iapi.userLogin(b.username, b.password, req).then(function(result){
res.set(commonHeader);
res.status(200).send(result);
}).catch(function(err){
res.set(commonHeader);
res.status(500).send(err);
}
);
}
}
res.set("Content-Type","application/json");
res.set(commonHeader);
res.status(200).send();
});

blorumRouter.post('/user/register', function (req, res) {
let b = req.body;
if(b.hasOwnProperty("username") && b.hasOwnProperty("password") && b.hasOwnProperty("email") && b.hasOwnProperty("nickname")){
if(typeof b.username == "string" && typeof b.password == "string" && typeof b.email == "string" && typeof b.nickname == "string" ){
if(b.p("username") && b.p("password") && b.p("email") && b.p("nickname")){
if(isAllString(b.username, b.password, b.email, b.nickname)){
try {
res.set("Content-Type","application/json");
res.set(commonHeader);
iapi.userRegister(b.username, b.nickname, b.password, b.email).then(function (result) {
iapi.userRegister(req, b.username, b.password, b.email, b.nickname).then(function (result) {
res.status(200).send(result);
}
).catch(function (error) {
log("debug", "Router", "Failed to register user: " + error);
res.sendStatus(500);
res.status(500).send(error);
});
} catch (error) {
log("debug", "Router", "Failed to register user: " + error);
Expand Down
24 changes: 22 additions & 2 deletions modules/utils.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { default as crypto } from "crypto";
import Redis from "ioredis";

const version = "1.0.0 in_dev (unf, debug) dv 10001";
const version = "1.0.0 in_dev (unf, debug) dv 10002";

const c = {
"reset": "\x1b[0m",
Expand Down Expand Up @@ -101,6 +101,15 @@ function isModuleAvailable(name) {
}
}

function isAllString(...args){
for(let i = 0; i < args.length; i++){
if(typeof args[i] !== "string"){
return false;
}
}
return true;
}

function strASCIIOnly(str){
return /^[\x00-\x7F]*$/.test(str);
}
Expand All @@ -109,6 +118,17 @@ function strStrictLegal(str){
return /^[a-zA-Z0-9_]+$/.test(str);
}

function basicPasswordRequirement(str){
//at least 8 characters, includes at least one number, one letter
return /^(?:(?=.*[a-z])|(?=.*[A-Z]))(?=.*\d)[^]{8,}$/.test(str);
}

function isValidEmail(str){
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
}

export {
version, outputLogs, outputLogsColored, blake2bHash, generateNewToken, isModuleAvailable, promisifiedMysqlConnect, promisifiedRedisConnect
version, outputLogs, outputLogsColored, blake2bHash, generateNewToken,
isModuleAvailable, promisifiedMysqlConnect, promisifiedRedisConnect,
strASCIIOnly, strStrictLegal, basicPasswordRequirement, isValidEmail, isAllString
};
2 changes: 1 addition & 1 deletion site_config.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ INSERT INTO `config`(`flag`, `value`) VALUES ("site_url","127.0.0.1");
INSERT INTO `config`(`flag`, `value`) VALUES ("site_title","Yet another Blorum site.");
INSERT INTO `config`(`flag`, `value`) VALUES ("site_excerpt","This is a Blorum site, where you could publish blogs and chat.");
INSERT INTO `config`(`flag`, `value`) VALUES ("site_logo","/favicon.ico");
INSERT INTO `config`(`flag`, `value`) VALUES ("ip_detect_method","raw_ip");
INSERT INTO `config`(`flag`, `value`) VALUES ("ip_detect_method","connection");
INSERT INTO `config`(`flag`, `value`) VALUES ("ip_detect_header","X-Forwarded-From");
INSERT INTO `config`(`flag`, `value`) VALUES ("user_cookie_expire_after","2630000");
INSERT INTO `config`(`flag`, `value`) VALUES ("admin_cookie_expire_after","1315000");
Expand Down
File renamed without changes.

0 comments on commit 35fd966

Please sign in to comment.