From c33f7bdd7bacd7810b79968735cf52906899c154 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 31 Aug 2018 17:08:04 +0100 Subject: [PATCH] Signup endpoints almost done --- src/app.js | 2 +- src/controllers/routes/router.js | 2 +- src/controllers/user.js | 62 +++++++++++++++++++-- src/models/api/API.js | 10 ++++ src/models/api/APIErrors.js | 39 +++++++++++++ src/models/api/baseAPI.js | 4 ++ src/models/api/userResponses.js | 34 +++++++++++ src/models/database/sqlite/database.sqlite | Bin 28672 -> 28672 bytes src/models/database/users.js | 15 +++-- src/models/logger.js | 6 ++ src/models/user/baseuser.js | 5 +- src/models/user/user.js | 6 +- 12 files changed, 163 insertions(+), 22 deletions(-) create mode 100644 src/models/api/API.js create mode 100644 src/models/api/APIErrors.js create mode 100644 src/models/api/baseAPI.js create mode 100644 src/models/api/userResponses.js diff --git a/src/app.js b/src/app.js index 78faee5..b4ac39a 100644 --- a/src/app.js +++ b/src/app.js @@ -15,8 +15,8 @@ async function init() { await Database.testConnection(); await Server.start(); await Router.initEndpoints(); - + Logger.ready(); // Logger.debug(JSON.stringify(await Database.users.getUserByID(12341356), null, 4)); // Logger.debug(JSON.stringify(await Database.users.listAll(), null, 4)); diff --git a/src/controllers/routes/router.js b/src/controllers/routes/router.js index 560d691..af4ae36 100644 --- a/src/controllers/routes/router.js +++ b/src/controllers/routes/router.js @@ -18,7 +18,7 @@ export class Router { app.delete('/user/:id', [MiddleWare.analytics]); app.post('/user', [MiddleWare.analytics, Controllers.UserController.newUser]); - app.use([MiddleWare.analytics, StatusCodes.pageNotFound]); + app.use([StatusCodes.pageNotFound]); Logger.info('HTTP endpoints settup'); } diff --git a/src/controllers/user.js b/src/controllers/user.js index c49cdf2..c88fce4 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -1,14 +1,66 @@ import {Logger} from '../models/logger'; import {ControllerHandler} from './controllerHandler'; +import {API} from '../models/api/api'; +import {Database} from '../models/database/database'; +import {User} from '../models/user/user'; export class UserController extends ControllerHandler { - static newUser(req, res, next) { - Logger.info('NEW USER'); + static async newUser(req, res, next) { + let errors = new API.errors(res); - let username = req.body.username || null; - let email = req.body.email || null; - let password = req.body.password || null; + let ip = req.connection.remoteAddress; + if (ip.startsWith('::ffff:')) ip = ip.substring(7); + let username = req.body.username || undefined; + let email = req.body.email || undefined; + let password = req.body.password || undefined; + + if (!username || !email || !password) errors.addError(422, 'Unprocessaable entity', 'Missing username, email or password in body of request'); + + if (!UserController.isUsernameValid(username)) errors.addError(422, 'Unprocessaable entity', 'Invalid username has special charicters (allowed A-z 0-9 - and _ without spaces)'); + if (!UserController.isEmailValid(email)) errors.addError(422, 'Unprocessaable entity', 'Invalid email'); + if (!UserController.isPasswordValid(password)) errors.addError(422, 'Unprocessaable entity', 'Invalid password has spaces'); + if (password.length < 7) errors.addError(422, 'Unprocessaable entity', 'Invalid password less than 7 charicters'); + + if (await Database.users.getID('username', username) == -1) errors.addError(422, 'Unprocessable entity', 'A user with that username allready exists'); + if (await Database.users.getID('email', email) == -1) errors.addError(422, 'Unprocessable entity', 'A user with that email allready exists'); + + let id = new Date().getTime(); + let token = "1234"; + + if (errors.count() > 0) { + errors.endpoint(); + next(); + } + + let success = new User(id, username, password, email, ip, 1234).insert(); + if (success == -1) { + errors.addError(500, 'Internal server error', 'An error occured with the databse').endpoint(); + next(); + } + + new API.user(res, id, username, email, new Date().toLocaleString(), token).endpoint(); next(); } + + static isUsernameValid(username) { + if (username.match(/[^A-Za-z0-9_-]/)) { + return false; + } + return true; + } + + static isEmailValid(email) { + if (email.match(/[^A-Za-z0-9@.-_]/)) { + return false; + } + return true; + } + + static isPasswordValid(pass) { + if (pass.match(/\s/)) { + return false; + } + return true; + } } diff --git a/src/models/api/API.js b/src/models/api/API.js new file mode 100644 index 0000000..8b4dbaa --- /dev/null +++ b/src/models/api/API.js @@ -0,0 +1,10 @@ +import {BaseAPI} from './baseAPI'; + +export class API extends BaseAPI { + constructor() { + super(); + } +} + +API.errors = require('./APIErrors').APIErrors; +API.user = require('./userResponses').User; diff --git a/src/models/api/APIErrors.js b/src/models/api/APIErrors.js new file mode 100644 index 0000000..425eeb7 --- /dev/null +++ b/src/models/api/APIErrors.js @@ -0,0 +1,39 @@ +import {API} from './API'; + +export class APIErrors extends API { + // get errors() {return this.errors} + // set errors(err) {this.errors = err} + + constructor(res) { + super() + this.res = res; + this.errors = { + status: { + error: true, + code: undefined, + type: undefined, + message: undefined + }, + error: { + errors: [] + } + } + } + + addError(statusCode, message, verbose) { + this.errors.error.errors.push({status: statusCode, title: message, detail: verbose}); + this.errors.status.code = statusCode; + this.errors.status.type = message; + this.errors.status.message = verbose; + } + + count() { + return this.errors.error.errors.length; + } + + endpoint() { + this.res.setHeader('Content-type', 'application/json'); + this.res.status(this.errors.status.code); + this.res.end(JSON.stringify(this.errors, false, 4)); + } +} diff --git a/src/models/api/baseAPI.js b/src/models/api/baseAPI.js new file mode 100644 index 0000000..c67d9f2 --- /dev/null +++ b/src/models/api/baseAPI.js @@ -0,0 +1,4 @@ + +export class BaseAPI { + constructor() { } +} diff --git a/src/models/api/userResponses.js b/src/models/api/userResponses.js new file mode 100644 index 0000000..3f63eda --- /dev/null +++ b/src/models/api/userResponses.js @@ -0,0 +1,34 @@ +import {API} from './API'; + +export class User extends API { + constructor(res, id, username, email, updated, token) { + super(); + this.res = res; + this.response = { + status: { + error: false, + code: 200, + type: 'success', + message: 'Success' + }, + data: [ + { + status: 'Authenticated', + user: { + id: id, + username: username, + email: email, + updated: updated + }, + token: token + } + ] + } + } + + endpoint() { + this.res.setHeader('Content-type', 'application/json'); + this.res.status(200); + this.res.end(JSON.stringify(this.response, false, 4)); + } +} diff --git a/src/models/database/sqlite/database.sqlite b/src/models/database/sqlite/database.sqlite index c74579fab8b568c73dc9ce9023f400ab7fffae0d..74117514b1cbabf489c283638802a43217760bad 100644 GIT binary patch delta 214 zcmZp8z}WDBae_1>+e8^>Mz)O!OZd5%`63zk3;CY#MQ#=p@aC&;v*onZ1^uplQfFV(=nAOJ)g8W;lkmBnB|hxFXU%pASs{9G$5Lqk(zQ*$FDb3+qL z0|P@NV-sCNBLhPVT>}eUV?zZ)V=H3|D`OKqO9NvCZ36=<0|QK19%SjwPvjIBxtRH% fGVp)k|H1!sv!KFter_&iRz`@km^XjW7jOUot*JMT delta 57 zcmV-90LK4--~oW(0gxL31(6&>0R^#Oqz?!J4&(q2aSr6O5g^zOv*aEi0SE#Q@Bk0+ P5BReYFys%j@GlTR8sigG diff --git a/src/models/database/users.js b/src/models/database/users.js index 274581c..e262c9d 100644 --- a/src/models/database/users.js +++ b/src/models/database/users.js @@ -2,7 +2,6 @@ import Sequelize from 'sequelize'; import {BaseDatabase} from './baseDatabase'; import {Logger} from '../logger'; -import {Config} from '../../config/config'; export class UserTools extends BaseDatabase { static async listAll() { @@ -36,7 +35,7 @@ export class UserTools extends BaseDatabase { let User = BaseDatabase.User; try { - let user = await User.destroy({where: {id: id}}); + await User.destroy({where: {id: id}}); return 1; } catch (e) { Logger.error(`An error occured while deleting user id ${id}: ${e}`); @@ -64,26 +63,26 @@ export class UserTools extends BaseDatabase { if (column == 'id') { return search; } else if (column == 'username') { - let user = await User.findOne({where: {username: serch}}); + let user = await User.findOne({where: {username: search}}); if (user == null) return -1; return user; } else if (column == 'password') { - let user = await User.findOne({where: {password: serch}}); + let user = await User.findOne({where: {password: search}}); if (user == null) return -1; return user; } else if (column == 'ip') { - let user = await User.findOne({where: {ip: serch}}); + let user = await User.findOne({where: {ip: search}}); if (user == null) return -1; return user; } else if (column == 'authcode') { - let user = await User.findOne({where: {authcode: serch}}); + let user = await User.findOne({where: {authcode: search}}); if (user == null) return -1; return user; } else { return -1 } } catch (e) { - Logger.error(`An error occured while querying the id of a user where ${term} is ${searchTerm}: ${e}`); + Logger.error(`An error occured while querying the id of a user where ${column} is ${search}: ${e}`); return -1; } } @@ -92,7 +91,7 @@ export class UserTools extends BaseDatabase { let User = BaseDatabase.User; try { - let user = await User.update({ip: newIP}, {where: {id: id}}); + await User.update({ip: newIP}, {where: {id: id}}); return 1; } catch (e) { Logger.error(`An error occured while updating user id ${id}'s ip: ${e}`); diff --git a/src/models/logger.js b/src/models/logger.js index 5cab5fa..e147b53 100644 --- a/src/models/logger.js +++ b/src/models/logger.js @@ -32,6 +32,12 @@ export class Logger { + colours.cyan('DEBUG') + '] ' + message); } + static ready() { + let d = new Date(); + console.log('[' + d.toLocaleString() + '] [' + + colours.rainbow('READY') + ']'); + } + static info(message) { if (LogLevel > 2) return; let d = new Date(); diff --git a/src/models/user/baseuser.js b/src/models/user/baseuser.js index 8525ce6..3ec1cc7 100644 --- a/src/models/user/baseuser.js +++ b/src/models/user/baseuser.js @@ -1,15 +1,12 @@ import {Logger} from '../logger'; export class BaseUser { - constructor(id, username, password, email, ip, lastupdated, verified, authcode, timeauthed) { + constructor(id, username, password, email, ip, authcode) { this.id = id; this.username = username; this.password = password; this.email = email; this.ip = ip; - this.lastupdated = lastupdated; - this.verified = verified; this.authcode = authcode; - this.timeauthed = timeauthed; } } diff --git a/src/models/user/user.js b/src/models/user/user.js index afc569f..c3d1aa0 100644 --- a/src/models/user/user.js +++ b/src/models/user/user.js @@ -3,13 +3,13 @@ import {BaseUser} from './baseUser'; import {Database} from '../database/database'; export class User extends BaseUser { - constructor(id, username, password, email, ip, lastupdated, verified, authcode, timeauthed) { - super(id, username, password, email, ip, lastupdated, verified, authcode, timeauthed); + constructor(id, username, password, email, ip, authcode) { + super(id, username, password, email, ip, authcode); } async insert() { this._instance = await Database.users.newUser(this.id, this.username, this.password, this.email, this.ip, this.authcode) - if (this._instance == -1) throw new Error('Failed to insert'); + if (this._instance == -1) return -1; Logger.debug(`New user [${this.id}] ${this.username}`); }