mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-service.git
synced 2026-09-21 16:52:03 -07:00
+2
-2
@@ -27,8 +27,8 @@ require('../config/passport')
|
||||
app.use(passport.initialize())
|
||||
app.use(passport.session())
|
||||
|
||||
const router = require('../src/controllers')
|
||||
router(app)
|
||||
const modules = require('../src/modules')
|
||||
modules(app)
|
||||
|
||||
app.listen(config.port, () => {
|
||||
console.log(`Server started on ${config.port}`)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import glob from 'glob'
|
||||
|
||||
exports = module.exports = function Controllers(app) {
|
||||
glob(`${__dirname}/*.js`, { ignore: '**/index.js' }, (err, matches) => {
|
||||
if (err) { throw err }
|
||||
|
||||
matches.forEach((file) => {
|
||||
const controller = require(file).default
|
||||
app
|
||||
.use(controller.routes())
|
||||
.use(controller.allowedMethods())
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import mongoose from 'mongoose'
|
||||
import bcrypt from 'bcrypt'
|
||||
import config from '../../config'
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
const User = new mongoose.Schema({
|
||||
type: { type: String, default: 'User' },
|
||||
@@ -47,4 +49,10 @@ User.methods.validatePassword = function validatePassword(password) {
|
||||
})
|
||||
}
|
||||
|
||||
User.methods.generateToken = function generateToken() {
|
||||
const user = this
|
||||
|
||||
return jwt.sign({ id: user.id }, config.token)
|
||||
}
|
||||
|
||||
export default mongoose.model('user', User)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import Router from 'koa-router'
|
||||
import passport from 'koa-passport'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import config from '../../config'
|
||||
|
||||
const router = new Router({ prefix: '/auth' })
|
||||
import config from '../../../config'
|
||||
|
||||
/**
|
||||
* @apiDefine TokenError
|
||||
@@ -55,8 +52,9 @@ const router = new Router({ prefix: '/auth' })
|
||||
* "error": "Unauthorized"
|
||||
* }
|
||||
*/
|
||||
router.post('/', async (ctx, next) =>
|
||||
passport.authenticate('local', (user) => {
|
||||
|
||||
export async function authUser(ctx, next) {
|
||||
return passport.authenticate('local', (user) => {
|
||||
if (!user) {
|
||||
ctx.throw(401)
|
||||
}
|
||||
@@ -73,6 +71,4 @@ router.post('/', async (ctx, next) =>
|
||||
user: response
|
||||
}
|
||||
})(ctx, next)
|
||||
)
|
||||
|
||||
export default router
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import * as auth from './controller'
|
||||
|
||||
export const baseUrl = '/auth'
|
||||
|
||||
export default [
|
||||
{
|
||||
method: 'POST',
|
||||
route: '/',
|
||||
handlers: [
|
||||
auth.authUser
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
import glob from 'glob'
|
||||
import Router from 'koa-router'
|
||||
|
||||
exports = module.exports = function initModules(app) {
|
||||
glob(`${__dirname}/*`, { ignore: '**/index.js' }, (err, matches) => {
|
||||
if (err) { throw err }
|
||||
|
||||
matches.forEach((mod) => {
|
||||
const router = require(`${mod}/router`)
|
||||
|
||||
const routes = router.default
|
||||
const baseUrl = router.baseUrl
|
||||
const instance = new Router({ prefix: baseUrl })
|
||||
|
||||
routes.forEach((config) => {
|
||||
const {
|
||||
method = '',
|
||||
route = '',
|
||||
handlers = []
|
||||
} = config
|
||||
|
||||
instance[method.toLowerCase()](route, ...handlers)
|
||||
|
||||
app
|
||||
.use(instance.routes())
|
||||
.use(instance.allowedMethods())
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,92 +1,4 @@
|
||||
import Router from 'koa-router'
|
||||
import User from '../models/users'
|
||||
import config from '../../config'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { ensureUser } from '../middleware/validators'
|
||||
|
||||
const router = new Router({ prefix: '/users' })
|
||||
|
||||
/**
|
||||
* @api {get} /users Get all users
|
||||
* @apiPermission user
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName GetUsers
|
||||
* @apiGroup Users
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* curl -H "Content-Type: application/json" -X GET localhost:5000/users
|
||||
*
|
||||
* @apiSuccess {Object[]} users Array of user objects
|
||||
* @apiSuccess {ObjectId} users._id User id
|
||||
* @apiSuccess {String} users.name User name
|
||||
* @apiSuccess {String} users.username User username
|
||||
*
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "users": [{
|
||||
* "_id": "56bd1da600a526986cf65c80"
|
||||
* "name": "John Doe"
|
||||
* "username": "johndoe"
|
||||
* }]
|
||||
* }
|
||||
*
|
||||
* @apiUse TokenError
|
||||
*/
|
||||
router.get('/',
|
||||
ensureUser,
|
||||
async (ctx) => {
|
||||
const users = await User.find({}, '-password -salt')
|
||||
ctx.body = users
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* @api {get} /users/:id Get user by id
|
||||
* @apiPermission user
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName GetUser
|
||||
* @apiGroup Users
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* curl -H "Content-Type: application/json" -X GET localhost:5000/users/56bd1da600a526986cf65c80
|
||||
*
|
||||
* @apiSuccess {Object} users User object
|
||||
* @apiSuccess {ObjectId} users._id User id
|
||||
* @apiSuccess {String} users.name User name
|
||||
* @apiSuccess {String} users.username User username
|
||||
*
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "user": {
|
||||
* "_id": "56bd1da600a526986cf65c80"
|
||||
* "name": "John Doe"
|
||||
* "username": "johndoe"
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @apiUse TokenError
|
||||
*/
|
||||
router.get('/:id',
|
||||
ensureUser,
|
||||
async (ctx) => {
|
||||
try {
|
||||
const user = await User.findById(ctx.params.id, '-password -salt')
|
||||
if (!user) {
|
||||
ctx.throw(404)
|
||||
}
|
||||
|
||||
ctx.body = user
|
||||
} catch (err) {
|
||||
if (err === 404 || err.name === 'CastError') {
|
||||
ctx.throw(404)
|
||||
}
|
||||
|
||||
ctx.throw(500)
|
||||
}
|
||||
}
|
||||
)
|
||||
import User from '../../models/users'
|
||||
|
||||
/**
|
||||
* @api {post} /users Create a new user
|
||||
@@ -126,27 +38,105 @@ router.get('/:id',
|
||||
* "error": "Unprocessable Entity"
|
||||
* }
|
||||
*/
|
||||
router.post('/',
|
||||
async (ctx) => {
|
||||
const user = new User(ctx.request.body.user)
|
||||
try {
|
||||
await user.save()
|
||||
const token = jwt.sign({ id: user.id }, config.token)
|
||||
|
||||
const response = user.toJSON()
|
||||
|
||||
delete response.password
|
||||
delete response.salt
|
||||
|
||||
ctx.body = {
|
||||
user: response,
|
||||
token
|
||||
}
|
||||
} catch (err) {
|
||||
ctx.throw(422, err)
|
||||
}
|
||||
export async function createUser(ctx) {
|
||||
const user = new User(ctx.request.body.user)
|
||||
try {
|
||||
await user.save()
|
||||
} catch (err) {
|
||||
ctx.throw(422, err.message)
|
||||
}
|
||||
)
|
||||
|
||||
const token = user.generateToken()
|
||||
const response = user.toJSON()
|
||||
|
||||
delete response.password
|
||||
delete response.salt
|
||||
|
||||
ctx.body = {
|
||||
user: response,
|
||||
token
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} /users Get all users
|
||||
* @apiPermission user
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName GetUsers
|
||||
* @apiGroup Users
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* curl -H "Content-Type: application/json" -X GET localhost:5000/users
|
||||
*
|
||||
* @apiSuccess {Object[]} users Array of user objects
|
||||
* @apiSuccess {ObjectId} users._id User id
|
||||
* @apiSuccess {String} users.name User name
|
||||
* @apiSuccess {String} users.username User username
|
||||
*
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "users": [{
|
||||
* "_id": "56bd1da600a526986cf65c80"
|
||||
* "name": "John Doe"
|
||||
* "username": "johndoe"
|
||||
* }]
|
||||
* }
|
||||
*
|
||||
* @apiUse TokenError
|
||||
*/
|
||||
export async function getUsers(ctx) {
|
||||
const users = await User.find({}, '-password -salt')
|
||||
ctx.body = { users }
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} /users/:id Get user by id
|
||||
* @apiPermission user
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName GetUser
|
||||
* @apiGroup Users
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* curl -H "Content-Type: application/json" -X GET localhost:5000/users/56bd1da600a526986cf65c80
|
||||
*
|
||||
* @apiSuccess {Object} users User object
|
||||
* @apiSuccess {ObjectId} users._id User id
|
||||
* @apiSuccess {String} users.name User name
|
||||
* @apiSuccess {String} users.username User username
|
||||
*
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "user": {
|
||||
* "_id": "56bd1da600a526986cf65c80"
|
||||
* "name": "John Doe"
|
||||
* "username": "johndoe"
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @apiUse TokenError
|
||||
*/
|
||||
export async function getUser(ctx, next) {
|
||||
try {
|
||||
const user = await User.findById(ctx.params.id, '-password -salt')
|
||||
if (!user) {
|
||||
ctx.throw(404)
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
user
|
||||
}
|
||||
} catch (err) {
|
||||
if (err === 404 || err.name === 'CastError') {
|
||||
ctx.throw(404)
|
||||
}
|
||||
|
||||
ctx.throw(500)
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {put} /users/:id Update a user
|
||||
@@ -188,30 +178,17 @@ router.post('/',
|
||||
*
|
||||
* @apiUse TokenError
|
||||
*/
|
||||
router.put('/:id',
|
||||
ensureUser,
|
||||
async (ctx) => {
|
||||
try {
|
||||
const user = await User.findById(ctx.params.id, '-password -salt')
|
||||
if (!user) {
|
||||
ctx.throw(404)
|
||||
}
|
||||
export async function updateUser(ctx) {
|
||||
const user = ctx.body.user
|
||||
|
||||
Object.assign(user, ctx.request.body.user)
|
||||
Object.assign(user, ctx.request.body.user)
|
||||
|
||||
await user.save()
|
||||
ctx.body = {
|
||||
user
|
||||
}
|
||||
} catch (err) {
|
||||
if (err === 404 || err.name === 'CastError') {
|
||||
ctx.throw(404)
|
||||
}
|
||||
await user.save()
|
||||
|
||||
ctx.throw(500)
|
||||
}
|
||||
ctx.body = {
|
||||
user
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {delete} /users/:id Delete a user
|
||||
@@ -228,31 +205,19 @@ router.put('/:id',
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "status": 200
|
||||
* "success": true
|
||||
* }
|
||||
*
|
||||
* @apiUse TokenError
|
||||
*/
|
||||
router.delete('/:id',
|
||||
ensureUser,
|
||||
async (ctx) => {
|
||||
try {
|
||||
const user = await User.findById(ctx.params.id)
|
||||
if (!user) {
|
||||
ctx.throw(404)
|
||||
}
|
||||
|
||||
await user.remove()
|
||||
export async function deleteUser(ctx) {
|
||||
const user = ctx.body.user
|
||||
|
||||
ctx.body = 200
|
||||
} catch (err) {
|
||||
if (err === 404 || err.name === 'CastError') {
|
||||
ctx.throw(404)
|
||||
}
|
||||
await user.remove()
|
||||
|
||||
ctx.throw(500)
|
||||
}
|
||||
ctx.status = 200
|
||||
ctx.body = {
|
||||
success: true
|
||||
}
|
||||
)
|
||||
|
||||
export default router
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ensureUser } from '../../middleware/validators'
|
||||
import * as user from './controller'
|
||||
|
||||
export const baseUrl = '/users'
|
||||
|
||||
export default [
|
||||
{
|
||||
method: 'POST',
|
||||
route: '/',
|
||||
handlers: [
|
||||
user.createUser
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'GET',
|
||||
route: '/',
|
||||
handlers: [
|
||||
ensureUser,
|
||||
user.getUsers
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'GET',
|
||||
route: '/:id',
|
||||
handlers: [
|
||||
ensureUser,
|
||||
user.getUser
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'PUT',
|
||||
route: '/:id',
|
||||
handlers: [
|
||||
ensureUser,
|
||||
user.getUser,
|
||||
user.updateUser
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'DELETE',
|
||||
route: '/:id',
|
||||
handlers: [
|
||||
ensureUser,
|
||||
user.getUser,
|
||||
user.deleteUser
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,51 @@
|
||||
import app from '../bin/server'
|
||||
import supertest from 'supertest'
|
||||
import { expect, should } from 'chai'
|
||||
import { cleanDb, authUser } from './utils'
|
||||
|
||||
should()
|
||||
const request = supertest.agent(app.listen())
|
||||
const context = {}
|
||||
|
||||
describe('Auth', () => {
|
||||
before((done) => {
|
||||
cleanDb()
|
||||
authUser(request, (err, { user, token }) => {
|
||||
if (err) { return done(err) }
|
||||
|
||||
context.user = user
|
||||
context.token = token
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /auth', () => {
|
||||
it('should throw 401 if credentials are incorrect', (done) => {
|
||||
request
|
||||
.post('/auth')
|
||||
.set('Accept', 'application/json')
|
||||
.send({ username: 'supercoolname', password: 'wrongpassword' })
|
||||
.expect(401, done)
|
||||
})
|
||||
|
||||
it('should auth user', (done) => {
|
||||
request
|
||||
.post('/auth')
|
||||
.set('Accept', 'application/json')
|
||||
.send({ username: 'test', password: 'pass' })
|
||||
.expect(200, (err, res) => {
|
||||
if (err) { return done(err) }
|
||||
|
||||
res.body.user.should.have.property('username')
|
||||
res.body.user.username.should.equal('test')
|
||||
expect(res.body.user.password).to.not.exist
|
||||
expect(res.body.user.salt).to.not.exist
|
||||
|
||||
context.user = res.body.user
|
||||
context.token = res.body.token
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+19
-2
@@ -56,7 +56,15 @@ describe('Users', () => {
|
||||
request
|
||||
.get(`/users?token=${token}`)
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200, done)
|
||||
.expect(200, (err, res) => {
|
||||
if (err) { return done(err) }
|
||||
|
||||
res.body.should.have.property('users')
|
||||
|
||||
res.body.users.should.have.length(1)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -85,7 +93,16 @@ describe('Users', () => {
|
||||
request
|
||||
.get(`/users/${_id}?token=${token}`)
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200, done)
|
||||
.expect(200, (err, res) => {
|
||||
if (err) { return done(err) }
|
||||
|
||||
res.body.should.have.property('user')
|
||||
|
||||
expect(res.body.user.password).to.not.exist
|
||||
expect(res.body.user.salt).to.not.exist
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
+19
-2
@@ -1,7 +1,24 @@
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export function cleanDb () {
|
||||
export function cleanDb() {
|
||||
for (const collection in mongoose.connection.collections) {
|
||||
mongoose.connection.collections[collection].remove();
|
||||
if (mongoose.connection.collections.hasOwnProperty(collection)) {
|
||||
mongoose.connection.collections[collection].remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function authUser(agent, callback) {
|
||||
agent
|
||||
.post('/users')
|
||||
.set('Accept', 'application/json')
|
||||
.send({ user: { username: 'test', password: 'pass' } })
|
||||
.end((err, res) => {
|
||||
if (err) { return callback(err) }
|
||||
|
||||
callback(null, {
|
||||
user: res.body.user,
|
||||
token: res.body.token
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user