Skip to content

Commit 72b778b

Browse files
committed
Add Users resource
Other changes: - Update and delete migrations and seeders - Update sessions lib - Fix the cors method in server.js
1 parent 3eba25c commit 72b778b

24 files changed

+536
-258
lines changed

README.md

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,22 @@ To manage separate Docker instance for API, open another terminal console and ru
117117

118118
Use the following credentials to test different API responses. Default password for all accounts is `password`.
119119

120-
- **Super Admin User:** `superadmin@email.com` - has wildcard access
121-
- **Admin User:** `admin@email.com` - has wildcard access but Admin › Users › Delete is excluded
122-
- **Common User:** `user@email.com` - can access My Profile, Admin › Dashboard, Users, Users › View, and Settings
123-
- **User redirected to internal page:** `referrer@email.com` – when `redirect.url` is set without the domain,
124-
user shall be redirected to internal page if no location path (referrer) found on the Sign In page
125-
- **User redirected to external page:** `redirect@email.com` – when `redirect.external` and `redirect.url` are set,
126-
user shall be redirected to external page if no location path (referrer) found on the Sign In page
127-
- **Blocked User:** `blocked@email.com` – user is signed in but the account is blocked
128-
- **Unauthorized User:** simply enter wrong `email` and/or `password`
120+
| Name | Email | Description |
121+
|-------------------|------------------------|-------------|
122+
| Super Admin User | `superadmin@email.com` | Has wildcard access |
123+
| Admin User | `admin@email.com` | Has wildcard access but `Admin › Users › Delete` is excluded |
124+
| Common User | `user@email.com` | Can access `My Profile`, `Admin › Dashboard`, `Users`, `Users › View, and Settings` |
125+
| Referrer User | `referrer@email.com` | When `redirect` is set without the domain, e.i. `/admin/dashboard`, user shall be redirected to internal page if no location path (referrer) found on the Sign In page |
126+
| Redirect User | `redirect@email.com` | When `redirect` is set with complete URL, e.i. `https://github.com/anthub-services`, user shall be redirected to external page if no location path (referrer) found on the Sign In page |
127+
| Blocked User | `blocked@email.com` | User is signed in but the account is blocked |
128+
| Unauthorized User | `<any invalid email>` | Simply enter wrong `email` and/or `password` |
129+
130+
## Docker Boilerplates
131+
132+
The following boilerplates can be used to install and run the API and client boilerplates in a Docker container.
133+
134+
[Docker for Node API Mockup Data and Client Boilerplates](https://github.com/anthub-services/docker-for-node-api-mockup-data-and-client-boilerplates)
135+
<br />
136+
[Docker for Node API and Client Boilerplates](https://github.com/anthub-services/docker-for-node-api-and-client-boilerplates)
137+
<br />
138+
[Docker for Rails API and Client Boilerplates](https://github.com/anthub-services/docker-for-rails-api-and-client-boilerplates)

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-express-api-boilerplate",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "Node Express API Boilerplate",
55
"author": "Ricky Hurtado",
66
"license": "UNLICENSED",
@@ -19,6 +19,7 @@
1919
"dotenv": "^4.0.0",
2020
"express": "~4.0.0",
2121
"jsonwebtoken": "^8.1.1",
22+
"moment": "^2.21.0",
2223
"passport": "^0.4.0",
2324
"passport-http-bearer": "^1.0.1",
2425
"pg": "^7.4.1",

src/controllers/Users.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import * as Users from '../lib/Users'
2+
3+
export default {
4+
list(req, res) {
5+
Promise
6+
.all([
7+
Users.list({
8+
res,
9+
query: req.query,
10+
returnData: true,
11+
jsonData: true
12+
}),
13+
Users.pages({ query: req.query })
14+
])
15+
.then(promises => {
16+
res.status(200).send({
17+
rows: promises[0],
18+
pages: promises[1]
19+
})
20+
})
21+
.catch(error => {
22+
res.status(400).send(error)
23+
})
24+
},
25+
26+
create(req, res) {
27+
// TODO: Create promises for paths creation and
28+
// sending temporary password to the new user
29+
// after the user record has beend created
30+
31+
Users.create({
32+
res,
33+
body: req.body
34+
})
35+
},
36+
37+
find(req, res) {
38+
Users.find({
39+
res,
40+
where: {
41+
userId: req.params.userId
42+
}
43+
})
44+
},
45+
46+
update(req, res) {
47+
Users.update({
48+
res,
49+
body: req.body,
50+
userId: req.params.userId
51+
})
52+
},
53+
54+
destroy(req, res) {
55+
Users.destroy({
56+
res,
57+
userId: req.params.userId
58+
})
59+
}
60+
}

src/controllers/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import Sessions from './Sessions'
22
import Tests from './Tests'
3+
import Users from './Users'
34

45
export default {
56
Sessions,
6-
Tests
7+
Tests,
8+
Users
79
}

src/helpers/Data.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import _ from 'lodash'
2+
import Sequelize from 'sequelize'
3+
4+
const DEFAULT_LIMIT = 20
5+
6+
export function filters(filtered, options={}) {
7+
if (!filtered) return {}
8+
9+
const filterArray = []
10+
11+
decodeURIComponent(filtered).split(',').map(filter => {
12+
const array = filter.split(':')
13+
14+
filterArray.push(filterType(array[0], decodeURIComponent(array[1]), options))
15+
})
16+
17+
return { $and: filterArray }
18+
}
19+
20+
export function orderBy(sorted, defaultOrder=[]) {
21+
if (!sorted) return [defaultOrder]
22+
23+
return sorted.split(',').map(sort => {
24+
return sort.split(':')
25+
})
26+
}
27+
28+
export function pageCount({ limit }, count) {
29+
return Math.ceil(count / (limit ? limit : DEFAULT_LIMIT))
30+
}
31+
32+
function filterType(key, value, options) {
33+
const optionKeys = Object.keys(options)
34+
35+
if (_.indexOf(optionKeys, key) > -1) {
36+
const filterObject = {}
37+
const type = options[key].type
38+
const col = options[key].col
39+
40+
if (type === 'integer')
41+
filterObject[key] = parseInt(value)
42+
43+
if (type === 'minDate')
44+
filterObject[col] = { $gte: new Date(value) }
45+
46+
if (type === 'maxDate')
47+
filterObject[col] = { $lte: new Date(value) }
48+
49+
return filterObject
50+
}
51+
52+
return Sequelize.where(
53+
Sequelize.fn(
54+
'lower',
55+
Sequelize.col(key)
56+
),
57+
{
58+
$like: value.toLowerCase()
59+
}
60+
)
61+
}

src/helpers/Math.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export function rand(min=0, max=60) {
2+
min = Math.ceil(min)
3+
max = Math.floor(max)
4+
5+
return Math.floor(Math.random() * (max - min)) + min
6+
}

src/lib/Paths.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import DB from '../models'
2+
3+
export function create(options) {
4+
const { res, body, userId } = options
5+
const value = {
6+
allowedPaths: body.allowedPaths,
7+
excludedPaths: body.excludedPaths,
8+
}
9+
10+
DB.Path
11+
.create({ userId, value })
12+
.then(Path => {
13+
const data = Path ? { userId } : null
14+
15+
return res.status(Path ? 201 : 400).send(data)
16+
})
17+
.catch(error => {
18+
console.log(error)
19+
20+
res.status(400).send(error)
21+
})
22+
}
23+
24+
export function update(options) {
25+
const { res, body, userId } = options
26+
const value = {
27+
allowedPaths: body.allowedPaths,
28+
excludedPaths: body.excludedPaths,
29+
}
30+
31+
DB.Path
32+
.update({ value }, {
33+
where: { userId }
34+
})
35+
.then(Path => {
36+
return res.status(Path ? 200 : 400).send()
37+
})
38+
.catch(error => {
39+
console.log(error)
40+
41+
res.status(400).send(error)
42+
})
43+
}

src/lib/Sessions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function auth(req, res) {
6161
}
6262

6363
return Users
64-
.find(null, { where: { email }, returnData: true })
64+
.find({ where: { email }, returnData: true })
6565
.then(User => {
6666
if (!User.object || !(User.object && User.object.authenticate(password)))
6767
return authResponse.invalid

0 commit comments

Comments
 (0)