3 Commits
dev ... master

Author SHA1 Message Date
Benjamin Kyd
7fb9bdd2f6 Merge pull request #5 from plane000/add-license-1
Create LICENSE
2019-02-03 20:30:11 +00:00
Benjamin Kyd
3463bd2d4b Create LICENSE 2019-02-03 20:29:51 +00:00
Benjamin Kyd
47193bf86e Merge pull request #4 from plane000/dev
Merge stable branch dev to master
2018-11-09 18:29:25 +00:00
16 changed files with 104 additions and 66 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Benjamin Kyd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -30,6 +30,6 @@ export class APIErrors extends API {
endpoint() {
this.res
.status(this.errors.status.code)
.send(JSON.stringify(this.errors, false, 4));
.end(JSON.stringify(this.errors, false, 4));
}
}

View File

@@ -29,8 +29,6 @@ export class NoteAPI extends API {
}
endpoint() {
this.res
.status(201)
.send(JSON.stringify(this.response, false, 4));
this.res.status(201).end(JSON.stringify(this.response, false, 4));
}
}

View File

@@ -28,8 +28,6 @@ export class PermaLinkAPI extends API {
}
endpoint() {
this.res
.status(201)
.send(JSON.stringify(this.response, false, 4));
this.res.status(201).end(JSON.stringify(this.response, false, 4));
}
}

View File

@@ -42,9 +42,7 @@ export class UserAPI extends API {
}
}
async endpoint() {
await this.res
.status(200)
.send(JSON.stringify(this.response, false, 4));
endpoint() {
this.res.status(200).end(JSON.stringify(this.response, false, 4));
}
}

View File

