├── .babelrc
├── .gitignore
├── .idea
├── inspectionProfiles
│ └── Project_Default.xml
├── mac-chat-api.iml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── README.md
├── app.json
├── package.json
└── src
├── config
└── index.js
├── controller
├── account.js
├── channel.js
├── extensions
│ └── userData-ext.js
├── message.js
└── user.js
├── db.js
├── index.js
├── middleware
├── authMiddleware.js
└── index.js
├── model
├── account.js
├── channel.js
├── message.js
└── user.js
└── routes
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "es2015",
4 | "stage-0"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | adminMongo/
2 | dist/
3 | dev/
4 | staging/
5 | logs/
6 | npm-debug.log
7 | node_modules/
8 | .DS_Store
9 | .vscode
10 | dump.tar.gz
11 | dump/
12 | coverage
13 | *.orig
14 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/mac-chat-api.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | true
54 | DEFINITION_ORDER
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
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 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | 1511980547704
118 |
119 |
120 | 1511980547704
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mac-chat-api
2 | Prebuilt api for slack app clone.
3 |
4 | This project is the API for creating a slack clone. No need to understand any of code here. But if you are interested in taking
5 | your development skills to the next level, check out our API course.
6 |
7 | ##### How It Works
8 |
9 | 1. User account creation and login are built-in using passport
10 | * Login at `/v1/account/login`
11 | * Create a new user account at `/v1/account/register`
12 | 2. Ensure that you use the middleware function `authenticated` for each of your new routes on any request that must first have an authenticated user
13 | * Data that you want made to the public (without a user first loggin in) can omit the `authenticated` middleware
14 | 3. Currently the express app assumes the database is on mLab using Heroku Deploy button at bottom. You can change the URL of the Mongo database to any location `src/config/index.js`
15 | 4. For a full review on how this api works, checkout our Mac Course on the [Devslopes platforms](https://devslopes.com/platforms)
16 |
17 | ##### Dependencies
18 | * npm - the `package.json` file lists all of the npm dependencies
19 |
20 | #### Chat App REST API with ES6 and Express.
21 |
22 | - ES6 support via [babel](https://babeljs.io)
23 | - Express is Node.js web application framework via [express](https://github.com/expressjs/express)
24 | - Passport authentication for Node.js via [passport](https://github.com/passport)
25 | - Socket.IO enables real-time bidirectional event-based communication via [socket.io](https://github.com/socketio/socket.io)
26 | - Mongoose is a MongoDB object modeling tool via [mongoose](https://github.com/Automattic/mongoose)
27 | - Body Parsing via [body-parser](https://github.com/expressjs/body-parser)
28 |
29 | Getting Started
30 | ---------------
31 | #### Run a local instance
32 | * Go to `src/config/index.js`
33 | * change port to `"port": 3005`
34 | * change mongoUrl to `"mongoUrl": "mongodb://localhost:27017/chat-api"`
35 | ```sh
36 | # Install dependencies
37 | npm install
38 |
39 | # Start local development live-reload server port 3005:
40 | npm run dev
41 |
42 | # Requests made in the form http://localhost:3005/v1/endpoint
43 |
44 | # To build ES6 code
45 | npm run build
46 |
47 | ```
48 |
49 | #### Run a live online instance
50 | * Go to `src/config/index.js`
51 | * change port to `"port": process.env.PORT`
52 | * change mongoUrl to `"mongoUrl": process.env.MONGODB_URI`
53 |
54 | You can also spin up a free Heroku dyno to test it out:
55 |
56 | [](https://heroku.com/deploy?template=https://github.com/devslopes/mac-chat-api)
57 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Slacky-Slack",
3 | "description": "Prebuilt api for slack app clone.",
4 | "website": "https://github.com/devslopes/mac-chat-api",
5 | "repository": "https://github.com/devslopes/mac-chat-api",
6 | "logo": "https://mlab.com/company/brand/resources/mLab-logo-onlight.png",
7 | "keywords": ["node", "express", "angular", "angular2", "MEAN", "mongodb", "REST", "API"],
8 | "addons": ["mongolab"]
9 | }
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "slacky-slack",
3 | "version": "1.0.0",
4 | "engines": {
5 | "node": "6.10.2"
6 | },
7 | "description": "Prebuilt api for slack app clone.",
8 | "main": "dist",
9 | "scripts": {
10 | "dev": "NODE_ENV=development nodemon -w src --exec \"babel-node src --presets es2015,stage-0\"",
11 | "build": "babel src -s -D -d dist --presets es2015,stage-0",
12 | "prestart": "npm run -s build",
13 | "start": "node ./dist/index.js",
14 | "lint": "eslint src",
15 | "test": "echo \"Error: no test specified\" && exit 1"
16 | },
17 | "eslintConfig": {
18 | "parserOptions": {
19 | "ecmaVersion": 7,
20 | "sourceType": "module"
21 | },
22 | "env": {
23 | "node": true
24 | },
25 | "rules": {
26 | "no-console": 0,
27 | "no-unsed-vars": 1
28 | }
29 | },
30 | "author": "Jacob Luetzow",
31 | "license": "ISC",
32 | "dependencies": {
33 | "body-parser": "1.17.1",
34 | "express": "4.15.2",
35 | "express-jwt": "5.3.0",
36 | "jsonwebtoken": "7.4.0",
37 | "mongoose": "4.9.7",
38 | "passport": "0.3.2",
39 | "passport-local": "1.0.0",
40 | "passport-local-mongoose": "4.0.0",
41 | "babel-cli": "6.24.1",
42 | "babel-core": "6.24.1",
43 | "babel-eslint": "7.2.3",
44 | "babel-preset-es2015": "6.24.1",
45 | "babel-preset-stage-0": "6.24.1",
46 | "socket.io": "2.0.3"
47 | },
48 | "devDependencies": {
49 | "eslint": "3.19.0",
50 | "nodemon": "1.11.0"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | import mongodb from 'mongodb';
2 |
3 | export default {
4 | // "port": 3005,
5 | // "mongoUrl": "mongodb://localhost:27017/chat-api",
6 | "port": process.env.PORT,
7 | "mongoUrl": process.env.MONGODB_URI,
8 | "bodyLimit": "100kb"
9 | }
10 |
--------------------------------------------------------------------------------
/src/controller/account.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import { Router } from 'express';
3 | import bodyParser from 'body-parser';
4 | import passport from 'passport';
5 | import config from '../config';
6 | import Account from '../model/account';
7 | import UserDataExt from './extensions/userData-ext';
8 |
9 | import { generateAccessToken, respond, authenticate } from '../middleware/authMiddleware';
10 |
11 | export default ({ config, db }) => {
12 | let api = Router();
13 |
14 | // '/v1/account/register'
15 | api.post('/register', (req, res) => {
16 | UserDataExt.findUserByEmail(req.body.email, (err, userData) => {
17 | if (err) {
18 | res.status(409).json({ message: `An error occured: ${err.message}`});
19 | } else if (userData) {
20 | res.status(300).json({ message: `Email ${req.body.email} is already registered`});
21 | } else {
22 | Account.register(new Account({ username: req.body.email }), req.body.password, function(err, account) {
23 | if(err) {
24 | res.status(500).json({ message: err });
25 | } else {
26 | passport.authenticate('local', { session: false })(req, res, () => {
27 | res.status(200).send('Successfully created new account');
28 | });
29 | }
30 | });
31 | }
32 | });
33 | });
34 |
35 | // '/v1/account/login'
36 | api.post('/login', (req, res, next) => {
37 | UserDataExt.findUserByEmail(req.body.email, (err, userData) => {
38 | if (err) {
39 | res.status(409).json({ message: `An error occured: ${err.message}`});
40 | } else {
41 | next();
42 | }
43 | });
44 | }, passport.authenticate('local', { session: false, scope: [], failWithError: true }), (err, req, res, next) => {
45 | if (err) {
46 | res.status(401).json({ message: `Email or password invalid, please check your credentials`});
47 | }
48 | }, generateAccessToken, respond);
49 |
50 | // '/v1/account/logout'
51 | api.get('/logout', authenticate, (req, res) => {
52 | res.logout();
53 | res.status(200).send('Successfully logged out');
54 | });
55 |
56 | api.get('/me', authenticate, (req, res) => {
57 | res.status(200).json(req.user);
58 | });
59 |
60 | return api;
61 | }
62 |
--------------------------------------------------------------------------------
/src/controller/channel.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import { Router } from 'express';
3 | import bodyParser from 'body-parser';
4 | import Channel from '../model/channel';
5 |
6 | import { authenticate } from '../middleware/authMiddleware';
7 |
8 | export default({ config, db }) => {
9 | let api = Router();
10 |
11 | //'/v1/channel/add' - Create
12 | api.post('/add', authenticate, (req, res) => {
13 | let newChannel = new Channel();
14 | newChannel.name = req.body.name;
15 | newChannel.description = req.body.description;
16 |
17 | newChannel.save(err => {
18 | if(err){
19 | res.status(500).json({ message: err });
20 | }
21 | res.status(200).json({ message: 'Channel saved successfully' })
22 | });
23 | });
24 |
25 | // '/v1/channel/' - Read
26 | api.get('/', authenticate, (req, res) => {
27 | Channel.find({}, (err, channels) => {
28 | if (err) {
29 | res.status(500).json({ message: err });
30 | }
31 | res.status(200).json(channels);
32 | });
33 | });
34 |
35 | // '/v1/channel/:id' - Read 1
36 | api.get('/:id', authenticate, (req, res) => {
37 | Channel.findById(req.params.id, (err, channel) => {
38 | if (err) {
39 | res.status(500).json({ message: err });
40 | }
41 | res.status(200).json(channel);
42 | });
43 | });
44 |
45 | // '/vq/channel/:id' -Delete
46 | api.delete('/:id', authenticate, (req, res) => {
47 | User.remove({
48 | _id: req.params.id
49 | }, (err, channel) => {
50 | if (err) {
51 | res.status(500).json({ message: err });
52 | }
53 | res.status(200).json({ message: 'Channel Successfully Removed'});
54 | });
55 | });
56 |
57 | return api;
58 | }
59 |
--------------------------------------------------------------------------------
/src/controller/extensions/userData-ext.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import UserData from '../../model/user';
3 |
4 | class UserDataExt {
5 |
6 | static findUserByEmail(email, callback) {
7 | UserData.findOne({ 'email': email }, (err, userData) => {
8 | if (err) {
9 | return callback(err, null);
10 | } else{
11 | return callback(null, userData);
12 | }
13 | });
14 | }
15 | }
16 |
17 | export default UserDataExt;
18 |
--------------------------------------------------------------------------------
/src/controller/message.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import { Router } from 'express';
3 | import bodyParser from 'body-parser';
4 | import Message from '../model/message';
5 |
6 | import { authenticate } from '../middleware/authMiddleware';
7 |
8 | export default({ config, db }) => {
9 | let api = Router();
10 |
11 | // '/v1/message/add' - Create
12 | api.post('/add', authenticate, (req, res) => {
13 | let newMessage = new Message();
14 | newMessage.messageBody = req.body.messageBody;
15 | newMessage.userId = req.body.userId;
16 | newMessage.channelId = req.body.channelId;
17 | newMessage.userName = req.body.userName;
18 | newMessage.userAvatar = req.body.userAvatar;
19 | newMessage.userAvatarColor = req.body.userAvatarColor;
20 |
21 | newMessage.save(err => {
22 | if (err) {
23 | res.status(500).json({ message: err });
24 | }
25 | res.status(200).json({ message: 'Message saved successfully' })
26 | });
27 | });
28 |
29 | // '/v1/message/:id' - Update
30 | api.put('/:id', authenticate, (req, res) => {
31 | Message.findById(req.params.id, (err, message) => {
32 | if (err) {
33 | res.status(500).json({ message: err });
34 | }
35 | message.messageBody = req.body.messageBody;
36 | message.userId = req.body.userId;
37 | message.channelId = req.body.channelId;
38 | newMessage.userName = req.body.userName;
39 | newMessage.userAvatar = req.body.userAvatar;
40 | newMessage.userAvatarColor = req.body.userAvatarColor;
41 |
42 | message.save(err => {
43 | if (err) {
44 | res.status(500).json({ message: err });
45 | }
46 | res.status(200).json({ message: 'Message updated' });
47 | });
48 | });
49 | });
50 |
51 | // '/v1/message/byChannel/:channelId'
52 | api.get('/byChannel/:channelId', authenticate, (req, res) => {
53 | Message
54 | .find({ 'channelId' : req.params.channelId }, (err, messages) => {
55 | if(err) {
56 | res.status(500).json({ message: err });
57 | }
58 | res.status(200).json(messages);
59 | });
60 | });
61 |
62 | // '/vq/message/:id' -Delete
63 | api.delete('/:id', authenticate, (req, res) => {
64 | Message.remove({
65 | _id: req.params.id
66 | }, (err, message) => {
67 | if (err) {
68 | res.status(500).json({ message: err });
69 | }
70 | res.status(200).json({ message: 'Message Successfully Removed'});
71 | });
72 | });
73 |
74 | // '/v1/message/' - Delete all
75 | api.delete('/', authenticate, (req, res) => {
76 | Message.find({}, (err, users) => {
77 | if (err) {
78 | res.status(500).json({ message: err });
79 | }
80 | res.status(200).json({ message: 'Users All Removed'});
81 | });
82 | });
83 |
84 | return api;
85 | }
86 |
--------------------------------------------------------------------------------
/src/controller/user.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import { Router } from 'express';
3 | import bodyParser from 'body-parser';
4 | import User from '../model/user';
5 |
6 | import { authenticate } from '../middleware/authMiddleware';
7 |
8 | export default({ config, db }) => {
9 | let api = Router();
10 |
11 | // '/v1/user/add' - Create
12 | api.post('/add', authenticate, (req, res) => {
13 | let newUser = new User();
14 | newUser.name = req.body.name;
15 | newUser.email = req.body.email;
16 | newUser.avatarName = req.body.avatarName;
17 | newUser.avatarColor = req.body.avatarColor;
18 |
19 | newUser.save(err => {
20 | if (err) {
21 | res.status(500).json({ message: err });
22 | }
23 | res.status(200).json(newUser);
24 | });
25 | });
26 |
27 | // '/v1/user/' - Read
28 | api.get('/', authenticate, (req, res) => {
29 | User.find({}, (err, users) => {
30 | if (err) {
31 | res.status(500).json({ message: err });
32 | }
33 | res.status(200).json(users);
34 | });
35 | });
36 |
37 | // '/v1/user/:id' - Read 1
38 | api.get('/:id', authenticate, (req, res) => {
39 | User.findById(req.params.id, (err, user) => {
40 | if (err) {
41 | res.status(500).json({ message: err });
42 | }
43 | res.status(200).json(user);
44 | });
45 | });
46 |
47 | // '/v1/user/:id' - Update
48 | api.put('/:id', authenticate, (req, res) => {
49 | User.findById(req.params.id, (err, user) => {
50 | if (err) {
51 | res.status(500).json({ message: err });
52 | }
53 | user.name = req.body.name;
54 | user.email = req.body.email;
55 | user.avatarName = req.body.avatarName;
56 | user.avatarColor = req.body.avatarColor;
57 | user.save(err => {
58 | if (err) {
59 | res.status(500).json({ message: err });
60 | }
61 | res.status(200).json({ message: 'User info updated' });
62 | });
63 | });
64 | });
65 |
66 | // 'v1/user/byEmail/:email'
67 | api.get('/byEmail/:email', authenticate, (req, res) => {
68 | User
69 | .findOne({ 'email': req.params.email })
70 | .exec((err, userData) => {
71 | if (err) {
72 | res.status(500).json({ message: err });
73 | }
74 | res.status(200).json(userData);
75 | });
76 | });
77 |
78 | // '/vq/user/:id' -Delete
79 | api.delete('/:id', authenticate, (req, res) => {
80 | User.remove({
81 | _id: req.params.id
82 | }, (err, user) => {
83 | if (err) {
84 | res.status(500).json({ message: err });
85 | }
86 | res.status(200).json({ message: 'User Successfully Removed'});
87 | });
88 | });
89 |
90 | // '/v1/user/' - Delete all
91 | api.delete('/', authenticate, (req, res) => {
92 | User.find({}, (err, users) => {
93 | if (err) {
94 | res.status(500).json({ message: err });
95 | }
96 | res.status(200).json({ message: 'Users All Removed'});
97 | });
98 | });
99 |
100 | return api;
101 | }
102 |
--------------------------------------------------------------------------------
/src/db.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import mongodb from 'mongodb';
3 | import config from './config';
4 |
5 | export default callback => {
6 | let db;
7 | // Connect to the database before starting the application server.
8 | mongoose.connect(config.mongoUrl, function (err, database) {
9 | if (err) {
10 | console.log(err);
11 | process.exit(1);
12 | }
13 | console.log(config.mongoUrl);
14 | // Save database object from the callback for reuse.
15 | db = database;
16 | console.log("Database connection ready");
17 | callback(db);
18 | });
19 | }
20 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import http from 'http';
2 | import express from 'express';
3 | import bodyParser from 'body-parser';
4 | import passport from 'passport';
5 | import socket from 'socket.io';
6 | import Message from './model/message';
7 | import Channel from './model/channel';
8 |
9 | const LocalStrategy = require('passport-local').Strategy;
10 |
11 | import config from './config';
12 | import routes from './routes';
13 |
14 | let app = express();
15 | app.server = http.createServer(app);
16 | let io = socket(app.server);
17 |
18 | //middleware
19 | //parse application/json
20 | app.use(bodyParser.json({
21 | limit: config.bodyLimit
22 | }));
23 |
24 | //passport config
25 | app.use(passport.initialize());
26 | let Account = require('./model/account');
27 | passport.use(new LocalStrategy({
28 | usernameField: 'email',
29 | passwordField: 'password'
30 | },
31 | Account.authenticate()
32 | ));
33 | passport.serializeUser(Account.serializeUser());
34 | passport.deserializeUser(Account.deserializeUser());
35 |
36 | //api routes v1
37 | app.use('/v1', routes);
38 |
39 | // Base URL test endpoint to see if API is running
40 | app.get('/', (req, res) => {
41 | res.json({ message: 'Chat API is ALIVE!' })
42 | });
43 |
44 | /*||||||||||||||||SOCKET|||||||||||||||||||||||*/
45 | //Listen for connection
46 | var typingUsers = {};
47 |
48 | io.on('connection', function(client) {
49 | console.log('a user connected');
50 | //Listens for a new chat message
51 | client.on('newChannel', function(name, description) {
52 | //Create channel
53 | let newChannel = new Channel({
54 | name: name,
55 | description: description,
56 | });
57 | //Save it to database
58 | newChannel.save(function(err, channel){
59 | //Send message to those connected in the room
60 | console.log('new channel created');
61 | io.emit("channelCreated", channel.name, channel.description, channel.id);
62 | });
63 | });
64 |
65 | //Listens for user typing.
66 | client.on("startType", function(userName, channelId){
67 | console.log("User " + userName + " is writing a message...");
68 | typingUsers[userName] = channelId;
69 | io.emit("userTypingUpdate", typingUsers, channelId);
70 | });
71 |
72 | client.on("stopType", function(userName){
73 | console.log("User " + userName + " has stopped writing a message...");
74 | delete typingUsers[userName];
75 | io.emit("userTypingUpdate", typingUsers);
76 | });
77 |
78 | //Listens for a new chat message
79 | client.on('newMessage', function(messageBody, userId, channelId, userName, userAvatar, userAvatarColor) {
80 | //Create message
81 |
82 | console.log(messageBody);
83 |
84 | let newMessage = new Message({
85 | messageBody: messageBody,
86 | userId: userId,
87 | channelId: channelId,
88 | userName: userName,
89 | userAvatar: userAvatar,
90 | userAvatarColor: userAvatarColor
91 | });
92 | //Save it to database
93 | newMessage.save(function(err, msg){
94 | //Send message to those connected in the room
95 | console.log('new message sent');
96 |
97 | io.emit("messageCreated", msg.messageBody, msg.userId, msg.channelId, msg.userName, msg.userAvatar, msg.userAvatarColor, msg.id, msg.timeStamp);
98 | });
99 | });
100 | });
101 | /*||||||||||||||||||||END SOCKETS||||||||||||||||||*/
102 |
103 | app.server.listen(config.port);
104 | console.log(`Started on port ${app.server.address().port}`);
105 |
106 | module.exports = {
107 | app,
108 | io
109 | }
110 |
--------------------------------------------------------------------------------
/src/middleware/authMiddleware.js:
--------------------------------------------------------------------------------
1 | import jwt from 'jsonwebtoken';
2 | import expressJwt from 'express-jwt';
3 |
4 | const TOKENTIME = 60*60*24*90;
5 | const SECRET = "W3 CHAT 4 FUN";
6 |
7 | let authenticate = expressJwt({ secret: SECRET });
8 |
9 | let generateAccessToken = (req, res, next) => {
10 | req.token = req.token || {};
11 | req.token = jwt.sign ({
12 | id: req.user.id,
13 | }, SECRET, {
14 | expiresIn: TOKENTIME // 90 days
15 | });
16 | next();
17 | }
18 |
19 | let respond = (req, res) => {
20 | res.status(200).json({
21 | user: req.user.username,
22 | token: req.token
23 | });
24 | }
25 |
26 | module.exports = {
27 | authenticate,
28 | generateAccessToken,
29 | respond
30 | }
31 |
--------------------------------------------------------------------------------
/src/middleware/index.js:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 |
3 | export default({ config, db }) => {
4 | let api = Router();
5 |
6 | //add middleware
7 |
8 | return api;
9 | }
10 |
--------------------------------------------------------------------------------
/src/model/account.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | const Schema = mongoose.Schema;
3 | import passportLocalMongoose from 'passport-local-mongoose';
4 |
5 | const Account = new Schema({
6 | email: String,
7 | password: String
8 | });
9 |
10 | Account.plugin(passportLocalMongoose);
11 | module.exports = mongoose.model('Account', Account);
12 |
--------------------------------------------------------------------------------
/src/model/channel.js:
--------------------------------------------------------------------------------
1 |
2 | import mongoose from 'mongoose';
3 | const Schema = mongoose.Schema;
4 |
5 | const channelSchema = new Schema({
6 | name: String, default: "",
7 | description: String, default: ""
8 | });
9 |
10 | module.exports = mongoose.model('Channel', channelSchema);
11 |
--------------------------------------------------------------------------------
/src/model/message.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import User from './user';
3 | import Channel from './channel';
4 |
5 | const Schema = mongoose.Schema;
6 | const ObjectId = mongoose.Schema.Types.ObjectId;
7 |
8 | const messageSchema = new Schema({
9 | messageBody: String, default: "",
10 | timeStamp: {type: Date, default: Date.now},
11 | userId: {type: ObjectId, ref: 'User'},
12 | channelId: {type: ObjectId, ref: 'Channel'},
13 | userName: String, default: "",
14 | userAvatar: String, default: "",
15 | userAvatarColor: String, default: ""
16 | });
17 |
18 | module.exports = mongoose.model('Message', messageSchema);
19 |
--------------------------------------------------------------------------------
/src/model/user.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | const Schema = mongoose.Schema;
3 |
4 | const userSchema = new Schema({
5 | name: String, default: "",
6 | email: String, default: "",
7 | avatarName: String, default: "",
8 | avatarColor: String, default: ""
9 | });
10 |
11 | module.exports = mongoose.model('User', userSchema);
12 |
--------------------------------------------------------------------------------
/src/routes/index.js:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import config from '../config';
3 | import middleware from '../middleware';
4 | import initalizeDb from '../db';
5 | import user from '../controller/user';
6 | import account from '../controller/account';
7 | import channel from '../controller/channel';
8 | import message from '../controller/message';
9 |
10 | let router = express();
11 |
12 | //connect to db
13 | initalizeDb(db => {
14 |
15 | //internal middleware
16 | router.use(middleware({ config, db }));
17 |
18 | //api routes v1 (/v1)
19 | router.use('/user', user({ config, db }));
20 | router.use('/account', account({ config, db }));
21 | router.use('/channel', channel({ config, db }));
22 | router.use('/message', message({ config, db }));
23 | });
24 |
25 | export default router;
26 |
--------------------------------------------------------------------------------