Compare commits
2 Commits
dev
...
add-licens
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3463bd2d4b | ||
|
|
47193bf86e |
21
LICENSE
Normal file
21
LICENSE
Normal 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.
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user