Merge pull request #30 from christroutner/unstable

Adding Winston Logging
This commit is contained in:
Chris Troutner
2019-05-20 21:11:10 -07:00
committed by GitHub
8 changed files with 1425 additions and 1272 deletions
+3
View File
@@ -22,6 +22,9 @@ It makes the following modifications:
of private vs public APIs that only be accessed by an admin. Useful for privileged
commands like updating and deleting other users.
- Winston logging integrated for daily rotated logs and a maximum size of
1 megabyte.
## Features
This project covers basic necessities of most APIs.
* Authentication (passport & jwt)
+2
View File
@@ -14,6 +14,7 @@ const cors = require('kcors')
const config = require('../config') // this first.
const adminLib = require('../src/lib/admin')
const errorMiddleware = require('../src/middleware')
const wlogger = require('../src/lib/wlogger')
async function startServer () {
// Create a Koa instance.
@@ -51,6 +52,7 @@ async function startServer () {
// MIDDLEWARE END
console.log(`Running server in environment: ${config.env}`)
wlogger.info(`Running server in environment: ${config.env}`)
await app.listen(config.port)
console.log(`Server started on ${config.port}`)
+1
View File
@@ -0,0 +1 @@
This directory will hold the Winston daily logs. Any files saved to this directory will be ignored by Git.
+1328 -1261
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -10,7 +10,7 @@
"docs": "./node_modules/.bin/apidoc -i src/ -o docs",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"coverage:report": "nyc --reporter=html mocha --exit",
"prep-test":"node util/users/delete-all-test-users.js"
"prep-test": "node util/users/delete-all-test-users.js"
},
"keywords": [
"koa-api-boilerplate",
@@ -48,7 +48,9 @@
"mongoose": "^5.5.4",
"passport-local": "^1.0.0",
"request": "^2.85.0",
"request-promise": "^4.2.2"
"request-promise": "^4.2.2",
"winston": "^3.2.1",
"winston-daily-rotate-file": "^3.9.0"
},
"devDependencies": {
"chai": "^4.1.2",
+56
View File
@@ -0,0 +1,56 @@
/*
Instantiates and configures the Winston logging library. This utitlity library
can be called by other parts of the application to conveniently tap into the
logging library.
*/
'use strict'
const winston = require('winston')
require('winston-daily-rotate-file')
const config = require('../../config')
// Configure daily-rotation transport.
var transport = new winston.transports.DailyRotateFile({
filename: `${__dirname}/../../logs/koa-${config.env}-%DATE%.log`,
datePattern: 'YYYY-MM-DD',
zippedArchive: false,
maxSize: '1m', // 1 megabyte
maxFiles: '5d', // 5 days
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
)
})
transport.on('rotate', function (oldFilename, newFilename) {
wlogger.info('Rotating log files')
})
// This controls what goes into the log FILES
var wlogger = winston.createLogger({
level: 'verbose',
format: winston.format.json(),
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
// - Write all logs error (and below) to `error.log`.
//
// new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
// new winston.transports.File({ filename: 'logs/combined.log' })
transport
]
})
// This controls the logs to CONSOLE
/*
wlogger.add(
new winston.transports.Console({
format: winston.format.simple(),
level: "info"
})
)
*/
module.exports = wlogger
+4 -6
View File
@@ -2,6 +2,7 @@ const User = require('../models/users')
const config = require('../../config')
const getToken = require('../lib/auth')
const jwt = require('jsonwebtoken')
const wlogger = require('../lib/wlogger')
async function ensureUser (ctx, next) {
// console.log(`getToken: ${typeof (getToken)}`)
@@ -102,17 +103,14 @@ async function ensureTargetUserOrAdmin (ctx, next) {
// console.log(`ctx.state.user: ${JSON.stringify(ctx.state.user, null, 2)}`)
// Ensure the calling user and the target user are the same.
if (ctx.state.user._id.toString() !== targetId.toString()) {
// console.log(`Calling user and target user do not match!`)
// console.log(`Calling user: ${ctx.state.user._id}`)
// console.log(`Target user: ${targetId}`)
wlogger.verbose(`Calling user and target user do not match! Calling user: ${ctx.state.user._id}, Target user: ${targetId}`)
// If they don't match, then the calling user better be an admin.
if (ctx.state.user.type !== 'admin') {
ctx.throw(401, 'not admin')
} else {
wlogger.verbose(`It's ok. The user is an admin.`)
}
// else {
// console.log(`It's ok. The user is an admin.`)
// }
}
return next()
+27 -3
View File
@@ -2,7 +2,6 @@ const testUtils = require('./utils')
const rp = require('request-promise')
const assert = require('chai').assert
const config = require('../config')
const adminLib = require('../src/lib/admin')
const util = require('util')
util.inspect.defaultOptions = { depth: 1 }
@@ -393,7 +392,7 @@ describe('Users', () => {
}
})
it('should not be able to update other user', async () => {
it('should not be able to update other user when not admin', async () => {
try {
const options = {
method: 'PUT',
@@ -424,6 +423,31 @@ describe('Users', () => {
}
}
})
it('should be able to update other user when admin', async () => {
const adminJWT = context.adminJWT
const options = {
method: 'PUT',
uri: `${LOCALHOST}/users/${context.user2._id.toString()}`,
resolveWithFullResponse: true,
json: true,
headers: {
Authorization: `Bearer ${adminJWT}`
},
body: {
user: {
name: 'This should work'
}
}
}
let result = await rp(options)
// console.log(`result stringified: ${JSON.stringify(result, null, 2)}`)
const userName = result.body.user.name
assert.equal(userName, 'This should work')
})
})
describe('DELETE /users/:id', () => {
@@ -519,7 +543,7 @@ describe('Users', () => {
assert.equal(result.body.success, true)
})
it('should delete other account when admin', async () => {
it('should be able to delete other users when admin', async () => {
const id = context.id2
const adminJWT = context.adminJWT