@@ -2,7 +2,6 @@ import {ControllerHandler} from './controllerHandler';
import {API} from './api/api';
import {Database} from '../models/database/database'
import {User} from '../models/user/user';
import { Logger } from '../models/logger';
export class LoginController extends ControllerHandler {
static async authenticate(req, res, next) {
@@ -18,7 +17,11 @@ export class LoginController extends ControllerHandler {
if (!password) errors.addError(400, 'Bad request', 'A password is required');
if (!username && !email) errors.addError(400, 'Bad request', 'A username or email is required');
if (errors.count() > 0) return next(errors);
if (errors.count() > 0) {
errors.endpoint();
next();
return;
}
let user;
if (!username /*If they're loging in with email*/) {
@@ -31,15 +34,21 @@ export class LoginController extends ControllerHandler {
email = user.email;
}
if (errors.count() > 0) return next(errors);
if (errors.count() > 0) {
errors.endpoint();
next();
return;
}
const match = await User.Password.compare(password, user.password);
if (!match) {
errors.addError(401, 'Unauthorized', 'Incorrect password for user');
return next(errors);
errors.endpoint();
next();
return;
}
let response = new API.user(res, user.id, username, email, new Date(parseInt(user.lastupdated)).toLocaleString());
const response = new API.user(res, user.id, username, email, new Date(parseInt(user.lastupdated)).toLocaleString());
let token = await Database.Authorization.getTokenByID(user.id);
if (token == -1) {
@@ -51,7 +60,7 @@ export class LoginController extends ControllerHandler {
}
response.Token = token.token;
await response.endpoint();
response.endpoint();
next();
}
}

View File

@@ -8,15 +8,15 @@ export class AuthMiddleWare extends MiddleWare {
const errors = new API.errors(res);
if (!req.headers.authorization) {
errors.addError(403, 'Forbidden', 'You cannot access this resource without authorization');
return next(errors);
errors.addError(403, 'Forbidden', 'You cannot access this resource without authorization').endpoint();
return;
}
const token = req.headers.authorization;
const user = await Auth.getUserFromToken(token);
if (user == -1 || !user.id) {
errors.addError(403, 'Forbidden', 'You cannot access this resource without authorization');
return next(errors);
if (user == -1) {
errors.addError(403, 'Forbidden', 'You cannot access this resource without authorization').endpoint();
return;
}
req.user = user;

View File

@@ -1,8 +1,6 @@
import {Logger} from '../../../models/logger';
export class ErrorHandler {
static async newError(err, req, res, next) {
// Logger.error(JSON.stringify(err));
err.endpoint();
}
}

View File

@@ -3,10 +3,10 @@ import stringify from 'json-stringify-safe';
import {Logger} from '../../models/logger';
export class MiddleWare {
// static async end(req, res, next) {
// await MiddleWare.RateLimits.request(req, res, next);
// await MiddleWare.analytics(req, res, next);
// }
static async end(req, res, next) {
await MiddleWare.RateLimits.request(req, res, next);
await MiddleWare.analytics(req, res, next);
}
static analytics(req, res, next) {
// TODO: Send data such as IP to an anyaltitics model

View File

@@ -11,9 +11,8 @@ export class RateLimits extends MiddleWare {
MiddleWare.analytics(req, res, next);
if (!buckets[ip]) {
Logger.debug(`New rate limiting bucket for ${ip}`);
Logger.debug(`New rate limiting bucket`);
RateLimits.newBucket(ip);
next();
return;
}
@@ -26,7 +25,6 @@ export class RateLimits extends MiddleWare {
}
buckets[ip].tokens.pop();
next();
}
static newBucket(ip) {

View File

@@ -1,40 +1,53 @@
import {ControllerHandler} from './controllerHandler';
import {API} from './api/api';
import {Notes} from '../models/notes/notes';
import {Logger} from '../models/logger'
export class NoteController extends ControllerHandler {
static async newNote(req, res, next) {
const errors = new API.errors(res);
const content = req.body.content || null;
const content = req.body.text || null;
const creatorid = req.user.id || undefined;
const group = req.body.parentgroup || undefined;
let order = req.body.order || undefined;
const user = req.user || undefined;
if (!creatorid || !user) {
errors.addError(403, 'Forbidden');
errors.endpoint();
next();
return;
}
if (!order) {
errors.addError(422, 'Unprocessable entity', 'Unprocessable entity, no order provided');
return next(errors);
errors.addError(422, 'Unprocessable entity');
errors.endpoint();
next();
return;
}
const id = await Notes.genID();
let success;
if (!group) {
success = await Notes.newNote(id, content, req.user, order);
success = await Notes.newNote(id, content, creatorid, order);
} else {
const doesExist = await Notes.doesGroupExist(user.id, parentgroup);
if (!doesExist) {
errors.addError(422, 'Unprocessable entity', 'You are trying to create a note for a group that does not exist');
return next(errors);
errors.endpoint();
next();
return;
}
success = await Notes.newGroupedNote(id, content, req.user, order, parentgroup);
success = await Notes.newGroupedNote(id, content, creatorid, order, parentgroup);
}
if (success == -1) {
errors.addError(500, 'Internal server error');
return next(errors);
errors.endpoint();
next();
return;
}
new API.note(res, user, id, content, order, parentgroup).endpoint();
@@ -45,10 +58,10 @@ export class NoteController extends ControllerHandler {
// id: id,
// content: content,
// parentgroup: parentgroup,
// req.user: req.user,
// creatorid: creatorid,
// order: order,
// catergory: null,
// endpoint: null,
// lastupdated: new Date().getTime()
// static async newNote(id, content, req.user, order, parentgroup) {
// static async newNote(id, content, creatorid, order, parentgroup) {

View File

@@ -11,7 +11,8 @@ export class PermaNoteController extends ControllerHandler {
const content = req.body.content || undefined;
if (!content) {
errors.addError(422, 'Unprocessable entity', 'There is no content');
return next(errors);
errors.endpoint();
return;
}
const uid = await PermaLink.genUID() || new Date().getTime();
@@ -20,7 +21,8 @@ export class PermaNoteController extends ControllerHandler {
const success = await Database.PermaNotes.newNote(uid, endpoint, content);
if (success == -1) {
errors.addError(500, 'Internal server error');
return next(errors);
errors.endpoint();
return;
}
new API.permalink(res, content, uid, endpoint).endpoint();
@@ -30,7 +32,9 @@ export class PermaNoteController extends ControllerHandler {
static async getPermaNote(req, res, next) {
const endpoint = req.params.endpoint || undefined;
if (!endpoint) return;
if (!endpoint) {
return;
}
const data = await Database.PermaNotes.getNoteByEndpoint(endpoint);
if (data == -1) {

View File

@@ -17,35 +17,31 @@ export class Router {
app.post('/user', [MiddleWare.RateLimits.request, Controllers.UserController.newUser]);
app.post('/login', [MiddleWare.RateLimits.request, Controllers.LoginController.authenticate]);
app.get('/user/:id', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.get('/auth/user/:id', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.delete('/auth/user/:id', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.post('/unauth/permanote', [MiddleWare.RateLimits.request, Controllers.PermaNoteController.newPermaNote]);
app.get('/note/:endpoint', [MiddleWare.RateLimits.request, Controllers.PermaNoteController.getPermaNote]);
app.post('/auth/note', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser, Controllers.NoteController.newNote]); // Passes through auth middleware which if authenticated passes user obj and token to the note handling function for it to deal with
app.post('/auth/group', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser, Controllers.GroupController.newGroup]);
app.get('/auth/getallnotes', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.get('/auth/getallgroups', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.post('/auth/movenote', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.post('/auth/movegroup', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.delete('/auth/deletenote', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.delete('/auth/deletegroup', [MiddleWare.RateLimits.request, MiddleWare.Auth.authUser]);
app.use(ErrorHandler.newError);
app.get('*', [MiddleWare.RateLimits.request, StatusCodes.pageNotFound]);
app.post('*', [MiddleWare.RateLimits.request, StatusCodes.pageNotFound]);
app.delete('*', [MiddleWare.RateLimits.request, StatusCodes.pageNotFound]);
app.use(ErrorHandler.newError);
Logger.info('HTTP endpoints settup');
}
static async frontPage(req, res, next) {
// const err = "lol";
// next(err);
static frontPage(req, res, next) {
res.end('DEVELOPMENT SERVER');
}
}

View File

@@ -1,6 +1,5 @@
export class StatusCodes {
static pageNotFound(req, res, next) {
res.status(404).send('404 Page not found');
next();
static pageNotFound(req, res) {
res.status(404).end('404 Page not found');
}
}

View File

@@ -27,7 +27,11 @@ export class UserController extends ControllerHandler {
if (await Database.Users.getUser('username', username) != -1) errors.addError(422, 'Unprocessable entity', 'A user with that username allready exists');
if (await Database.Users.getUser('email', email) != -1) errors.addError(422, 'Unprocessable entity', 'A user with that email allready exists');
if (errors.count() > 0) return next(errors);
if (errors.count() > 0) {
errors.endpoint();
next();
return;
}
const response = new API.user(res, id, username, email, new Date().toLocaleString());
@@ -45,7 +49,9 @@ export class UserController extends ControllerHandler {
const success = await user.insert();
if (success == -1) {
errors.addError(500, 'Internal server error');
return next(errors);
errors.endpoint();
next();
return;
}
response.endpoint();

View File

@@ -2,8 +2,8 @@ import {Database} from '../database/database';
export class Auth {
static async getUserFromToken(token) {
const id = await Database.Authorization.getIDByToken(token);
const id = await Database.auth.getIDByToken(token);
if (id == -1) return id;
return await Database.Users.getUserByID(id);
return await Database.users.getUserByID(id.id);
}
}