Skip to content

Commit e70f0f1

Browse files
authored
Merge pull request #1 from aeksco/master
Cloned existing project
2 parents ba8d68b + 1afe5e2 commit e70f0f1

22 files changed

+708
-1
lines changed

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# top-most EditorConfig file
2+
root = true
3+
4+
# Unix-style newlines with a newline ending every file
5+
[*]
6+
end_of_line = lf
7+
insert_final_newline = true
8+
indent_style = space
9+
indent_size = 4

.eslintrc.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module.exports = {
2+
"env": {
3+
"es6": true,
4+
"node": true
5+
},
6+
"extends": "eslint:recommended",
7+
"parserOptions": {
8+
"sourceType": "module"
9+
},
10+
"rules": {
11+
"indent": [
12+
"error",
13+
4
14+
],
15+
"linebreak-style": [
16+
"error",
17+
"windows"
18+
],
19+
"quotes": [
20+
"error",
21+
"single"
22+
],
23+
"semi": [
24+
"error",
25+
"never"
26+
],
27+
"no-console": 0
28+
}
29+
};

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
server/config.js
3+
**/.DS_Store
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"variables": [],
3+
"info": {
4+
"name": "astrokey_web_api_dev",
5+
"_postman_id": "a7425849-0679-69d2-7def-bc0559eb593d",
6+
"description": "",
7+
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
8+
},
9+
"item": [
10+
{
11+
"name": "/api/users",
12+
"request": {
13+
"url": "/api/users",
14+
"method": "GET",
15+
"header": [],
16+
"body": {
17+
"mode": "formdata",
18+
"formdata": [
19+
{
20+
"key": "",
21+
"value": "",
22+
"description": "",
23+
"type": "text"
24+
}
25+
]
26+
},
27+
"description": "List all Users in the database."
28+
},
29+
"response": []
30+
},
31+
{
32+
"name": "/api/auth/login",
33+
"request": {
34+
"url": "/api/auth/login",
35+
"method": "POST",
36+
"header": [],
37+
"body": {
38+
"mode": "formdata",
39+
"formdata": [
40+
{
41+
"key": "",
42+
"value": "",
43+
"description": "",
44+
"type": "text"
45+
}
46+
]
47+
},
48+
"description": "Authenticates and end user."
49+
},
50+
"response": []
51+
},
52+
{
53+
"name": "/api/auth/register",
54+
"request": {
55+
"url": "/api/auth/register",
56+
"method": "POST",
57+
"header": [],
58+
"body": {
59+
"mode": "formdata",
60+
"formdata": [
61+
{
62+
"key": "",
63+
"value": "",
64+
"description": "",
65+
"type": "text"
66+
}
67+
]
68+
},
69+
"description": "Registers a new user."
70+
},
71+
"response": []
72+
}
73+
]
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"id": "761f27a7-5e09-1016-e771-9cae71ec51e4",
3+
"name": "astrokey_web_api_dev",
4+
"values": [
5+
{
6+
"key": "server_root",
7+
"value": "localhost:4000",
8+
"description": "",
9+
"type": "text",
10+
"enabled": true
11+
}
12+
],
13+
"timestamp": 1508599920643,
14+
"_postman_variable_scope": "environment",
15+
"_postman_exported_at": "2017-10-21T15:32:18.470Z",
16+
"_postman_exported_using": "Postman/5.2.1"
17+
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
# ak_web_api
1+
# astrokey_web_api
22
AstroKey web backend

docker-compose.yml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
version: '2'
2+
3+
services:
4+
5+
mongo:
6+
image: mongo
7+
ports:
8+
- "27017:27017"
9+
10+
mongo_admin:
11+
image: mongo-express
12+
links:
13+
- mongo
14+
ports:
15+
- "8081:8081"
16+
17+
redis:
18+
image: redis
19+
ports:
20+
- "6379:6379"

