├── client ├── .env ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── src │ ├── components │ │ ├── Home.js │ │ ├── App.js │ │ ├── CustomInput.js │ │ ├── HOCs │ │ │ └── authGuard.js │ │ ├── Header.js │ │ ├── Dashboard.js │ │ ├── SignIn.js │ │ └── SignUp.js │ ├── reducers │ │ ├── index.js │ │ ├── auth.js │ │ └── dashboard.js │ ├── actions │ │ ├── types.js │ │ └── index.js │ ├── index.js │ └── registerServiceWorker.js ├── .gitignore └── package.json ├── __tests__ ├── report │ ├── lcov-report │ │ ├── sort-arrow-sprite.png │ │ ├── prettify.css │ │ ├── server │ │ │ ├── configuration │ │ │ │ ├── index.js.html │ │ │ │ └── index.html │ │ │ ├── index.html │ │ │ ├── models │ │ │ │ ├── index.html │ │ │ │ └── user.js.html │ │ │ ├── routes │ │ │ │ ├── index.html │ │ │ │ └── users.js.html │ │ │ ├── controllers │ │ │ │ ├── index.html │ │ │ │ └── users.js.html │ │ │ ├── helpers │ │ │ │ ├── index.html │ │ │ │ └── routeHelpers.js.html │ │ │ ├── app.js.html │ │ │ └── passport.js.html │ │ ├── routes │ │ │ ├── index.html │ │ │ └── users.js.html │ │ ├── controllers │ │ │ ├── index.html │ │ │ └── users.js.html │ │ ├── helpers │ │ │ ├── index.html │ │ │ └── routeHelpers.js.html │ │ ├── configuration │ │ │ ├── index.html │ │ │ └── index.js.html │ │ ├── index.html │ │ ├── sorter.js │ │ ├── base.css │ │ └── prettify.js │ └── lcov.info └── server │ ├── routes │ └── users.test.js │ └── controllers │ └── users.test.js ├── .gitignore ├── .travis.yml ├── server ├── index.js ├── helpers │ └── routeHelpers.js ├── configuration │ └── index.js ├── app.js ├── routes │ └── users.js ├── models │ └── user.js ├── controllers │ └── users.js └── passport.js ├── .editorconfig ├── package.json └── README.md /client/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eXtremeXR/APIAuthenticationWithNode/HEAD/client/public/favicon.ico -------------------------------------------------------------------------------- /__tests__/report/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eXtremeXR/APIAuthenticationWithNode/HEAD/__tests__/report/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /client/src/components/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => { 4 | return ( 5 |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 | 1x 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | | module.exports = {
73 | JWT_SECRET: 'codeworkrauthentication',
74 | oauth: {
75 | google: {
76 | clientID: 'number',
77 | clientSecret: 'string'
78 | },
79 | facebook: {
80 | clientID: 'number',
81 | clientSecret: 'string'
82 | }
83 | }
84 | };
85 | |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| passport.js | 63 |44.9% | 65 |22/49 | 66 |30% | 67 |3/10 | 68 |50% | 69 |2/4 | 70 |44.9% | 71 |22/49 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| users.js | 63 |100% | 65 |14/14 | 66 |100% | 67 |0/0 | 68 |100% | 69 |0/0 | 70 |100% | 71 |14/14 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| users.js | 63 |100% | 65 |22/22 | 66 |100% | 67 |2/2 | 68 |100% | 69 |6/6 | 70 |100% | 71 |22/22 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| routeHelpers.js | 63 |100% | 65 |10/10 | 66 |75% | 67 |3/4 | 68 |100% | 69 |2/2 | 70 |100% | 71 |9/9 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| index.js | 63 |66.67% | 65 |2/3 | 66 |50% | 67 |1/2 | 68 |100% | 69 |0/0 | 70 |66.67% | 71 |2/3 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| user.js | 63 |88.24% | 65 |15/17 | 66 |100% | 67 |0/0 | 68 |100% | 69 |2/2 | 70 |88.24% | 71 |15/17 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| users.js | 63 |100% | 65 |14/14 | 66 |100% | 67 |0/0 | 68 |100% | 69 |0/0 | 70 |100% | 71 |14/14 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| index.js | 63 |100% | 65 |1/1 | 66 |100% | 67 |0/0 | 68 |100% | 69 |0/0 | 70 |100% | 71 |1/1 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| users.js | 63 |100% | 65 |22/22 | 66 |100% | 67 |2/2 | 68 |100% | 69 |6/6 | 70 |100% | 71 |22/22 | 72 |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| routeHelpers.js | 63 |100% | 65 |10/10 | 66 |75% | 67 |3/4 | 68 |100% | 69 |2/2 | 70 |100% | 71 |9/9 | 72 |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 | 1x 69 | 70 | 1x 71 | 72 | 2x 73 | 5x 74 | 5x 75 | 1x 76 | 77 | 78 | 4x 79 | 4x 80 | 4x 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | | const Joi = require('joi');
91 |
92 | module.exports = {
93 | validateBody: (schema) => {
94 | return (req, res, next) => {
95 | const result = Joi.validate(req.body, schema);
96 | if (result.error) {
97 | return res.status(400).json(result.error);
98 | }
99 |
100 | Eif (!req.value) { req.value = {}; }
101 | req.value['body'] = result.value;
102 | next();
103 | }
104 | },
105 |
106 | schemas: {
107 | authSchema: Joi.object().keys({
108 | email: Joi.string().email().required(),
109 | password: Joi.string().required()
110 | })
111 | }
112 | } |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 | 1x 69 | 70 | 1x 71 | 72 | 2x 73 | 5x 74 | 5x 75 | 1x 76 | 77 | 78 | 4x 79 | 4x 80 | 4x 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | | const Joi = require('joi');
91 |
92 | module.exports = {
93 | validateBody: (schema) => {
94 | return (req, res, next) => {
95 | const result = Joi.validate(req.body, schema);
96 | if (result.error) {
97 | return res.status(400).json(result.error);
98 | }
99 |
100 | Eif (!req.value) { req.value = {}; }
101 | req.value['body'] = result.value;
102 | next();
103 | }
104 | },
105 |
106 | schemas: {
107 | authSchema: Joi.object().keys({
108 | email: Joi.string().email().required(),
109 | password: Joi.string().required()
110 | })
111 | }
112 | } |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| controllers | 63 |100% | 65 |22/22 | 66 |100% | 67 |2/2 | 68 |100% | 69 |6/6 | 70 |100% | 71 |22/22 | 72 ||
| routes | 76 |100% | 78 |14/14 | 79 |100% | 80 |0/0 | 81 |100% | 82 |0/0 | 83 |100% | 84 |14/14 | 85 |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 | 1x 72 | 1x 73 | 1x 74 | 1x 75 | 76 | 1x 77 | 1x 78 | 1x 79 | 80 | 81 | 82 | 83 | 1x 84 | 85 | 86 | 1x 87 | 88 | 89 | 90 | 1x 91 | 92 | 93 | 1x 94 | 95 | 1x 96 | | const express = require('express');
97 | const morgan = require('morgan');
98 | const bodyParser = require('body-parser');
99 | const mongoose = require('mongoose');
100 |
101 | mongoose.Promise = global.Promise;
102 | Eif (process.env.NODE_ENV === 'test') {
103 | mongoose.connect('mongodb://localhost/APIAuthenticationTEST', { useMongoClient: true });
104 | } else {
105 | mongoose.connect('mongodb://localhost/APIAuthentication', { useMongoClient: true });
106 | }
107 |
108 | const app = express();
109 |
110 | // Middlewares moved morgan into if for clear tests
111 | Iif (!process.env.NODE_ENV === 'test') {
112 | app.use(morgan('dev'));
113 | }
114 |
115 | app.use(bodyParser.json());
116 |
117 | // Routes
118 | app.use('/users', require('./routes/users'));
119 |
120 | module.exports = app;
121 | |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 | 1x 72 | 1x 73 | 1x 74 | 1x 75 | 76 | 1x 77 | 1x 78 | 1x 79 | 1x 80 | 81 | 1x 82 | 83 | 84 | 1x 85 | 86 | 87 | 1x 88 | 89 | 90 | 1x 91 | 92 | 93 | 1x 94 | 95 | 96 | 1x | const express = require('express');
97 | const router = require('express-promise-router')();
98 | const passport = require('passport');
99 | const passportConf = require('../passport');
100 |
101 | const { validateBody, schemas } = require('../helpers/routeHelpers');
102 | const UsersController = require('../controllers/users');
103 | const passportSignIn = passport.authenticate('local', { session: false });
104 | const passportJWT = passport.authenticate('jwt', { session: false });
105 |
106 | router.route('/signup')
107 | .post(validateBody(schemas.authSchema), UsersController.signUp);
108 |
109 | router.route('/signin')
110 | .post(validateBody(schemas.authSchema), passportSignIn, UsersController.signIn);
111 |
112 | router.route('/oauth/google')
113 | .post(passport.authenticate('googleToken', { session: false }), UsersController.googleOAuth);
114 |
115 | router.route('/oauth/facebook')
116 | .post(passport.authenticate('facebookToken', { session: false }), UsersController.facebookOAuth);
117 |
118 | router.route('/secret')
119 | .get(passportJWT, UsersController.secret);
120 |
121 | module.exports = router; |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 | 1x 76 | 1x 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | | Eif (process.env.NODE_ENV === 'test') { 105 | module.exports = { 106 | JWT_SECRET: 'codeworkrauthentication', 107 | oauth: { 108 | google: { 109 | clientID: 'number', 110 | clientSecret: 'string', 111 | }, 112 | facebook: { 113 | clientID: 'number', 114 | clientSecret: 'string', 115 | }, 116 | }, 117 | }; 118 | } else { 119 | module.exports = { 120 | JWT_SECRET: '', 121 | oauth: { 122 | google: { 123 | clientID: '', 124 | clientSecret: '', 125 | }, 126 | facebook: { 127 | clientID: '', 128 | clientSecret: '', 129 | }, 130 | }, 131 | }; 132 | } 133 | |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 | 1x 72 | 1x 73 | 1x 74 | 1x 75 | 76 | 1x 77 | 1x 78 | 1x 79 | 1x 80 | 81 | 1x 82 | 83 | 84 | 1x 85 | 86 | 87 | 1x 88 | 89 | 90 | 1x 91 | 92 | 93 | 1x 94 | 95 | 96 | 1x | const express = require('express');
97 | const router = require('express-promise-router')();
98 | const passport = require('passport');
99 | const passportConf = require('../passport');
100 |
101 | const { validateBody, schemas } = require('../helpers/routeHelpers');
102 | const UsersController = require('../controllers/users');
103 | const passportSignIn = passport.authenticate('local', { session: false });
104 | const passportJWT = passport.authenticate('jwt', { session: false });
105 |
106 | router.route('/signup')
107 | .post(validateBody(schemas.authSchema), UsersController.signUp);
108 |
109 | router.route('/signin')
110 | .post(validateBody(schemas.authSchema), passportSignIn, UsersController.signIn);
111 |
112 | router.route('/oauth/google')
113 | .post(passport.authenticate('googleToken', { session: false }), UsersController.googleOAuth);
114 |
115 | router.route('/oauth/facebook')
116 | .post(passport.authenticate('facebookToken', { session: false }), UsersController.facebookOAuth);
117 |
118 | router.route('/secret')
119 | .get(passportJWT, UsersController.secret);
120 |
121 | module.exports = router; |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 89 | 44 90 | 45 | 1x 91 | 1x 92 | 1x 93 | 94 | 95 | 1x 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 1x 109 | 2x 110 | 111 | 2x 112 | 113 | 2x 114 | 115 | 2x 116 | 2x 117 | 118 | 119 | 120 | 121 | 122 | 1x 123 | 1x 124 | 1x 125 | 126 | 127 | 128 | 129 | 130 | 131 | 1x 132 | 133 | 134 | 1x | const mongoose = require('mongoose');
135 | const bcrypt = require('bcryptjs');
136 | const Schema = mongoose.Schema;
137 |
138 | // Create a schema
139 | const userSchema = new Schema({
140 | email: {
141 | type: String,
142 | required: true,
143 | unique: true,
144 | lowercase: true
145 | },
146 | password: {
147 | type: String,
148 | required: true
149 | }
150 | });
151 |
152 | userSchema.pre('save', async function(next) {
153 | try {
154 | // Generate a salt
155 | const salt = await bcrypt.genSalt(10);
156 | // Generate a password hash (salt + hash)
157 | const passwordHash = await bcrypt.hash(this.password, salt);
158 | // Re-assign hashed version over original, plain text password
159 | this.password = passwordHash;
160 | next();
161 | } catch(error) {
162 | next(error);
163 | }
164 | });
165 |
166 | userSchema.methods.isValidPassword = async function(newPassword) {
167 | try {
168 | return await bcrypt.compare(newPassword, this.password);
169 | } catch(error) {
170 | throw new Error(error);
171 | }
172 | }
173 |
174 | // Create a model
175 | const User = mongoose.model('user', userSchema);
176 |
177 | // Export the model
178 | module.exports = User; |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 89 | 44 90 | 45 91 | 46 92 | 47 93 | 48 94 | 49 95 | 50 96 | 51 97 | 52 98 | 53 99 | 54 100 | 55 101 | 56 102 | 57 103 | 58 104 | 59 105 | 60 106 | 61 107 | 62 108 | 63 | 2x 109 | 2x 110 | 2x 111 | 112 | 2x 113 | 6x 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 2x 122 | 123 | 7x 124 | 125 | 126 | 7x 127 | 7x 128 | 2x 129 | 130 | 131 | 132 | 5x 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 5x 141 | 142 | 143 | 5x 144 | 145 | 5x 146 | 147 | 148 | 149 | 150 | 3x 151 | 3x 152 | 153 | 154 | 155 | 156 | 1x 157 | 1x 158 | 159 | 160 | 161 | 162 | 1x 163 | 1x 164 | 165 | 166 | 167 | 2x 168 | 2x 169 | 170 | | const JWT = require('jsonwebtoken');
171 | const User = require('../models/user');
172 | const { JWT_SECRET } = require('../configuration');
173 |
174 | signToken = user => {
175 | return JWT.sign({
176 | iss: 'CodeWorkr',
177 | sub: user.id,
178 | iat: new Date().getTime(), // current time
179 | exp: new Date().setDate(new Date().getDate() + 1) // current time + 1 day ahead
180 | }, JWT_SECRET);
181 | }
182 |
183 | module.exports = {
184 | signUp: async (req, res, next) => {
185 | const { email, password } = req.value.body;
186 |
187 | // Check if there is a user with the same email
188 | const foundUser = await User.findOne({ "local.email": email });
189 | if (foundUser) {
190 | return res.status(403).json({ error: 'Email is already in use'});
191 | }
192 |
193 | // Create a new user
194 | const newUser = new User({
195 | method: 'local',
196 | local: {
197 | email: email,
198 | password: password
199 | }
200 | });
201 |
202 | await newUser.save();
203 |
204 | // Generate the token
205 | const token = signToken(newUser);
206 | // Respond with token
207 | res.status(200).json({ token });
208 | },
209 |
210 | signIn: async (req, res, next) => {
211 | // Generate token
212 | const token = signToken(req.user);
213 | res.status(200).json({ token });
214 | },
215 |
216 | googleOAuth: async (req, res, next) => {
217 | // Generate token
218 | const token = signToken(req.user);
219 | res.status(200).json({ token });
220 | },
221 |
222 | facebookOAuth: async (req, res, next) => {
223 | // Generate token
224 | const token = signToken(req.user);
225 | res.status(200).json({ token });
226 | },
227 |
228 | secret: async (req, res, next) => {
229 | console.log('I managed to get here!');
230 | res.json({ secret: "resource" });
231 | }
232 | } |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 89 | 44 90 | 45 91 | 46 92 | 47 93 | 48 94 | 49 95 | 50 96 | 51 97 | 52 98 | 53 99 | 54 100 | 55 101 | 56 102 | 57 103 | 58 104 | 59 105 | 60 106 | 61 107 | 62 108 | 63 | 2x 109 | 2x 110 | 2x 111 | 112 | 2x 113 | 6x 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 2x 122 | 123 | 7x 124 | 125 | 126 | 7x 127 | 7x 128 | 2x 129 | 130 | 131 | 132 | 5x 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 5x 141 | 142 | 143 | 5x 144 | 145 | 5x 146 | 147 | 148 | 149 | 150 | 3x 151 | 3x 152 | 153 | 154 | 155 | 156 | 1x 157 | 1x 158 | 159 | 160 | 161 | 162 | 1x 163 | 1x 164 | 165 | 166 | 167 | 2x 168 | 2x 169 | 170 | | const JWT = require('jsonwebtoken');
171 | const User = require('../models/user');
172 | const { JWT_SECRET } = require('../configuration');
173 |
174 | signToken = user => {
175 | return JWT.sign({
176 | iss: 'CodeWorkr',
177 | sub: user.id,
178 | iat: new Date().getTime(), // current time
179 | exp: new Date().setDate(new Date().getDate() + 1) // current time + 1 day ahead
180 | }, JWT_SECRET);
181 | }
182 |
183 | module.exports = {
184 | signUp: async (req, res, next) => {
185 | const { email, password } = req.value.body;
186 |
187 | // Check if there is a user with the same email
188 | const foundUser = await User.findOne({ "local.email": email });
189 | if (foundUser) {
190 | return res.status(403).json({ error: 'Email is already in use'});
191 | }
192 |
193 | // Create a new user
194 | const newUser = new User({
195 | method: 'local',
196 | local: {
197 | email: email,
198 | password: password
199 | }
200 | });
201 |
202 | await newUser.save();
203 |
204 | // Generate the token
205 | const token = signToken(newUser);
206 | // Respond with token
207 | res.status(200).json({ token });
208 | },
209 |
210 | signIn: async (req, res, next) => {
211 | // Generate token
212 | const token = signToken(req.user);
213 | res.status(200).json({ token });
214 | },
215 |
216 | googleOAuth: async (req, res, next) => {
217 | // Generate token
218 | const token = signToken(req.user);
219 | res.status(200).json({ token });
220 | },
221 |
222 | facebookOAuth: async (req, res, next) => {
223 | // Generate token
224 | const token = signToken(req.user);
225 | res.status(200).json({ token });
226 | },
227 |
228 | secret: async (req, res, next) => {
229 | console.log('I managed to get here!');
230 | res.json({ secret: "resource" });
231 | }
232 | } |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 89 | 44 90 | 45 91 | 46 92 | 47 93 | 48 94 | 49 95 | 50 96 | 51 97 | 52 98 | 53 99 | 54 100 | 55 101 | 56 102 | 57 103 | 58 104 | 59 105 | 60 106 | 61 107 | 62 108 | 63 109 | 64 110 | 65 111 | 66 112 | 67 113 | 68 114 | 69 115 | 70 116 | 71 117 | 72 118 | 73 119 | 74 120 | 75 121 | 76 122 | 77 123 | 78 124 | 79 125 | 80 126 | 81 127 | 82 128 | 83 129 | 84 130 | 85 131 | 86 132 | 87 133 | 88 134 | 89 135 | 90 136 | 91 137 | 92 138 | 93 139 | 94 140 | 95 141 | 96 142 | 97 143 | 98 144 | 99 145 | 100 146 | 101 147 | 102 148 | 103 149 | 104 150 | 105 151 | 106 152 | 107 153 | 108 154 | 109 155 | 110 156 | 111 157 | 112 158 | 113 159 | 114 160 | 115 161 | 116 162 | 117 | 1x 163 | 1x 164 | 1x 165 | 1x 166 | 1x 167 | 1x 168 | 1x 169 | 1x 170 | 171 | 172 | 1x 173 | 174 | 175 | 176 | 1x 177 | 178 | 1x 179 | 180 | 181 | 1x 182 | 183 | 184 | 185 | 186 | 1x 187 | 188 | 189 | 190 | 191 | 192 | 193 | 1x 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 1x 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 1x 254 | 255 | 256 | 1x 257 | 258 | 1x 259 | 260 | 261 | 1x 262 | 263 | 264 | 265 | 266 | 1x 267 | 268 | 269 | 1x 270 | 271 | 272 | 273 | 274 | 1x 275 | 276 | 277 | 278 | | const passport = require('passport');
279 | const JwtStrategy = require('passport-jwt').Strategy;
280 | const { ExtractJwt } = require('passport-jwt');
281 | const LocalStrategy = require('passport-local').Strategy;
282 | const GooglePlusTokenStrategy = require('passport-google-plus-token');
283 | const FacebookTokenStrategy = require('passport-facebook-token');
284 | const config = require('./configuration');
285 | const User = require('./models/user');
286 |
287 | // JSON WEB TOKENS STRATEGY
288 | passport.use(new JwtStrategy({
289 | jwtFromRequest: ExtractJwt.fromHeader('authorization'),
290 | secretOrKey: config.JWT_SECRET
291 | }, async (payload, done) => {
292 | try {
293 | // Find the user specified in token
294 | const user = await User.findById(payload.sub);
295 |
296 | // If user doesn't exists, handle it
297 | Iif (!user) {
298 | return done(null, false);
299 | }
300 |
301 | // Otherwise, return the user
302 | done(null, user);
303 | } catch(error) {
304 | done(error, false);
305 | }
306 | }));
307 |
308 | // Google OAuth Strategy
309 | passport.use('googleToken', new GooglePlusTokenStrategy({
310 | clientID: config.oauth.google.clientID,
311 | clientSecret: config.oauth.google.clientSecret
312 | }, async (accessToken, refreshToken, profile, done) => {
313 | try {
314 | // Should have full user profile over here
315 | console.log('profile', profile);
316 | console.log('accessToken', accessToken);
317 | console.log('refreshToken', refreshToken);
318 |
319 | const existingUser = await User.findOne({ "google.id": profile.id });
320 | if (existingUser) {
321 | return done(null, existingUser);
322 | }
323 |
324 | const newUser = new User({
325 | method: 'google',
326 | google: {
327 | id: profile.id,
328 | email: profile.emails[0].value
329 | }
330 | });
331 |
332 | await newUser.save();
333 | done(null, newUser);
334 | } catch(error) {
335 | done(error, false, error.message);
336 | }
337 | }));
338 |
339 | passport.use('facebookToken', new FacebookTokenStrategy({
340 | clientID: config.oauth.facebook.clientID,
341 | clientSecret: config.oauth.facebook.clientSecret
342 | }, async (accessToken, refreshToken, profile, done) => {
343 | try {
344 | console.log('profile', profile);
345 | console.log('accessToken', accessToken);
346 | console.log('refreshToken', refreshToken);
347 |
348 | const existingUser = await User.findOne({ "facebook.id": profile.id });
349 | if (existingUser) {
350 | return done(null, existingUser);
351 | }
352 |
353 | const newUser = new User({
354 | method: 'facebook',
355 | facebook: {
356 | id: profile.id,
357 | email: profile.emails[0].value
358 | }
359 | });
360 |
361 | await newUser.save();
362 | done(null, newUser);
363 | } catch(error) {
364 | done(error, false, error.message);
365 | }
366 | }));
367 |
368 | // LOCAL STRATEGY
369 | passport.use(new LocalStrategy({
370 | usernameField: 'email'
371 | }, async (email, password, done) => {
372 | try {
373 | // Find the user given the email
374 | const user = await User.findOne({ "local.email": email });
375 |
376 | // If not, handle it
377 | Iif (!user) {
378 | return done(null, false);
379 | }
380 |
381 | // Check if the password is correct
382 | const isMatch = await user.isValidPassword(password);
383 |
384 | // If not, handle it
385 | Iif (!isMatch) {
386 | return done(null, false);
387 | }
388 |
389 | // Otherwise, return the user
390 | done(null, user);
391 | } catch(error) {
392 | done(error, false);
393 | }
394 | })); |