Skip to content

Commit c3de52d

Browse files
committed
react context api auth basic setup
0 parents  commit c3de52d

34 files changed

+10811
-0
lines changed

.gitignore

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
# Created by https://www.gitignore.io/api/node
3+
4+
### Node ###
5+
# Logs
6+
logs
7+
*.log
8+
npm-debug.log*
9+
yarn-debug.log*
10+
yarn-error.log*
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
24+
# nyc test coverage
25+
.nyc_output
26+
27+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
28+
.grunt
29+
30+
# Bower dependency directory (https://bower.io/)
31+
bower_components
32+
33+
# node-waf configuration
34+
.lock-wscript
35+
36+
# Compiled binary addons (https://nodejs.org/api/addons.html)
37+
build/Release
38+
39+
# Dependency directories
40+
node_modules/
41+
jspm_packages/
42+
43+
# TypeScript v1 declaration files
44+
typings/
45+
46+
# Optional npm cache directory
47+
.npm
48+
49+
# Optional eslint cache
50+
.eslintcache
51+
52+
# Optional REPL history
53+
.node_repl_history
54+
55+
# Output of 'npm pack'
56+
*.tgz
57+
58+
# dotenv environment variables file
59+
.env

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# React Context API Demo
2+
3+
Basic demo to show the usage of the React context API with authenticate
4+
5+
Project Structure:
6+
7+
```sh
8+
-api
9+
-src
10+
-data
11+
-schemas
12+
-logic
13+
-routes
14+
-utils
15+
-index.js
16+
-.env
17+
18+
-app
19+
-public
20+
-src
21+
-components
22+
-context
23+
-logic
24+
-utils
25+
-index.js
26+
-.env
27+
```
28+
29+
System Requirements:
30+
31+
- Node
32+
- Mongodb
33+
34+
Server:
35+
36+
1. Install the project dependencies
37+
38+
```sh
39+
$ npm i
40+
```
41+
42+
2. Create the .env file on the root of the api/ folder
43+
44+
```sh
45+
$ touch .env
46+
```
47+
48+
.env
49+
50+
```sh
51+
DB_URL=mongodb://localhost:27017/your-database
52+
PORT=5000
53+
TOKEN_SECRET=your-secret
54+
TOKEN_EXP=3h
55+
```
56+
57+
3. Start the API
58+
59+
```sh
60+
$ npm start
61+
```
62+
63+
Client:
64+
65+
1. Download dependencies
66+
67+
```sh
68+
$ npm i
69+
```
70+
71+
2. Create the .env file on the root of the app/ folder
72+
73+
```sh
74+
$ touch .env
75+
```
76+
77+
.env
78+
79+
```sh
80+
REACT_APP_API_BASE_URL=http:localhost:5000/api
81+
```
82+
83+
\*Note: In order to enviroment variables work with this react project without touching any config file they all have to start with **REACT*APP***
84+
85+
3. Start the app
86+
87+
```sh
88+
$ npm start
89+
```
90+
91+
Author: [http://github.com/mikelpmc](http://github.com/mikelpmc)

api/index.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
require('dotenv').config();
4+
5+
const mongoose = require('mongoose');
6+
const express = require('express');
7+
const router = require('./src/routes/');
8+
const cors = require('cors');
9+
10+
const { userRouter } = require('./src/routes/');
11+
12+
const {
13+
env: { PORT, DB_URL }
14+
} = process;
15+
16+
mongoose
17+
.connect(
18+
DB_URL,
19+
{ useNewUrlParser: true }
20+
)
21+
.then(() => {
22+
const port = PORT || process.argv[2] || 5000;
23+
24+
const app = express();
25+
26+
app.use(cors());
27+
28+
app.use('/api', userRouter);
29+
30+
app.listen(port, () => console.log(`server running on port ${port}`));
31+
32+
process.on('SIGINT', () => {
33+
console.log('\nstopping server');
34+
35+
mongoose.connection.close(() => {
36+
console.log('db connection closed');
37+
38+
process.exit();
39+
});
40+
});
41+
})
42+
.catch(console.error);

api/package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "api",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "node .",
8+
"watch": "nodemon .",
9+
"debug": "node inspect .",
10+
"test": "echo \"Error: no test specified\" && exit 1"
11+
},
12+
"keywords": [],
13+
"author": "",
14+
"license": "ISC",
15+
"dependencies": {
16+
"body-parser": "^1.18.3",
17+
"cors": "^2.8.4",
18+
"dotenv": "^6.0.0",
19+
"express": "^4.16.3",
20+
"jsonwebtoken": "^8.3.0",
21+
"mongodb": "^3.1.4",
22+
"mongoose": "^5.2.14"
23+
}
24+
}

api/src/data/User.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const mongoose = require('mongoose');
2+
const { UserSchema } = require('./schemas/');
3+
4+
module.exports = mongoose.model('User', UserSchema);

api/src/data/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const User = require('./User');
2+
3+
module.exports = {
4+
User
5+
};

api/src/data/schemas/User.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { Schema } = require('mongoose');
2+
3+
const UserSchema = new Schema({
4+
email: {
5+
type: String,
6+
required: true
7+
},
8+
password: {
9+
type: String,
10+
required: true
11+
},
12+
name: {
13+
type: String
14+
}
15+
});
16+
17+
module.exports = UserSchema;

api/src/data/schemas/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const UserSchema = require('./User');
2+
3+
module.exports = {
4+
UserSchema
5+
};

api/src/logic/index.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'use strict';
2+
3+
const mongoose = require('mongoose');
4+
const { User } = require('./../data/');
5+
6+
const { validateEmail } = require('./../utils/validate-email');
7+
8+
const logic = {
9+
_validateStringField(field, value) {
10+
if (typeof field !== 'string' || !field.trim().length)
11+
throw Error(`${field} is not valid`);
12+
},
13+
14+
/**
15+
*
16+
* @param {*} value
17+
*/
18+
_validateEmail(email) {
19+
if (!validateEmail(email)) throw Error(`${email} is not a valid email`);
20+
},
21+
22+
/**
23+
* Register a user
24+
*/
25+
register(name, email, password) {
26+
return Promise.resolve()
27+
.then(() => {
28+
this._validateEmail(email);
29+
this._validateStringField('password', password);
30+
this._validateStringField('name', name);
31+
32+
return User.findOne({ email });
33+
})
34+
.then(user => {
35+
if (user)
36+
throw Error(`User with email ${email} already exists`);
37+
38+
return User.create({ email, password, name });
39+
})
40+
.then(({ email, name }) => ({ email, name }));
41+
},
42+
43+
/**
44+
* Authenticates a user
45+
*/
46+
authenticate(email, password) {
47+
return Promise.resolve()
48+
.then(() => {
49+
this._validateEmail(email);
50+
this._validateStringField('password', password);
51+
52+
return User.findOne({ email, password });
53+
})
54+
.then(user => {
55+
if (!user) throw Error(`Wrong credentials`);
56+
57+
return user;
58+
});
59+
},
60+
61+
/**
62+
* Retrieves a user by its ID
63+
*/
64+
retrieveUserById(userId) {
65+
return Promise.resolve()
66+
.then(() => {
67+
this._validateStringField('userId', userId);
68+
69+
return User.findById(userId).select('email name -_id');
70+
})
71+
.then(user => {
72+
if (!user) throw Error(`No data found for user ${userId}`);
73+
74+
return user;
75+
});
76+
}
77+
};
78+
79+
module.exports = logic;

api/src/routes/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const userRouter = require('./userRouter');
2+
3+
module.exports = {
4+
userRouter
5+
};

0 commit comments

Comments
 (0)