diff --git a/assetsTransformer.js b/assetsTransformer.js index 5eadded..7f8711f 100644 --- a/assetsTransformer.js +++ b/assetsTransformer.js @@ -2,6 +2,6 @@ const path = require('path'); module.exports = { process(src, filename, config, options) { - return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; + return `module.exports = ${JSON.stringify(path.basename(filename))};`; }, }; diff --git a/client/actions/groups.js b/client/actions/groups.js index d68f1cb..d6220a1 100644 --- a/client/actions/groups.js +++ b/client/actions/groups.js @@ -1,7 +1,7 @@ /* global localStorage */ import axios from 'axios'; import { - LIST_GROUPS, ADD_USER_TO_GROUP, GET_GROUP_USERS, LIST_ALL_USERS, LIST_GROUP } + LIST_GROUPS, ADD_USER_TO_GROUP, GET_GROUP_USERS, LIST_GROUP } from './types'; import attachAuthorizationToken from '../utils/attachAuthorizationToken'; @@ -86,14 +86,28 @@ export const listAllUsers = groupId => dispatch => }); /** - * api call to addMemberToGroup + * api call to joinGroup * @param {object} groupId * @return {object} returns newGroup if the call is successful */ -export const addMemberToGroup = groupId => +export const joinGroup = groupId => dispatch => axios.post(`/api/v1/group/${groupId}/user`) .then((response) => { dispatch(addUser(response.data.newGroup)); }).catch((error) => { throw (error); }); + +/** + * api call to addMemberToGroup + * @param {object} groupId + * @return {object} returns newGroup if the call is successful + */ +export const addMemberToGroup = (groupId, userId) => + dispatch => axios.post(`/api/v1/group/${groupId}/user/${userId}`) + .then((response) => { + dispatch(addUser(response.data.newGroup)); + }).catch((error) => { + throw (error); + }); + diff --git a/client/components/Group/GroupCard.jsx b/client/components/Group/GroupCard.jsx index bbc5b17..c309b56 100644 --- a/client/components/Group/GroupCard.jsx +++ b/client/components/Group/GroupCard.jsx @@ -19,7 +19,7 @@ class GroupCard extends Component { } /* eslint-enable */ render() { - const { groupName, id, joinGroup, listUsers, users } = this.props; + const { groupName, id, joinAGroup, listUsers, users } = this.props; return (
@@ -46,7 +46,7 @@ class GroupCard extends Component { >
  • games -
    +
    Join group
  • @@ -74,7 +74,8 @@ class GroupCard extends Component {
    {users && users.map(user => ( -
    +
    {user.username}
    ))} diff --git a/client/components/Group/GroupChat.jsx b/client/components/Group/GroupChat.jsx index 62f90a5..2bf66c1 100644 --- a/client/components/Group/GroupChat.jsx +++ b/client/components/Group/GroupChat.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; +import { withRouter, Link } from 'react-router-dom'; import MessageCard from './MessageCard'; import { newMessage, getMessages } from '../../actions/messages'; import { getUserGroups, allUserGroups } from '../../actions/users'; @@ -12,7 +12,6 @@ import { getGroup } from '../../actions/groups'; * @extends {React.Component} */ class GroupChat extends React.Component { - /** * Creates an instance of GroupChat. * Binds class methods @@ -39,8 +38,6 @@ class GroupChat extends React.Component { componentDidMount() { $('select').material_select(); const { groupId } = this.props.match.params; - const userid = this.props.access.user.userId; - this.props.allUserGroups(userid); this.props.getMessages(groupId); this.props.getGroup(groupId); } @@ -97,11 +94,17 @@ class GroupChat extends React.Component { this.props.history.push('/homepage/groups'); return null; } + const id = this.props.group.id; return (
    {(this.props.group.groupName || '').toUpperCase()}
    + + add + Add User +
      {this.props.messages.map(message => ( @@ -126,13 +129,16 @@ class GroupChat extends React.Component { onChange={this.onChange} value={this.state.messagePriority} > - + - +
    @@ -149,11 +155,14 @@ const mapStateToProps = (state, ownProps) => { messages: state.messages[groupId] || [], group: state.group[groupId] || {}, userGroups: state.users.usergroups || [], - access: state.access, + access: state.access }; }; export default connect(mapStateToProps, { - newMessage, getMessages, getGroup, getUserGroups, allUserGroups })(withRouter( - GroupChat -)); + newMessage, + getMessages, + getGroup, + getUserGroups, + allUserGroups +})(withRouter(GroupChat)); diff --git a/client/components/Group/ListGroup.jsx b/client/components/Group/ListGroup.jsx index 4956fe6..73bc129 100644 --- a/client/components/Group/ListGroup.jsx +++ b/client/components/Group/ListGroup.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { connect } from 'react-redux'; import { getMessages } from '../../actions/messages'; import { - getGroups, listAllUsers, addMemberToGroup + getGroups, listAllUsers, joinGroup } from '../../actions/groups'; import GroupCard from './GroupCard'; @@ -11,7 +11,7 @@ import GroupCard from './GroupCard'; * @class ListGroup * @extends {React.Component} */ -export class ListGroup extends React.Component { +class ListGroup extends React.Component { /** * Creates an instance of ListGroup. @@ -23,7 +23,7 @@ export class ListGroup extends React.Component { constructor(props) { super(props); this.onClick = this.onClick.bind(this); - this.joinGroup = this.joinGroup.bind(this); + this.joinAGroup = this.joinAGroup.bind(this); this.listUsers = this.listUsers.bind(this); } @@ -48,16 +48,16 @@ export class ListGroup extends React.Component { /** * - * Makes an action call to addMemberToGroup + * Makes an action call to joinGroup * @param {object} event The event of the HTML component * * @memberOf ListGroup */ - joinGroup(event) { + joinAGroup(event) { event.preventDefault(); const id = event.target.id; this.props - .addMemberToGroup(id) + .joinGroup(id) .then(() => { Materialize.toast('Member successfully added', 5000, 'green'); }) @@ -106,7 +106,7 @@ export class ListGroup extends React.Component { key={group.id} id={group.id} onClick={() => this.onClick(group.id)} - joinGroup={this.joinGroup} + joinAGroup={this.joinAGroup} {...group} users={group.users} listUsers={this.listUsers} @@ -132,7 +132,7 @@ const mapStateToProps = state => ({ const actions = { getGroups, getMessages, - addMemberToGroup, + joinGroup, listAllUsers, }; diff --git a/client/components/Group/MessageCard.jsx b/client/components/Group/MessageCard.jsx index 1dcc377..d849a9c 100644 --- a/client/components/Group/MessageCard.jsx +++ b/client/components/Group/MessageCard.jsx @@ -1,5 +1,11 @@ import React from 'react'; +/** + * + * + * @param {any} props + * @returns + */ const MessageCard = (props) => { const date = new Date(props.createdAt); return ( diff --git a/client/components/Group/SearchUser.jsx b/client/components/Group/SearchUser.jsx new file mode 100644 index 0000000..c4de526 --- /dev/null +++ b/client/components/Group/SearchUser.jsx @@ -0,0 +1,229 @@ +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import ReactPaginate from 'react-paginate'; +import { getAllUsers } from '../../actions/users'; +import { addMemberToGroup, getGroups } from '../../actions/groups'; + +/** + * @class SearchPage + * @extends {Component} + */ +class SearchUser extends Component { + /** + * Creates an instance of SearchPage. + * Bind the function handlePageClick to the class. + * @memberOf SearchPage + */ + constructor() { + super(); + this.state = { + users: [], + offset: 0, + pageCount: 0, + limit: 5, + searchParam: '' + }; + this.joinGroup = this.joinGroup.bind(this); + this.handlePageClick = this.handlePageClick.bind(this); + } + + /** + * Makes action call to get all users + * @memberOf SearchPage + */ + + componentWillMount() { + this.props.getGroups(); + this.getUsers(); + } + + /** + * function to get users of the offset, limit and serach param + * @param {int} offset + * @param {int} limit + * @memberOf SearchPage + */ + + getUsers(offset, limit) { + this.props.getAllUsers(offset, limit, this.state.searchParam); + } + + /** + * Update the state if the props are changed + * @param {object} nextProps + * @memberOf SearchPage + */ + componentWillReceiveProps(nextProps) { + this.setState({ + users: nextProps.users.users, + pageCount: nextProps.pagination.pageCount, + count: nextProps.pagination.count + }); + } + /** + * + * Makes an action call to addMemberToGroup + * @param {object} event The event of the HTML component + * + * @memberOf SearchUser + */ + + joinGroup(event) { + event.preventDefault(); + const id = event.target.id; + const groupId = this.props.match.params.groupId; + this.props + .addMemberToGroup(groupId, id) + .then(() => { + Materialize.toast('Member successfully added', 5000, 'green'); + }) + .catch(({ response }) => { + Materialize.toast( + `An error occured: ${response.data.message}`, + 5000, + 'red' + ); + }); + } + + /** + * Sets the event value and default value to the state + * @function searchUsers + * @param {object} event + * @memberOf SearchPage + */ + searchUsers = (event) => { + this.setState({ searchParam: event.target.value, offset: 0, limit: 5 }); + }; + + /** + * Makes an action call to search for a user + * @function onSearch + * @memberOf SearchPage + */ + onSearch = () => { + const limit = 5, + offset = 0; + if (!this.state.searchParam) return; + this.getUsers(offset, limit); + }; + + /** + * Pagination for list of users + * @param {object} data + * @memberOf SearchPage + */ + handlePageClick(data) { + const selected = data.selected; + const limit = 5; + const offset = Math.ceil(selected * limit); + this.setState({ offset }); + this.getUsers(offset, limit).then(() => { + this.setState({ + users: this.props.users.users + }); + }); + } + + /** + * Renders the SearchPage document + * @returns SearchPage + * @memberOf SearchPage + */ + render() { + const { users } = this.state; + const groupid = this.props.match.params.groupId; + return ( +
    + + {' '} + Go Back to Group + +
    +
    +
    +
    +
    +
    + search + + + + Search + +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + {users && + users.map(user => ( + + + + + ))}{' '} + +
    USERNAMEEMAIL
    + + add_box + + {user.username} + {user.email}
    + {this.state.count > 5 && ( + + )} +
    +
    + ); + } +} + +const mapStateToProps = state => ({ + users: state.users, + pagination: state.users.pagination, + groupList: state.group.groupList +}); + +export default connect(mapStateToProps, { + getAllUsers, + addMemberToGroup, + getGroups +})(SearchUser); diff --git a/client/components/Homepage.jsx b/client/components/Homepage.jsx index 2ac066d..e094052 100644 --- a/client/components/Homepage.jsx +++ b/client/components/Homepage.jsx @@ -9,6 +9,7 @@ import UsersPage from '../components/Users/UsersPage'; import UserProfile from '../components/Users/UserProfile'; import Welcomepage from './Welcomepage'; import PageNotFound from './PageNotFound'; +import SearchUser from '../components/Group/SearchUser'; /** @@ -69,6 +70,10 @@ class Homepage extends React.Component { path={`${this.props.match.url}/user-profile`} component={UserProfile} /> +
    diff --git a/client/components/PageNotFound.jsx b/client/components/PageNotFound.jsx index e7e09d4..8d5f6ae 100644 --- a/client/components/PageNotFound.jsx +++ b/client/components/PageNotFound.jsx @@ -3,7 +3,7 @@ import NavigationBar from './NavigationBar'; const PageNotFound = () => (
    - +

    Error 404: Page Not Found

    diff --git a/client/components/SignIn/SignInForm.jsx b/client/components/SignIn/SignInForm.jsx index 6046bbb..d1d0153 100755 --- a/client/components/SignIn/SignInForm.jsx +++ b/client/components/SignIn/SignInForm.jsx @@ -86,6 +86,7 @@ class SignInForm extends React.Component { render() { return (
    +

    LOGIN

    account_circle @@ -124,7 +125,7 @@ class SignInForm extends React.Component { "btn waves-effect waves-light col s6 offset-s3 red lighten-2" name="action" > - Login + Loginsend
    diff --git a/client/components/Signup/SignupForm.jsx b/client/components/Signup/SignupForm.jsx index 09492c7..54ec516 100644 --- a/client/components/Signup/SignupForm.jsx +++ b/client/components/Signup/SignupForm.jsx @@ -90,6 +90,7 @@ class SignupForm extends React.Component { render() { return (
    +

    REGISTER

    account_circle @@ -174,7 +175,7 @@ class SignupForm extends React.Component { type="submit" name="action" > - Register + Registersend
    @@ -185,4 +186,5 @@ const mapStateToProps = state => ({ access: state.access }); -export default connect(mapStateToProps, { userSignupRequest })(withRouter(SignupForm)); +export default connect(mapStateToProps, + { userSignupRequest })(withRouter(SignupForm)); diff --git a/client/components/Users/UserProfile.jsx b/client/components/Users/UserProfile.jsx index 046fd48..0cbd0fb 100644 --- a/client/components/Users/UserProfile.jsx +++ b/client/components/Users/UserProfile.jsx @@ -76,7 +76,8 @@ class UserProfile extends Component { Groups I belong to:{' '} {this.state.groups && this.state.groups.map(group => ( -
    {group.groupName}
    +
    {group.groupName} +
    ))}{' '}
    diff --git a/client/index.html b/client/index.html index 5085be6..9027c06 100755 --- a/client/index.html +++ b/client/index.html @@ -1,21 +1,34 @@ - - - - Post-It - - - - - - - - - - -
    - - + + + + Post-It + + + + + + + + + + + +
    + + + + \ No newline at end of file diff --git a/client/scss/pages/view_group.scss b/client/scss/pages/view_group.scss index c717d56..89da67f 100644 --- a/client/scss/pages/view_group.scss +++ b/client/scss/pages/view_group.scss @@ -1,5 +1,16 @@ body { font-family: 'Open Sans', sans-serif; + display: flex; + min-height: 100vh; + flex-direction: column; +} + +main { + flex: 1 0 auto; +} + +.footer-width { + width: 60% !important ; } a { @@ -10,9 +21,9 @@ nav ul a { font-weight: bolder; } .message-form { - height: 100%; - position: fixed; - width: calc(100% - 300px) !important ; + height: 100%; + position: fixed; + width: calc(100% - 300px) !important; } .message-card { max-width: 600px; @@ -50,16 +61,16 @@ nav ul a { } } .message-box { - max-width: 650px; - margin: 0 auto; - max-height: calc(100% - 340px); - overflow: scroll; - border: none; - - > h5 { + max-width: 650px; + margin: 0 auto; + max-height: calc(100% - 340px); + overflow: scroll; + border: none; + + > h5 { margin: 25px; font-weight: bolder; - } + } } .message-card2 { margin: 20px auto; @@ -86,16 +97,16 @@ nav ul a { } } -.message-holder{ - position: fixed; - right: 0; - bottom: 0; - margin: 0 auto 30px auto; - background: #fff; - width: calc(100% - 300px); - margin-top: 0; - border-top: 1px solid #aaa; - height: 200px; +.message-holder { + position: fixed; + right: 0; + bottom: 0; + margin: 0 auto 30px auto; + background: #fff; + width: calc(100% - 300px); + margin-top: 0; + border-top: 1px solid #aaa; + height: 200px; } .float-right { @@ -125,7 +136,7 @@ nav ul a { } &:hover { - background: rgba(229, 115, 115, 0.08); + background: rgba(229, 115, 115, 0.08); } } @@ -152,10 +163,10 @@ nav ul a { } } .page-button { - margin-top: 50px; - a { - margin-right: 30px; - } + margin-top: 50px; + a { + margin-right: 30px; + } } .forgot-password { margin-top: 20px; @@ -175,7 +186,7 @@ nav ul a { margin-top: 10%; } .collection { - margin-bottom: 100px !important; + margin-bottom: 100px !important; } .profile-image { @@ -183,8 +194,8 @@ nav ul a { text-align: center; } .scroll-group { - overflow: scroll; - border: 3px solid #FFF; - width: 150px; - height: 500px; + overflow: scroll; + border: 3px solid #fff; + width: 150px; + height: 500px; } diff --git a/client/scss/shared/header.scss b/client/scss/shared/header.scss index 71efdd5..089cd1f 100644 --- a/client/scss/shared/header.scss +++ b/client/scss/shared/header.scss @@ -1,5 +1,13 @@ .form-margin { margin-top: 5% !important; + + div { + h3 { + margin-left: 25%; + font-size: 1.92rem; + margin-bottom: 3%; + } + } } @media only screen and (min-width: 769px) { diff --git a/client/test-env.js b/client/test-env.js index 7eadfaa..bc0acce 100644 --- a/client/test-env.js +++ b/client/test-env.js @@ -1,3 +1,5 @@ -import $ from 'jquery'; -global.$ = global.jQuery = $; +global.$ = () => ({ + collapsible: () => null, + material_select: () => null +}); diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..7e824f2 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,47 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/Users/andeladeveloper/.nvm/versions/node/v6.11.2/bin/node', +1 verbose cli '/Users/andeladeveloper/.nvm/versions/node/v6.11.2/bin/npm', +1 verbose cli 'start' ] +2 info using npm@3.10.10 +3 info using node@v6.11.2 +4 verbose run-script [ 'prestart', 'start', 'poststart' ] +5 info lifecycle postit-bootcamp-project@1.0.0~prestart: postit-bootcamp-project@1.0.0 +6 silly lifecycle postit-bootcamp-project@1.0.0~prestart: no script for prestart, continuing +7 info lifecycle postit-bootcamp-project@1.0.0~start: postit-bootcamp-project@1.0.0 +8 verbose lifecycle postit-bootcamp-project@1.0.0~start: unsafe-perm in lifecycle true +9 verbose lifecycle postit-bootcamp-project@1.0.0~start: PATH: /Users/andeladeveloper/.nvm/versions/node/v6.11.2/lib/node_modules/npm/bin/node-gyp-bin:/Users/andeladeveloper/Documents/Projects/PostIt-Bootcamp-Project/node_modules/.bin:/Users/andeladeveloper/.nvm/versions/node/v6.11.2/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin +10 verbose lifecycle postit-bootcamp-project@1.0.0~start: CWD: /Users/andeladeveloper/Documents/Projects/PostIt-Bootcamp-Project +11 silly lifecycle postit-bootcamp-project@1.0.0~start: Args: [ '-c', 'babel-node -- server.js' ] +12 silly lifecycle postit-bootcamp-project@1.0.0~start: Returned: code: 1 signal: null +13 info lifecycle postit-bootcamp-project@1.0.0~start: Failed to exec start script +14 verbose stack Error: postit-bootcamp-project@1.0.0 start: `babel-node -- server.js` +14 verbose stack Exit status 1 +14 verbose stack at EventEmitter. (/Users/andeladeveloper/.nvm/versions/node/v6.11.2/lib/node_modules/npm/lib/utils/lifecycle.js:255:16) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at EventEmitter.emit (events.js:191:7) +14 verbose stack at ChildProcess. (/Users/andeladeveloper/.nvm/versions/node/v6.11.2/lib/node_modules/npm/lib/utils/spawn.js:40:14) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at ChildProcess.emit (events.js:191:7) +14 verbose stack at maybeClose (internal/child_process.js:891:16) +14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) +15 verbose pkgid postit-bootcamp-project@1.0.0 +16 verbose cwd /Users/andeladeveloper/Documents/Projects/PostIt-Bootcamp-Project +17 error Darwin 16.4.0 +18 error argv "/Users/andeladeveloper/.nvm/versions/node/v6.11.2/bin/node" "/Users/andeladeveloper/.nvm/versions/node/v6.11.2/bin/npm" "start" +19 error node v6.11.2 +20 error npm v3.10.10 +21 error code ELIFECYCLE +22 error postit-bootcamp-project@1.0.0 start: `babel-node -- server.js` +22 error Exit status 1 +23 error Failed at the postit-bootcamp-project@1.0.0 start script 'babel-node -- server.js'. +23 error Make sure you have the latest version of node.js and npm installed. +23 error If you do, this is most likely a problem with the postit-bootcamp-project package, +23 error not with npm itself. +23 error Tell the author that this fails on your system: +23 error babel-node -- server.js +23 error You can get information on how to open an issue for this project with: +23 error npm bugs postit-bootcamp-project +23 error Or if that isn't available, you can get their info via: +23 error npm owner ls postit-bootcamp-project +23 error There is likely additional logging output above. +24 verbose exit [ 1, true ] diff --git a/server/controllers/usergroups.js b/server/controllers/usergroups.js index 39932ee..6abe628 100755 --- a/server/controllers/usergroups.js +++ b/server/controllers/usergroups.js @@ -2,24 +2,71 @@ const models = require('../models'); const Usergroups = models.Usergroups; const Groups = models.Groups; +const Users = models.Users; module.exports = { /** * Add user to a group - * Route: POST: /group/:groupid/user + * Route: POST: /group/:groupid/user/:userid * * @param {object} request object * @param {object} response object */ + create(req, res) { const groupId = Number(req.params.groupid); + const userId = Number(req.params.userid); + + Groups.findById(groupId) + .then((foundGroup) => { + // check if user is already in group + Usergroups.findOne({ + where: { + $and: [ + { userId }, + { groupId } + ] + } + }) + .then((foundUserGroup) => { + if (foundUserGroup) { + return res.status(409).send({ message: 'User Already in group' }); + } + }); + // Find username from users model + Users.findById(userId) + .then((user) => { + Usergroups.create({ + groupId: foundGroup.id, + userId: req.params.userid, + username: user.username, + groupName: foundGroup.groupName + }); + }).then(newGroup => res.status(200).send({ + newGroup, + message: 'User successfully added to group' + })); + }).catch(error => res.status(400).send(error)); + }, + + /** + * User Join a group + * Route: POST: /group/:groupid/user + * + * @param {object} request object + * @param {object} response object + */ + + joinGroup(req, res) { + const groupId = Number(req.params.groupid); + const userId = req.decoded.userId; Groups.findById(groupId) .then((foundGroup) => { Usergroups.findOne({ where: { $and: [ - { userId: req.decoded.userId }, + { userId }, { groupId } ] } diff --git a/server/controllers/users.js b/server/controllers/users.js index 9752a26..7960bce 100755 --- a/server/controllers/users.js +++ b/server/controllers/users.js @@ -1,11 +1,10 @@ -const paginate = require('../middleware/paginate'); +import paginate from '../middleware/paginate'; const jwt = require('jsonwebtoken'); const nodemailer = require('nodemailer'); const bcrypt = require('bcrypt'); const models = require('../models'); - require('dotenv').config(); const Users = models.Users; @@ -47,13 +46,11 @@ module.exports = { phoneNumber: newUser.phoneNumber, email: newUser.email }; - return res - .status(200) - .send({ - token, - userInfo, - message: 'Your account has been created' - }); + return res.status(200).send({ + token, + userInfo, + message: 'Your account has been created' + }); }) .catch(error => res.status(400).send({ message: error.message })); } else { @@ -80,8 +77,7 @@ module.exports = { userId: foundUser.id, username: foundUser.username, email: foundUser.email, - phoneNumber: foundUser.phoneNumber, - + phoneNumber: foundUser.phoneNumber }, secret, { expiresIn: '1 day' } @@ -91,7 +87,6 @@ module.exports = { username: foundUser.username, email: foundUser.email, phoneNumber: foundUser.phoneNumber - }; return res.status(200).send({ token, @@ -99,12 +94,10 @@ module.exports = { message: 'You have logged in succesfully' }); } - return res - .status(401) - .send({ - success: false, - message: 'Incorrect username or password' - }); + return res.status(401).send({ + success: false, + message: 'Incorrect username or password' + }); }) .catch(error => res.status(400).send({ message: error.message })); } else { @@ -225,16 +218,20 @@ module.exports = { from: '"POST_IT" ', // sender address to: email, // list of receivers subject: 'Reset Your Password_POSTIT', // Subject line - html: - `
    + html: `
    -
    -
    POST-IT
    +
    + +
    POST-IT
    - Hello ${email}, You are receiving this because you (or someone else) requested to change password.
    Please click on the following link or paste this into your browser to complete: -

    this Link

    + Hello ${email}, You are receiving this because you (or someone else) requested to change password. +
    Please click on the following link or paste this into your browser to complete: +

    this Link

    If you did not request this, please ignore this mail and your password will remain unchanged.

    diff --git a/server/middleware/jwt.js b/server/middleware/jwt.js index 6d297e0..6abe393 100755 --- a/server/middleware/jwt.js +++ b/server/middleware/jwt.js @@ -24,7 +24,7 @@ module.exports = { return res.status(401).send({ message: 'Token authentication failed' }); } req.decoded = decoded; - return next(); + next(); }); } }; diff --git a/server/routes/index.js b/server/routes/index.js index b87db39..19618b7 100755 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -28,11 +28,15 @@ module.exports = (app) => { // api route to add users to group app.post( - '/api/v1/group/:groupid/user', + '/api/v1/group/:groupid/user/:userid', auth.checkToken, usergroupsController.create ); + // api to join a group + app.post('/api/v1/group/:groupid/user', auth.checkToken, + usergroupsController.joinGroup); + // api route to post message to group app.post( '/api/v1/group/:groupid/message',