package.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "astrokey_web_api",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"start": "nodemon -L ./server/bin/www.js"
6+
},
7+
"license": "MIT",
8+
"dependencies": {
9+
"body-parser": "^1.15.2",
10+
"express": "^4.14.0",
11+
"jsonwebtoken": "^7.1.9",
12+
"mongoose": "^4.7.1",
13+
"morgan": "^1.7.0",
14+
"nodemon": "^1.12.1"
15+
},
16+
"devDependencies": {
17+
"eslint": "^3.11.1"
18+
}
19+
}

server/api/auth/auth.controller.js

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
const jwt = require('jsonwebtoken')
2+
const User = require('../user/user.model')
3+
4+
// // // //
5+
6+
// POST /api/auth/register
7+
// { username, password }
8+
exports.register = (req, res) => {
9+
10+
// Parses username, password parameters from req.body
11+
const { username, password } = req.body
12+
let newUser = null
13+
14+
// create a new user if does not exist
15+
const create = (user) => {
16+
if(user) {
17+
throw new Error('username exists')
18+
} else {
19+
return User.create(username, password)
20+
}
21+
}
22+
23+
// count the number of the user
24+
const count = (user) => {
25+
newUser = user
26+
return User.count({}).exec()
27+
}
28+
29+
// assign admin if count is 1
30+
const assign = (count) => {
31+
if(count === 1) {
32+
return newUser.assignAdmin()
33+
} else {
34+
// if not, return a promise that returns false
35+
return Promise.resolve(false)
36+
}
37+
}
38+
39+
// respond to the client
40+
const respond = (isAdmin) => {
41+
res.json({
42+
message: 'registered successfully',
43+
admin: isAdmin ? true : false
44+
})
45+
}
46+
47+
// run when there is an error (username exists)
48+
const onError = (error) => {
49+
res.status(409).json({
50+
message: error.message
51+
})
52+
}
53+
54+
// check username duplication
55+
User.findOneByUsername(username)
56+
.then(create)
57+
.then(count)
58+
.then(assign)
59+
.then(respond)
60+
.catch(onError)
61+
}
62+
63+
// // // //
64+
65+
// POST /api/auth/login
66+
// { username, password }
67+
exports.login = (req, res) => {
68+
const {username, password} = req.body
69+
const secret = req.app.get('jwt-secret')
70+
71+
// check the user info & generate the jwt
72+
const check = (user) => {
73+
if(!user) {
74+
// user does not exist
75+
throw new Error('login failed')
76+
} else {
77+
// user exists, check the password
78+
if(user.verify(password)) {
79+
// create a promise that generates jwt asynchronously
80+
const p = new Promise((resolve, reject) => {
81+
jwt.sign(
82+
{
83+
_id: user._id,
84+
username: user.username,
85+
admin: user.admin
86+
},
87+
secret,
88+
{
89+
expiresIn: '7d',
90+
issuer: 'velopert.com',
91+
subject: 'userInfo'
92+
}, (err, token) => {
93+
if (err) reject(err)
94+
resolve(token)
95+
})
96+
})
97+
return p
98+
} else {
99+
throw new Error('login failed')
100+
}
101+
}
102+
}
103+
104+
// respond the token
105+
const respond = (token) => {
106+
res.json({
107+
message: 'logged in successfully',
108+
token
109+
})
110+
}
111+
112+
// error occured
113+
const onError = (error) => {
114+
res.status(403).json({
115+
message: error.message
116+
})
117+
}
118+
119+
// find the user
120+
User.findOneByUsername(username)
121+
.then(check)
122+
.then(respond)
123+
.catch(onError)
124+
125+
}

server/api/auth/index.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const router = require('express').Router()
2+
const controller = require('./auth.controller')
3+
4+
// // // //
5+
6+
// POST /register
7+
router.post('/register', controller.register)
8+
9+
// POST /login
10+
router.post('/login', controller.login)
11+
12+
// // // //
13+
14+
module.exports = router

0 commit comments

Comments
 (0)