diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9daa824 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +node_modules diff --git a/README.md b/README.md index b2e3b8b..dcd8487 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -# api-auth \ No newline at end of file +# USER-AUTH + +ROUTE | HTTP | Description +------|------| ----------- +/api/signup | POST | create a new user with role is "user" +/api/signin | POST | create a token if true (admin, password) +/api/users | GET | Get All User for admin +/api/users/:id | GET | Get a Single User for admin and authenticated user +/api/users | POST | Create a User for admin +/api/users/:id | DELETE | Delete a User for admin +/api/users/:id | PUT | Update a user with new info for admin and authenticated user diff --git a/app.js b/app.js new file mode 100644 index 0000000..1eb5d40 --- /dev/null +++ b/app.js @@ -0,0 +1,27 @@ +"use strict" + +const express = require('express') + +var index = require('./routes/index'); +var users = require('./routes/users'); + +//UNTUK GABUNGIN VIEW MUNGKIN??? +// var path = require('path'); +var bodyParser = require('body-parser'); +let app = express() + + +//UNTUK VIEW TERNYATA +// app.set('views', path.join(__dirname, 'views')); +// app.set('view engine', 'ejs'); + + +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); + +app.use('/', index); +app.use('/api', users); + + +app.listen(3000) +module.exports = app; \ No newline at end of file diff --git a/config/config.json b/config/config.json new file mode 100644 index 0000000..fc36860 --- /dev/null +++ b/config/config.json @@ -0,0 +1,24 @@ +{ + "development": { + "username": "postgres", + "password": "postgres", + "database": "api_auth", + "host": "127.0.0.1", + "port": "5432", + "dialect": "postgres" + }, + "test": { + "username": "root", + "password": null, + "database": "database_test", + "host": "127.0.0.1", + "dialect": "mysql" + }, + "production": { + "username": "root", + "password": null, + "database": "database_production", + "host": "127.0.0.1", + "dialect": "mysql" + } +} diff --git a/controllers/userController.js b/controllers/userController.js new file mode 100644 index 0000000..665db93 --- /dev/null +++ b/controllers/userController.js @@ -0,0 +1,71 @@ +var db = require('../models'); +var passwordHash = require('password-hash') +var jwt = require('jsonwebtoken') +const methods = {} + +methods.signUp = function(req,res){ + db.User.create({ + username:req.body.username, + password:passwordHash.generate(req.body.password), + role:"user", + name:req.body.name + }) + .then((user)=>{ + res.send(user) + }) +}// CREATE USER SIGN UP + +methods.signIn = function(req,res){ + db.User.findOne({where : {username:req.body.username}}) + .then((user)=>{ + if(passwordHash.verify(req.body.password, user.password)){ + let token = jwt.sign({id:user.id, username: user.username, role: user.role}, 'secret', {expiresIn:'6h'}) + res.send(token) + } + else{ + res.send('password tidak cocok') + } + }) +}// SIGN IN (LOGIN) + +methods.getAllUser = function(req,res){ + db.User.findAll() + .then((users)=>{ + res.send(users) + }) +}// GET ALL USERS + +methods.getSingleUser = function(req,res){ + db.User.findById(req.params.id) + .then((user)=>{ + res.send(user) + }) +}// FIND SINGLE USER + +methods.createUser = function(req,res){ + db.User.create({ + username:req.body.username, + password:passwordHash.generate(req.body.password), + name:req.body.name, + role:"user" + }) + .then((user)=>{ + res.send(user) + }) +}// CREATE USER + +methods.deleteUser = function(req,res){ + db.User.destroy({where : { id : req.params.id }} ) + .then(()=>{ + res.send('berhasil hapus') + }) +}// Delete USER + +methods.updateUser = function(req,res){ + db.User.update({username: req.body.username, password:passwordHash.generate(req.body.password), role:req.body.role}, {where : { id : req.params.id }} ) + .then(()=>{ + res.send('berhasil update') + }) +}// Delete USER + +module.exports = methods \ No newline at end of file diff --git a/helper/jwt_validation.js b/helper/jwt_validation.js new file mode 100644 index 0000000..120e183 --- /dev/null +++ b/helper/jwt_validation.js @@ -0,0 +1,36 @@ +var jwt = require('jsonwebtoken') +const methods = {} + +methods.verifyLogin = function(req,res, next){ + jwt.verify(req.headers.token, 'secret', function(err, decoded){ + if(!err){ + if(decoded.role == 'admin' || decoded.id == req.params.id){ + next() + } + else{ + res.send('Anda Tidak punya Akses') + } + } + else { + res.send(err) + } + }) +} + +methods.verifyAdmin = function(req,res, next){ + jwt.verify(req.headers.token, 'secret', function(err, decoded){ + if(!err){ + if(decoded.role == 'admin'){ + next() + } + else{ + res.send('Anda Bukan Admin') + } + } + else { + res.send(err) + } + }) +} + +module.exports = methods \ No newline at end of file diff --git a/migrations/20170425074314-create-user.js b/migrations/20170425074314-create-user.js new file mode 100644 index 0000000..3b6a4f3 --- /dev/null +++ b/migrations/20170425074314-create-user.js @@ -0,0 +1,38 @@ +'use strict'; +module.exports = { + up: function(queryInterface, Sequelize) { + return queryInterface.createTable('Users', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + username: { + type: Sequelize.STRING + }, + password: { + type: Sequelize.STRING + }, + role: { + type: Sequelize.STRING + }, + name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + defaultValue:new Date() + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + defaultValue:new Date() + } + }); + }, + down: function(queryInterface, Sequelize) { + return queryInterface.dropTable('Users'); + } +}; \ No newline at end of file diff --git a/models/index.js b/models/index.js new file mode 100644 index 0000000..7540dba --- /dev/null +++ b/models/index.js @@ -0,0 +1,36 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var Sequelize = require('sequelize'); +var basename = path.basename(module.filename); +var env = process.env.NODE_ENV || 'development'; +var config = require(__dirname + '/../config/config.json')[env]; +var db = {}; + +if (config.use_env_variable) { + var sequelize = new Sequelize(process.env[config.use_env_variable]); +} else { + var sequelize = new Sequelize(config.database, config.username, config.password, config); +} + +fs + .readdirSync(__dirname) + .filter(function(file) { + return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); + }) + .forEach(function(file) { + var model = sequelize['import'](path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach(function(modelName) { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/models/user.js b/models/user.js new file mode 100644 index 0000000..5985912 --- /dev/null +++ b/models/user.js @@ -0,0 +1,16 @@ +'use strict'; +module.exports = function(sequelize, DataTypes) { + var User = sequelize.define('User', { + username: DataTypes.STRING, + password: DataTypes.STRING, + role: DataTypes.STRING, + name: DataTypes.STRING + }, { + classMethods: { + associate: function(models) { + // associations can be defined here + } + } + }); + return User; +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..cd71ba3 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "api-auth", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "start": "nodemon ./app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/oscarhermawan/api-auth.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/oscarhermawan/api-auth/issues" + }, + "homepage": "https://github.com/oscarhermawan/api-auth#readme", + "dependencies": { + "body-parser": "^1.17.1", + "express": "^4.15.2", + "jsonwebtoken": "^7.4.0", + "password-hash": "^1.2.2", + "pg": "^6.1.5", + "sequelize": "^3.30.4" + } +} diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..e92cbd6 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,10 @@ +var express = require('express'); +var router = express.Router(); + +// var db = require('../models'); + +router.get('/', function(req, res){ + res.send('halo') +}) + +module.exports = router \ No newline at end of file diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..9671e1f --- /dev/null +++ b/routes/users.js @@ -0,0 +1,14 @@ +var express = require('express'); +var api = require('../controllers/userController') +var jwt = require('../helper/jwt_validation') +var router = express.Router(); + +router.post('/signup', api.signUp) // +router.post('/signin', api.signIn) // +router.get('/users', jwt.verifyAdmin, api.getAllUser) // +router.get('/users/:id', jwt.verifyLogin, api.getSingleUser) // +router.post('/users', jwt.verifyAdmin, api.createUser) // +router.delete('/users/:id', jwt.verifyAdmin, api.deleteUser) // +router.put('/users/:id', jwt.verifyLogin, api.updateUser) + +module.exports = router \ No newline at end of file