This commit is contained in:
23
.drone.yml
Normal file
23
.drone.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
workspace:
|
||||
path: /drone/src
|
||||
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: node:latest
|
||||
commands:
|
||||
- npm install -g yarn
|
||||
- yarn install
|
||||
- yarn test
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"watch": ["src"],
|
||||
"exec": "yarn run serve",
|
||||
"ext": "ts"
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "@mifi/grow-api",
|
||||
"name": "@mifi/auth",
|
||||
"version": "0.0.1",
|
||||
"main": "server.js",
|
||||
"author": "mifi (Mike Fitzpatrick)",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@@ -13,6 +12,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/http-status-codes": "^1.2.0",
|
||||
@@ -44,7 +44,8 @@
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mifi/grow-db": "0.0.1",
|
||||
"@simplewebauthn/server": "^7.2.0",
|
||||
"bcrypt": "^5.1.0",
|
||||
"crypto": "^1.0.1",
|
||||
"dotenv": "^16.0.3",
|
||||
"http-status-codes": "^2.2.0",
|
||||
@@ -67,6 +68,6 @@
|
||||
"description": "",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.mifi.dev/mifi/grow-api.git"
|
||||
"url": "https://git.mifi.dev/mifi/auth.git"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import Koa from 'koa';
|
||||
import bodyParser from 'koa-bodyparser';
|
||||
import cookie from 'koa-cookie';
|
||||
import passport from 'koa-passport';
|
||||
import session from 'koa-session';
|
||||
|
||||
import { performanceLogger, perfromanceTimer } from '../middleware/performance';
|
||||
import { errorHandler } from '../middleware/errorHandler';
|
||||
|
||||
const app: Koa = new Koa();
|
||||
|
||||
app.use(errorHandler);
|
||||
app.use(perfromanceTimer);
|
||||
app.use(performanceLogger);
|
||||
app.use(bodyParser());
|
||||
app.use(cookie());
|
||||
|
||||
app.keys = [process.env.SESSION_KEYS as string];
|
||||
app.use(session({}, app));
|
||||
|
||||
app.use(passport.initialize())
|
||||
app.use(passport.session())
|
||||
|
||||
// Application error logging.
|
||||
app.on('error', console.error);
|
||||
|
||||
export default app;
|
||||
16
src/auth.ts
16
src/auth.ts
@@ -1,16 +0,0 @@
|
||||
import passport from 'koa-passport';
|
||||
|
||||
import Users from 'grow-db/lib/models/users';
|
||||
import { User } from 'grow-db/lib/schemas/user';
|
||||
|
||||
passport.serializeUser((user: User, done) => { done(null, user._id); });
|
||||
|
||||
passport.deserializeUser(async (id, done) => {
|
||||
const user = await Users.findById(id);
|
||||
|
||||
if (user) {
|
||||
done(null, user);
|
||||
}
|
||||
|
||||
done('user not found', null);
|
||||
});
|
||||
@@ -1,231 +0,0 @@
|
||||
// const errors = require('restify-errors');
|
||||
|
||||
// const config = require('../config');
|
||||
|
||||
// const handlePassportResponse = (req, res, next) => (err, user, info) => {
|
||||
// if (err) {
|
||||
// return next(err);
|
||||
// }
|
||||
|
||||
// const isVerifiedUser = user &&
|
||||
// user.isRegistrationVerified();
|
||||
|
||||
// if (user && isVerifiedUser) {
|
||||
// return res.send({ ...user.toAuthJSON() });
|
||||
// } else if (user && !isVerifiedUser){
|
||||
// return res.send({
|
||||
// registrationSuccess: true,
|
||||
// nextSteps: 'Check your email for our confirmation email, you will not be able to login without confirming.'
|
||||
// });
|
||||
// }
|
||||
|
||||
// return res.send(400, info);
|
||||
// };
|
||||
|
||||
// module.exports = function (server, auth) {
|
||||
// const { passport } = auth;
|
||||
|
||||
// /* Local Auth */
|
||||
// server.post('/auth', (req, res, next) => {
|
||||
// const { body: { username = null, password = null } = {} } = req;
|
||||
|
||||
// if (!username || !password) {
|
||||
// let errors = {};
|
||||
|
||||
// if (!username) {
|
||||
// errors.username = 'is required';
|
||||
// }
|
||||
|
||||
// if (!password) {
|
||||
// errors.password = 'is required';
|
||||
// }
|
||||
|
||||
// return res.send(422, { errors });
|
||||
// }
|
||||
|
||||
// const callback = handlePassportResponse(req, res, next);
|
||||
// return passport.authenticate('local', { session: false }.then(callback)(req, res, next);
|
||||
// });
|
||||
|
||||
// /**
|
||||
// * SERVICES
|
||||
// */
|
||||
|
||||
// /* Google */
|
||||
// server.get(
|
||||
// '/auth/google',
|
||||
// passport.authenticate('google', { scope: 'profile email', session: false }),
|
||||
// );
|
||||
|
||||
// server.get(
|
||||
// '/auth/google/callback',
|
||||
// (req, res, next) => {
|
||||
// const callback = handlePassportResponse(req, res, next);
|
||||
// return passport.authenticate(
|
||||
// 'google',
|
||||
// { failureRedirect: '/login' },
|
||||
// callback,
|
||||
// )(req, res, next);
|
||||
// },
|
||||
// );
|
||||
|
||||
// /* Facebook */
|
||||
// server.get(
|
||||
// '/auth/facebook/login',
|
||||
// passport.authenticate('facebook', {
|
||||
// scope: ['email', 'public_profile'],
|
||||
// session: false,
|
||||
// }),
|
||||
// );
|
||||
|
||||
// server.get(
|
||||
// '/auth/facebook/loggedin',
|
||||
// (req, res, next) => {
|
||||
// const callback = handlePassportResponse(req, res, next);
|
||||
// return passport.authenticate(
|
||||
// 'facebook',
|
||||
// { failureRedirect: '/login' },
|
||||
// callback,
|
||||
// )(req, res, next);
|
||||
// }
|
||||
// );
|
||||
|
||||
// server.get(
|
||||
// '/auth/facebook/link',
|
||||
// auth.secure,
|
||||
// (req, res, next) => {
|
||||
// req.user.record.setLinkCheckBit((err, linkCheckBit) => {
|
||||
// passport.authenticate('facebookLink', {
|
||||
// scope: ['email', 'public_profile'],
|
||||
// session: false,
|
||||
// state: linkCheckbit,
|
||||
// })(req, res, next);
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
//
|
||||
// server.get(
|
||||
// '/auth/facebook/linked',
|
||||
// (req, res, next) => {
|
||||
// const linkCheckBit = req.query.state;
|
||||
//
|
||||
// return passport.authenticate(
|
||||
// 'facebook',
|
||||
// { failureRedirect: '/profile' },
|
||||
// (err, profile) => {
|
||||
// if (err) {
|
||||
// return next(err);
|
||||
// }
|
||||
//
|
||||
// User.linkFacebookProfile(linkCheckBit, profile, (err, user) => {
|
||||
// if (err) {
|
||||
// return next(err);
|
||||
// }
|
||||
//
|
||||
// if (!user) {
|
||||
// return next(err, false, 'Linking the account to Facebook was unsuccessful, please try again.');
|
||||
// }
|
||||
//
|
||||
// res.send({
|
||||
// success: true,
|
||||
// info: 'Facerbook account successfully linked',
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
// )(req, res, next);
|
||||
// }
|
||||
// );
|
||||
};
|
||||
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
|
||||
import Users from 'grow-db/lib/models/users';
|
||||
|
||||
const handlePassportResponse = (ctx: Koa.Context) => (err, user, info) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
const isVerifiedUser = user &&
|
||||
user.isRegistrationVerified();
|
||||
|
||||
if (user && isVerifiedUser) {
|
||||
return res.send({ ...user.toAuthJSON() });
|
||||
} else if (user && !isVerifiedUser){
|
||||
return res.send({
|
||||
registrationSuccess: true,
|
||||
nextSteps: 'Check your email for our confirmation email, you will not be able to login without confirming.'
|
||||
});
|
||||
}
|
||||
|
||||
return res.send(400, info);
|
||||
};
|
||||
|
||||
const routerOpts: Router.IRouterOptions = {
|
||||
prefix: '/auth',
|
||||
};
|
||||
|
||||
const router: Router = new Router(routerOpts);
|
||||
|
||||
router.get('/', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.find({}).exec();
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
|
||||
router.get('/:customer_id', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.findById(ctx.params.customer_id).populate('person').exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.delete('/:customer_id', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.findByIdAndDelete(ctx.params.customer_id).exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
|
||||
router.post('/', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.create(ctx.body);
|
||||
data.save();
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
|
||||
router.post('/', async (ctx: Koa.Context) => {
|
||||
const { body: { username = null, password = null } = {} } = ctx;
|
||||
|
||||
if (!username || !password) {
|
||||
let errors = {};
|
||||
|
||||
if (!username) {
|
||||
errors.username = 'is required';
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
errors.password = 'is required';
|
||||
}
|
||||
|
||||
ctx.status = StatusCodes.UNPROCESSABLE_ENTITY;
|
||||
ctx.throw(422, { errors });
|
||||
}
|
||||
|
||||
const callback = handlePassportResponse(req, res, next);
|
||||
return passport.authenticate('local', { session: false }, callback)(req, res, next);
|
||||
});
|
||||
|
||||
|
||||
router.patch('/:customer_id', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.findByIdAndUpdate(ctx.params.customer_id);
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
|
||||
import Customers from 'grow-db/lib/models/customers';
|
||||
|
||||
const routerOpts: Router.IRouterOptions = {
|
||||
prefix: '/customers',
|
||||
};
|
||||
|
||||
const router: Router = new Router(routerOpts);
|
||||
|
||||
router.get('/', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.find({}).exec();
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.get('/:customer_id', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.findById(ctx.params.customer_id).populate('person').exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.delete('/:customer_id', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.findByIdAndDelete(ctx.params.customer_id).exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
|
||||
router.post('/', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.create(ctx.body);
|
||||
data.save();
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
router.patch('/:customer_id', async (ctx: Koa.Context) => {
|
||||
const data = await Customers.findByIdAndUpdate(ctx.params.customer_id);
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
|
||||
import Users from 'grow-db/lib/models/users';
|
||||
|
||||
const routerOpts: Router.IRouterOptions = {
|
||||
prefix: '/login',
|
||||
};
|
||||
|
||||
const router: Router = new Router(routerOpts);
|
||||
|
||||
router.post('/', async (ctx: Koa.Context) => {
|
||||
const data = await Users.create(ctx.body);
|
||||
data.save();
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
|
||||
import People from 'grow-db/lib/models/people';
|
||||
|
||||
const routerOpts: Router.IRouterOptions = {
|
||||
prefix: '/people',
|
||||
};
|
||||
|
||||
const router: Router = new Router(routerOpts);
|
||||
|
||||
router.get('/', async (ctx: Koa.Context) => {
|
||||
const data = await People.find({}).exec();
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.get('/:person_id', async (ctx: Koa.Context) => {
|
||||
const data = await People.findById(ctx.params.person_id).populate('person').exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.delete('/:person_id', async (ctx: Koa.Context) => {
|
||||
const data = await People.findByIdAndDelete(ctx.params.person_id).exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
router.post('/', async (ctx: Koa.Context) => {
|
||||
const data = await People.create(ctx.body);
|
||||
data.save();
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
router.patch('/:person_id', async (ctx: Koa.Context) => {
|
||||
const data = await People.findByIdAndUpdate(ctx.params.person_id);
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
@@ -1,68 +0,0 @@
|
||||
const errors = require('restify-errors');
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
const config = require('../config');
|
||||
const User = require('../models/user');
|
||||
|
||||
const {
|
||||
api: { url },
|
||||
security: { reset: { route, tokenPlaceholder } },
|
||||
} = config;
|
||||
|
||||
const routes = {
|
||||
resetWithToken: `${route}/${tokenPlaceholder}([A-Za-z0-9_]+\.{3})`,
|
||||
getTestToken: `${route}/generate`,
|
||||
};
|
||||
|
||||
module.exports = function (server, auth) {
|
||||
server.get(routes.getTestToken, auth.secure, function (req, res, next) {
|
||||
const { record: user } = req.user;
|
||||
const resetToken = user.generateResetToken();
|
||||
const resetUrl = `${url}${route}/${resetToken}`;
|
||||
|
||||
res.send({ resetToken, resetUrl });
|
||||
next();
|
||||
});
|
||||
|
||||
server.post(routes.resetWithToken, auth.bypass, function (req, res, next) {
|
||||
const { reset_token } = req.params;
|
||||
const { password } = req.body;
|
||||
|
||||
if (!reset_token) {
|
||||
return next(
|
||||
new errors.InvalidContentError('A reset token was not provided.'),
|
||||
);
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
return next(
|
||||
new errors.InvalidContentError('Password cannot be empty.'),
|
||||
);
|
||||
}
|
||||
|
||||
User.verifyTokenAndResetPassword(reset_token, password, (err, user, info) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return next(
|
||||
new errors.InvalidContentError(err),
|
||||
);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
console.error(err);
|
||||
res.send({
|
||||
success: false,
|
||||
info: 'Password reset failed. ' + info,
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
res.send({
|
||||
success: true,
|
||||
info: 'Password reset successful.',
|
||||
...user.toAuthJSON()
|
||||
});
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,106 +0,0 @@
|
||||
const errors = require('restify-errors');
|
||||
|
||||
const User = require('../models/user');
|
||||
|
||||
module.exports = function (server, auth) {
|
||||
const { passport } = auth;
|
||||
|
||||
server.post('/signup', auth.basic, (req, res, next) => {
|
||||
const { body: { user = null } = {} } = req;
|
||||
|
||||
let errors = {};
|
||||
let errorCount = 0;
|
||||
if (!user) {
|
||||
errors.user = 'is required - can\'t make something from nothing...';
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
if (errorCount) {
|
||||
return res.send(422, { errors });
|
||||
}
|
||||
|
||||
User.register(user, (err, user, info) => {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
|
||||
if (info) {
|
||||
res.send(200, {
|
||||
success: false,
|
||||
nextSteps: 'Please fix the problems indicated and try again.',
|
||||
...info
|
||||
});
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
res.send(200, {
|
||||
success: true,
|
||||
nextSteps: 'Check your email for our confirmation email, you will not be able to login without confirming.',
|
||||
});
|
||||
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/signup/validate/email/:email', auth.basic, (req, res, next) => {
|
||||
const email = decodeURI(req.params.email);
|
||||
|
||||
User.findOne({ email }, (err, user) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
res.send(200, { available: !!!user });
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/signup/validate/nom/:nom_de_bid', auth.basic, (req, res, next) => {
|
||||
const nomDeBid = decodeURI(req.params.nom_de_bid);
|
||||
|
||||
User.findOne({ nomDeBid }, (err, user) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
res.send(200, { available: !!!user });
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
server.post('/signup/verify/resend', auth.basic, (req, res, next) => {
|
||||
const { body: { email = null } = {} } = req;
|
||||
|
||||
User.resendVerificationEmail(email, (err, user, info) => {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
res.send(200, {
|
||||
success: false,
|
||||
nextSteps: 'There was no user located with the email address provided. Please try again.',
|
||||
});
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
if (user && info.success) {
|
||||
res.send(200, {
|
||||
success: true,
|
||||
nextSteps: 'Check your email for our confirmation email, you will not be able to login without confirming.',
|
||||
});
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
res.send(200, {
|
||||
success: false,
|
||||
nextSteps: 'There was a problem resending the verification email. Please try again later.',
|
||||
});
|
||||
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
import { Context } from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import { } from 'koa-bodyparser';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
|
||||
import Strains from 'grow-db/lib/models/strains';
|
||||
import { Strain } from 'grow-db/lib/schemas/strain';
|
||||
|
||||
const routerOpts: Router.IRouterOptions = {
|
||||
prefix: '/strains',
|
||||
};
|
||||
|
||||
const router: Router = new Router(routerOpts);
|
||||
|
||||
router.get('/', async (ctx: Context) => {
|
||||
const data = await Strains.find({}).exec();
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.get('/:strain_id', async (ctx) => {
|
||||
const data = await Strains.findById(ctx.params.strain_id).populate('person').exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { data };
|
||||
});
|
||||
|
||||
router.delete('/:strain_id', async (ctx: Context) => {
|
||||
const data = await Strains.findByIdAndDelete(ctx.params.strain_id).exec();
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
|
||||
router.post('/', async (ctx: Context) => {
|
||||
const data = await Strains.create(ctx.request.body);
|
||||
data.save();
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
|
||||
router.patch('/:strain_id', async (ctx) => {
|
||||
const data = await Strains.findByIdAndUpdate(ctx.params.strain_id, <Strain>ctx.request.body, { lean: true, returnDocument: 'after' });
|
||||
if (!data) {
|
||||
ctx.throw(StatusCodes.NOT_FOUND);
|
||||
}
|
||||
ctx.body = { success: true, data };
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
export const connection = mongoose.connect(
|
||||
`${process.env.DB_USER}:${process.env.DB_PASSWORD}@mongodb:27017/${process.env.DB_NAME}`
|
||||
);
|
||||
@@ -1,13 +0,0 @@
|
||||
import { StatusCodes } from "http-status-codes";
|
||||
import { Context, Next } from "koa";
|
||||
|
||||
export const errorHandler = async (ctx: Context, next: Next) => {
|
||||
try {
|
||||
await next();
|
||||
} catch (error: any) {
|
||||
ctx.status = error.statusCode || error.status || StatusCodes.INTERNAL_SERVER_ERROR;
|
||||
error.status = ctx.status;
|
||||
ctx.body = { error };
|
||||
ctx.app.emit('error', error, ctx);
|
||||
}
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Next } from 'koa';
|
||||
import { KoaContext } from '../types/KoaContext';
|
||||
|
||||
export const performanceLogger = async (ctx: KoaContext, next: Next) => {
|
||||
await next();
|
||||
const rt = ctx.response.get('X-Response-Time');
|
||||
console.log(`${ctx.method} ${ctx.url} - ${rt}`);
|
||||
};
|
||||
|
||||
export const perfromanceTimer = async (ctx: KoaContext, next: Next) => {
|
||||
const start = Date.now();
|
||||
await next();
|
||||
const ms = Date.now() - start;
|
||||
ctx.set('X-Response-Time', `${ms}ms`);
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
import app from './app/app';
|
||||
import { connection } from './database/database.connection';
|
||||
|
||||
const PORT: number = Number(process.env.PORT) || 9000;
|
||||
|
||||
connection.then(
|
||||
() => app.listen(PORT),
|
||||
(err) => console.error('ERROR!', err),
|
||||
);
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Context, Request } from 'koa';
|
||||
|
||||
interface KoaRequest<RequestBody = any> extends Request {
|
||||
body?: RequestBody;
|
||||
}
|
||||
|
||||
export interface KoaContext<RequestBody = any, ResponseBody = any> extends Context {
|
||||
request: KoaRequest<RequestBody>;
|
||||
body: ResponseBody;
|
||||
}
|
||||
|
||||
export interface KoaResponseContext<ResponseBody> extends KoaContext<any, ResponseBody> {};
|
||||
Reference in New Issue
Block a user