diff --git a/.gitignore b/.gitignore index 1fe1b00..6fd37b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea/ node_modules/ +backend/.env diff --git a/backend/.env.template b/backend/.env.template new file mode 100644 index 0000000..8fe39b7 --- /dev/null +++ b/backend/.env.template @@ -0,0 +1,20 @@ +DB_TEST_USER=dev_user +DB_TEST_PASSWORD=dev_password +DB_TEST_NAME=dev_db +DB_TEST_HOST=127.0.0.1 +DB_TEST_PORT=5432 +DB_TEST_DIALECT=postgres + +DB_DEV_USER=dev_user +DB_DEV_PASSWORD=dev_password +DB_DEV_NAME=dev_db +DB_DEV_HOST=127.0.0.1 +DB_DEV_PORT=5432 +DB_DEV_DIALECT=postgres + +DB_PROD_USER=prod_user +DB_PROD_PASSWORD=prod_password +DB_PROD_NAME=prod_db +DB_PROD_HOST=prod-db-server.com +DB_PROD_PORT=5432 +DB_PROD_DIALECT=postgres diff --git a/backend/app.js b/backend/app.js index 8e9ac84..642c87d 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1,6 +1,5 @@ const express = require("express"); const cors = require("cors"); -const bcrypt = require("bcryptjs"); const app = express(); @@ -14,13 +13,7 @@ app.use(express.json()); // parse requests of content-type - application/x-www-form-urlencoded app.use(express.urlencoded({ extended: true })); -// database -const db = require("./models"); -const Role = db.Role; -const User = db.User; -const PitchType = db.PitchType; - -db.sequelize.sync(); +// db.sequelize.sync(); // force: true will drop the table if it already exists // db.sequelize.sync({force: true}).then(() => { // console.log('Drop and Re-sync Database with { force: true }'); @@ -38,33 +31,33 @@ require('./routes/user.routes')(app); require('./routes/pitchType.routes')(app); require('./routes/bullpenSession.routes')(app); -function initial() { - Role.bulkCreate([ - { name: 'user' }, - { name: 'administrator' }, - ]); - User.bulkCreate([ - { firstName: 'Nolan', lastName: 'Ryan', dateOfBirth: new Date(1947, 1, 31), email: 'ryan.nolan@bullpen.com', password: bcrypt.hashSync('nolan', 8) }, - { firstName: 'Sandy', lastName: 'Koufax', dateOfBirth: new Date(1935, 12, 30), email: 'sandy.koufax@bullpen.com', password: bcrypt.hashSync('sandy', 8) }, - { firstName: 'Pedro', lastName: 'Martinez', dateOfBirth: new Date(1971, 10, 25), email: 'pedro.martinez@bullpen.com', password: bcrypt.hashSync('pedro', 8) }, - { firstName: 'randy', lastName: 'johnson', dateOfBirth: new Date(1963, 9, 10), email: 'randy.johnson@bullpen.com', password: bcrypt.hashSync('randy', 8) } - ]); - - User.findAll().then(users => { - users.forEach(user => { - user.setRoles([1]); - }); - }); - - PitchType.bulkCreate([ - { name: 'Fastball', abbreviation: 'FB' }, - { name: 'Curveball', abbreviation: 'CB' }, - { name: 'Slider', abbreviation: 'SL' }, - { name: 'Changeup', abbreviation: 'CH' }, - { name: 'Cutter', abbreviation: 'CUT' }, - { name: 'Sweeper', abbreviation: 'SW' }, - { name: 'Slurve', abbreviation: 'SLV' }, - ]); -} +// function initial() { +// Role.bulkCreate([ +// { name: 'user' }, +// { name: 'administrator' }, +// ]); +// User.bulkCreate([ +// { firstName: 'Nolan', lastName: 'Ryan', dateOfBirth: new Date(1947, 1, 31), email: 'ryan.nolan@bullpen.com', password: bcrypt.hashSync('nolan', 8) }, +// { firstName: 'Sandy', lastName: 'Koufax', dateOfBirth: new Date(1935, 12, 30), email: 'sandy.koufax@bullpen.com', password: bcrypt.hashSync('sandy', 8) }, +// { firstName: 'Pedro', lastName: 'Martinez', dateOfBirth: new Date(1971, 10, 25), email: 'pedro.martinez@bullpen.com', password: bcrypt.hashSync('pedro', 8) }, +// { firstName: 'randy', lastName: 'johnson', dateOfBirth: new Date(1963, 9, 10), email: 'randy.johnson@bullpen.com', password: bcrypt.hashSync('randy', 8) } +// ]); +// +// User.findAll().then(users => { +// users.forEach(user => { +// user.setRoles([1]); +// }); +// }); +// +// PitchType.bulkCreate([ +// { name: 'Fastball', abbreviation: 'FB' }, +// { name: 'Curveball', abbreviation: 'CB' }, +// { name: 'Slider', abbreviation: 'SL' }, +// { name: 'Changeup', abbreviation: 'CH' }, +// { name: 'Cutter', abbreviation: 'CUT' }, +// { name: 'Sweeper', abbreviation: 'SW' }, +// { name: 'Slurve', abbreviation: 'SLV' }, +// ]); +// } module.exports = app; diff --git a/backend/config/config.js b/backend/config/config.js index 987efc7..de5f27d 100644 --- a/backend/config/config.js +++ b/backend/config/config.js @@ -1,38 +1,31 @@ require('dotenv').config(); module.exports = { - development: { - dialect: 'postgres', - username: 'tester', - password: 'test123', - database: 'bullpen', - host: 'localhost', - port: 15432, - logging: false, - }, test: { - dialect: 'postgres', - username: 'test', - password: 'test123!', - database: 'bullpen', - host: 'localhost', - port: 5432, + username: process.env.DB_TEST_USER, + password: process.env.DB_TEST_PASSWORD, + database: process.env.DB_TEST_NAME, + host: process.env.DB_TEST_HOST, + port: process.env.DB_TEST_PORT, + dialect: process.env.DB_TEST_DIALECT, logging: false, }, - staging: { - username: process.env.DB_USER, - password: process.env.DB_PASS, - database: process.env.DB_NAME, - host: process.env.DB_HOST, - dialect: process.env.DB_DIALECT, + development: { + username: process.env.DB_DEV_USER, + password: process.env.DB_DEV_PASSWORD, + database: process.env.DB_DEV_NAME, + host: process.env.DB_DEV_HOST, + port: process.env.DB_DEV_PORT, + dialect: process.env.DB_DEV_DIALECT, logging: false, }, production: { - username: process.env.DB_USER, - password: process.env.DB_PASS, - database: process.env.DB_NAME, - host: process.env.DB_HOST, - dialect: process.env.DB_DIALECT, + username: process.env.DB_PROD_USER, + password: process.env.DB_PROD_PASSWORD, + database: process.env.DB_PROD_NAME, + host: process.env.DB_PROD_HOST, + port: process.env.DB_PROD_PORT, + dialect: process.env.DB_PROD_DIALECT, logging: false, }, }; diff --git a/backend/controllers/auth.controller.js b/backend/controllers/auth.controller.js index 187e80a..eb87937 100644 --- a/backend/controllers/auth.controller.js +++ b/backend/controllers/auth.controller.js @@ -1,6 +1,6 @@ const db = require("../models/index"); const config = require("../config/auth.config"); -const { User: User, Role: Role, RefreshToken: RefreshToken } = db; +const { Auth: Auth, User: User, Role: Role, RefreshToken: RefreshToken } = db; const Op = db.Sequelize.Op; @@ -8,83 +8,90 @@ const jwt = require("jsonwebtoken"); exports.register = (req, res) => { // Save User to Database - User.create({ - firstName: req.body.firstName, - lastName: req.body.lastName, + Auth.create({ email: req.body.email, - dateOfBirth: new Date(req.body.dateOfBirth), password: req.body.password - }) - .then(user => { - if (req.body.roles) { - Role.findAll({ - where: { - name: { - [Op.or]: req.body.roles - } - } - }).then(roles => { - user.setRoles(roles).then(() => { - res.send({ message: "User registered successfully!" }); - }); - }); - } else { - // user role = 1 - user.setRoles([1]).then(() => { - res.send({ message: "User registered successfully!" }); - }, (error) => { - console.log(JSON.stringify(error, null, 2)); - }); + }).then((auth) => { + User.create({ + firstName: req.body.firstName, + lastName: req.body.lastName, + dateOfBirth: new Date(req.body.dateOfBirth), + authId: auth.id, + gender: 'male', + handedness: 'right' + }).then(user => { + if (!req.body.roles || !req.body.roles.length === 0) { + req.body.roles = ['player']; } - }) - .catch(err => { + Role.findAll({ + where: { + name: { + [Op.or]: req.body.roles + } + } + }).then(roles => { + user.setRoles(roles).then(() => { + res.send({ message: "User registered successfully!" }); + }); + }); + }).catch(err => { res.status(500).send({ message: err.message }); }); + }).catch(err => { + res.status(500).send({ message: err.message }); + }); }; exports.login = (req, res) => { - User.findOne({ + Auth.findOne({ where: { email: req.body.email } }) - .then(async (user) => { - if (!user) { + .then(async (auth) => { + if (!auth) { return res.status(404).send({ message: "User Not found." }); } - const passwordIsValid = user.validPassword(req.body.password); - - if (!passwordIsValid) { - return res.status(401).send({ - accessToken: null, - message: "Invalid Password!" - }); - } - - const token = jwt.sign({ id: user.id }, - config.secret, - { - algorithm: 'HS256', - allowInsecureKeySizes: true, - expiresIn: config.jwtExpiration - }); - - let refreshToken = await RefreshToken.createToken(user); - - const authorities = []; - user.getRoles().then(roles => { - for (let i = 0; i < roles.length; i++) { - authorities.push("ROLE_" + roles[i].name.toUpperCase()); + await User.findOne({ + where: { + authId: auth.id } - res.status(200).send({ - id: user.id, - username: user.username, - email: user.email, - roles: authorities, - accessToken: token, - refreshToken: refreshToken + }).then(async (user) => { + const passwordIsValid = auth.validPassword(req.body.password); + + if (!passwordIsValid) { + return res.status(401).send({ + accessToken: null, + message: "Invalid Password!" + }); + } + + const token = jwt.sign({ id: auth.id }, + config.secret, + { + algorithm: 'HS256', + allowInsecureKeySizes: true, + expiresIn: config.jwtExpiration + }); + + let refreshToken = await RefreshToken.createToken(auth); + + const authorities = []; + user.getRoles().then(roles => { + for (let i = 0; i < roles.length; i++) { + authorities.push("ROLE_" + roles[i].name.toUpperCase()); + } + res.status(200).send({ + id: user.id, + email: auth.email, + roles: authorities, + accessToken: token, + refreshToken: refreshToken + }); }); + }).catch(err => { + res.status(500).send({ message: err.message }); }); }) .catch(err => { @@ -92,9 +99,9 @@ exports.login = (req, res) => { }); }; -exports.logout = (req, res) => { - -} +// exports.logout = (req, res) => { +// +// } exports.refreshToken = async (req, res) => { const { refreshToken: requestToken } = req.body; @@ -122,8 +129,7 @@ exports.refreshToken = async (req, res) => { return; } - const user = await refreshToken.getUser(); - let newAccessToken = jwt.sign({ id: user.id }, config.secret, { + let newAccessToken = jwt.sign({ id: auth.id }, config.secret, { expiresIn: config.jwtExpiration, }); diff --git a/backend/middleware/verifySignUp.js b/backend/middleware/verifySignUp.js index df9d6e8..81be6de 100644 --- a/backend/middleware/verifySignUp.js +++ b/backend/middleware/verifySignUp.js @@ -1,14 +1,14 @@ const db = require("../models/index"); -const User = db.User; +const Auth = db.Auth; checkDuplicateUsernameOrEmail = (req, res, next) => { // Username - User.findOne({ + Auth.findOne({ where: { email: req.body.email } - }).then(user => { - if (user) { + }).then(auth => { + if (auth) { res.status(400).send({ message: "Failed! Email is already in use!" }); @@ -21,6 +21,7 @@ checkDuplicateUsernameOrEmail = (req, res, next) => { checkRolesExisted = (req, res, next) => { if (req.body.roles) { + const ROLES = ['player', 'coach', 'admin']; for (let i = 0; i < req.body.roles.length; i++) { if (!ROLES.includes(req.body.roles[i])) { res.status(400).send({ diff --git a/backend/migrations/00-create-auth.js b/backend/migrations/00-create-auth.js new file mode 100644 index 0000000..9825f25 --- /dev/null +++ b/backend/migrations/00-create-auth.js @@ -0,0 +1,34 @@ +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('Authentications', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + email: { + type: Sequelize.STRING, + allowNull: false, + unique: true, + validate: {isEmail: true}, + }, + password: { + type: Sequelize.STRING, + allowNull: false, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + async down(queryInterface, /*Sequelize*/) { + await queryInterface.dropTable('Authentications'); + } +}; diff --git a/backend/migrations/01-create-user.js b/backend/migrations/01-create-user.js index 2e6d7ed..d7a434f 100644 --- a/backend/migrations/01-create-user.js +++ b/backend/migrations/01-create-user.js @@ -1,4 +1,3 @@ -'use strict'; /** @type {import('sequelize-cli').Migration} */ module.exports = { async up(queryInterface, Sequelize) { @@ -9,6 +8,15 @@ module.exports = { primaryKey: true, type: Sequelize.INTEGER }, + authId: { + type: Sequelize.INTEGER, + references: { + model: 'Authentications', + key: 'id' + }, + onUpdate: 'CASCADE', + onDelete: 'CASCADE' + }, firstName: { allowNull: false, type: Sequelize.STRING @@ -17,18 +25,29 @@ module.exports = { allowNull: false, type: Sequelize.STRING }, - email: { - allowNull: false, - type: Sequelize.STRING - }, dateOfBirth: { allowNull: false, type: Sequelize.DATE }, - password: { - allowNull: false, - type: Sequelize.STRING + height: { + type: Sequelize.FLOAT }, + weight: { + type: Sequelize.FLOAT + }, + gender: { + allowNull: false, + type: Sequelize.ENUM('male', 'female', 'other'), + }, + handedness: { + type: Sequelize.ENUM('left', 'right', 'both'), + }, + // position: { + // type: DataTypes.ENUM + // }, + // preferredPosition: { + // type: DataTypes.ENUM + // } createdAt: { allowNull: false, type: Sequelize.DATE @@ -39,7 +58,7 @@ module.exports = { } }); }, - async down(queryInterface, Sequelize) { + async down(queryInterface, /*Sequelize*/) { await queryInterface.dropTable('Users'); } -}; \ No newline at end of file +}; diff --git a/backend/migrations/04-create-refresh-token.js b/backend/migrations/04-create-refresh-token.js index c082ec1..c21067b 100644 --- a/backend/migrations/04-create-refresh-token.js +++ b/backend/migrations/04-create-refresh-token.js @@ -12,10 +12,10 @@ module.exports = { token: { type: Sequelize.STRING }, - userId: { + authId: { type: Sequelize.INTEGER, references: { - model: 'Users', + model: 'Authentications', key: 'id' }, onUpdate: 'CASCADE', @@ -34,7 +34,7 @@ module.exports = { } }); }, - async down(queryInterface, Sequelize) { + async down(queryInterface, /*Sequelize*/) { await queryInterface.dropTable('RefreshTokens'); } }; \ No newline at end of file diff --git a/backend/models/auth.model.js b/backend/models/auth.model.js new file mode 100644 index 0000000..a89fb34 --- /dev/null +++ b/backend/models/auth.model.js @@ -0,0 +1,61 @@ +const { Model } = require('sequelize'); +const bcrypt = require("bcryptjs"); + +module.exports = (sequelize, DataTypes) => { + class Auth extends Model { + /** + * Helper method for defining associations. + * This method is not a part of Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + Auth.hasOne(models.User, { + foreignKey: 'authId', + as: 'user' + }); + Auth.hasMany(models.RefreshToken, { + foreignKey: 'authId', + as: 'tokens' + }); + } + } + + Auth.init({ + email: { + type: DataTypes.STRING, + allowNull: false, + unique: true, + validate: {isEmail: true}, + }, + password: { + type: DataTypes.STRING, + allowNull: false, + }, + }, { + sequelize, + modelName: 'Auth', + tableName: 'Authentications', + timestamps: true, + hooks: { + beforeCreate: async (auth) => { + const salt = await bcrypt.genSalt(10); + auth.password = await bcrypt.hash(auth.password, salt); + } + } + }, { + defaultScope: { + attributes: { exclude: ['password'] }, + }, + scopes: { + withSecretColumns: { + attributes: { include: ['password'] }, + }, + }, + }); + + Auth.prototype.validPassword = function (password) { + return bcrypt.compareSync(password, this.password); + }; + + return Auth; +} diff --git a/backend/models/member.js b/backend/models/member.js deleted file mode 100644 index faea447..0000000 --- a/backend/models/member.js +++ /dev/null @@ -1,52 +0,0 @@ -const { Model } = require('sequelize'); - -module.exports = (sequelize, DataTypes) => { - class Member extends Model { - /** - * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. - * The `models/index` file will call this method automatically. - */ - static associate(models) { - // Member.belongsTo(models.User, { - // foreignKey: 'loginId', - // targetKey: 'id' - // }); - } - } - Member.init({ - firstName: { - type: DataTypes.STRING, - allowNull: false - }, - lastName: { - type: DataTypes.STRING, - allowNull: false - }, - dateOfBirth: { - type: DataTypes.DATE, - allowNull: false - }, - height: { - type: DataTypes.INTEGER - }, - weight: { - type: DataTypes.INTEGER - }, - // handedness: { - // type: DataTypes.ENUM('LeftHandedness', 'RightHandedness'), - // }, - // position: { - // type: DataTypes.ENUM - // }, - // preferredPosition: { - // type: DataTypes.ENUM - // } - }, { - sequelize, - modelName: 'Member', - tableName: "Members" - }); - - return Member; -}; diff --git a/backend/models/refreshToken.model.js b/backend/models/refreshToken.model.js index 691f42c..400560a 100644 --- a/backend/models/refreshToken.model.js +++ b/backend/models/refreshToken.model.js @@ -10,8 +10,8 @@ module.exports = (sequelize, DataTypes) => { * The `models/index` file will call this method automatically. */ static associate(models) { - RefreshToken.belongsTo(models.User, { - foreignKey: 'userId', + RefreshToken.belongsTo(models.Auth, { + foreignKey: 'authId', targetKey: 'id' }); } @@ -31,7 +31,7 @@ module.exports = (sequelize, DataTypes) => { tableName: 'RefreshTokens' }); - RefreshToken.createToken = async function (user) { + RefreshToken.createToken = async function (auth) { let expiredAt = new Date(); expiredAt.setSeconds(expiredAt.getSeconds() + config.jwtRefreshExpiration); @@ -40,7 +40,7 @@ module.exports = (sequelize, DataTypes) => { let refreshToken = await this.create({ token: _token, - userId: user.id, + authId: auth.id, expiryDate: expiredAt.getTime(), }); diff --git a/backend/models/user.model.js b/backend/models/user.model.js index 13dee2a..a43dfd8 100644 --- a/backend/models/user.model.js +++ b/backend/models/user.model.js @@ -1,5 +1,4 @@ const { Model } = require('sequelize'); -const bcrypt = require("bcryptjs"); module.exports = (sequelize, DataTypes) => { class User extends Model { @@ -14,9 +13,9 @@ module.exports = (sequelize, DataTypes) => { foreignKey: 'userId', as: 'roles', }); - User.hasOne(models.RefreshToken, { - foreignKey: 'userId', - targetKey: 'id' + User.belongsTo(models.Auth, { + foreignKey: 'authId', + as: 'auth' }); } } @@ -30,42 +29,33 @@ module.exports = (sequelize, DataTypes) => { allowNull: false }, dateOfBirth: { - type: DataTypes.DATE, + type: DataTypes.DATEONLY, allowNull: false }, - email: { - type: DataTypes.STRING, - allowNull: false, - unique: true + height: { + type: DataTypes.FLOAT }, - password: { - type: DataTypes.STRING, + weight: { + type: DataTypes.FLOAT + }, + gender: { + type: DataTypes.ENUM('male', 'female', 'other'), allowNull: false - } + }, + handedness: { + type: DataTypes.ENUM('left', 'right', 'both'), + }, + // position: { + // type: DataTypes.ENUM + // }, + // preferredPosition: { + // type: DataTypes.ENUM + // } }, { sequelize, modelName: 'User', - tableName: "Users", - hooks: { - beforeCreate: async (user) => { - const salt = await bcrypt.genSalt(10); - user.password = await bcrypt.hash(user.password, salt); - } - } - }, { - defaultScope: { - attributes: { exclude: ['password'] }, - }, - scopes: { - withSecretColumns: { - attributes: { include: ['password'] }, - }, - }, + tableName: "Users" }); - User.prototype.validPassword = function (password) { - return bcrypt.compareSync(password, this.password); - }; - return User; }; diff --git a/backend/seeders/01-roles.js b/backend/seeders/01-roles.js index 0f29b56..ae48291 100644 --- a/backend/seeders/01-roles.js +++ b/backend/seeders/01-roles.js @@ -1,22 +1,14 @@ -'use strict'; - /** @type {import('sequelize-cli').Migration} */ module.exports = { - async up (queryInterface, Sequelize) { - return queryInterface.bulkInsert('Roles', [{ - id: 1, - name: 'user', - createdAt: new Date(), - updatedAt: new Date(), - }, { - id: 2, - name: 'administrator', - createdAt: new Date(), - updatedAt: new Date() - }]); + async up (queryInterface, /*Sequelize*/) { + return queryInterface.bulkInsert('Roles', [ + { name: 'player', createdAt: new Date(), updatedAt: new Date() }, + { name: 'coach', createdAt: new Date(), updatedAt: new Date() }, + { name: 'admin', createdAt: new Date(), updatedAt: new Date() } + ]); }, - async down (queryInterface, Sequelize) { + async down (queryInterface, /*Sequelize*/) { return queryInterface.dropTable('Roles'); } }; diff --git a/backend/seeders/02-users.js b/backend/seeders/02-users.js index 8f7f3e5..0a577f5 100644 --- a/backend/seeders/02-users.js +++ b/backend/seeders/02-users.js @@ -2,19 +2,69 @@ const bcrypt = require("bcryptjs"); /** @type {import('sequelize-cli').Migration} */ module.exports = { - async up (queryInterface, Sequelize) { - return queryInterface.bulkInsert('Users', [{ - firstName: 'Nolan', - lastName: 'Ryan', - dateOfBirth: new Date(1947, 1, 31), - email: 'ryan.nolan@bullpen.com', - password: bcrypt.hashSync('nolan', 8), - createdAt: new Date(), - updatedAt: new Date(), - }]); + async up (queryInterface, /*Sequelize*/) { + await queryInterface.bulkInsert('Authentications', [ + { email: 'player@example.com', password: bcrypt.hashSync('hash1234', 8), createdAt: new Date(), updatedAt: new Date() }, + { email: 'coach@example.com', password: bcrypt.hashSync('hash2345', 8), createdAt: new Date(), updatedAt: new Date() }, + { email: 'admin@example.com', password: bcrypt.hashSync('hash3456', 8), createdAt: new Date(), updatedAt: new Date() }, + ]); + + const auths = await queryInterface.select(null, 'Authentications'); + const playerAuthId = auths.filter((auth) => auth.email === 'player@example.com').map((auth) => auth.id).shift(); + const coachAuthId = auths.filter((auth) => auth.email === 'coach@example.com').map((auth) => auth.id).shift(); + const adminAuthId = auths.filter((auth) => auth.email === 'admin@example.com').map((auth) => auth.id).shift(); + + await queryInterface.bulkInsert('Users', [{ + firstName: 'Alice', + lastName: 'Player', + dateOfBirth: '1990-01-01', + gender: 'female', + handedness: 'right', + authId: playerAuthId, + createdAt: new Date(), + updatedAt: new Date(), + }, { + firstName: 'Bob', + lastName: 'Coach', + dateOfBirth: '1985-05-05', + gender: 'male', + handedness: 'left', + authId: coachAuthId, + createdAt: new Date(), + updatedAt: new Date(), + }, { + firstName: 'Charlie', + lastName: 'Admin', + dateOfBirth: '1980-03-03', + gender: 'other', + handedness: 'both', + authId: adminAuthId, + createdAt: new Date(), + updatedAt: new Date(), + }] + ); + + const users = await queryInterface.select(null, 'Users'); + const aliceId = users.filter((user) => user.firstName === 'Alice').map((user) => user.id).shift(); + const bobId = users.filter((user) => user.firstName === 'Bob').map((user) => user.id).shift(); + const charlieId = users.filter((user) => user.firstName === 'Charlie').map((user) => user.id).shift(); + + const roles = await queryInterface.select(null, 'Roles'); + const playerId = roles.filter((role) => role.name === 'player').map((role) => role.id).shift(); + const coachId = roles.filter((role) => role.name === 'coach').map((role) => role.id).shift(); + const adminId = roles.filter((role) => role.name === 'admin').map((role) => role.id).shift(); + + await queryInterface.bulkInsert('UserRoles', [ + { userId: aliceId, roleId: playerId, createdAt: new Date(), updatedAt: new Date() }, + { userId: bobId, roleId: coachId, createdAt: new Date(), updatedAt: new Date() }, + { userId: charlieId, roleId: adminId, createdAt: new Date(), updatedAt: new Date() }, + ]); + }, - async down (queryInterface, Sequelize) { - return queryInterface.dropTable('Users'); + async down (queryInterface, /*Sequelize*/) { + await queryInterface.dropTable('Authentications'); + await queryInterface.dropTable('Users'); + await queryInterface.dropTable('UserRoles'); } }; diff --git a/backend/test/bullpenSession.test.js b/backend/test/bullpenSession.test.js index 7635f76..797d33e 100644 --- a/backend/test/bullpenSession.test.js +++ b/backend/test/bullpenSession.test.js @@ -14,8 +14,8 @@ describe("Test bullpen session", () => { let response = await request(app) .post("/api/auth/login") .send({ - email: 'ryan.nolan@bullpen.com', - password: 'nolan' + email: 'player@example.com', + password: 'hash1234' }); const user = response.body; @@ -38,6 +38,6 @@ describe("Test bullpen session", () => { .set('x-access-token', user.accessToken); expect(response.statusCode).toBe(200); - console.log(JSON.stringify(response.body, null, 2)); + // console.log(JSON.stringify(response.body, null, 2)); }); }) diff --git a/backend/test/data/user.test.data.js b/backend/test/data/user.test.data.js index f8f723d..9500b61 100644 --- a/backend/test/data/user.test.data.js +++ b/backend/test/data/user.test.data.js @@ -3,7 +3,8 @@ const signupUser = { lastName: "Zimmer", dateOfBirth: "1956-11-23", email: "hans.zimmer@email.com", - password: "secret123" + password: "secret123", + roles: ['admin'] } module.exports = { diff --git a/backend/test/pitchType.test.js b/backend/test/pitchType.test.js index d0a41ee..2282e5e 100644 --- a/backend/test/pitchType.test.js +++ b/backend/test/pitchType.test.js @@ -12,8 +12,8 @@ describe("Test retrieving pitch types", () => { let response = await request(app) .post("/api/auth/login") .send({ - email: 'ryan.nolan@bullpen.com', - password: 'nolan' + email: 'player@example.com', + password: 'hash1234' }); const user = response.body; diff --git a/backend/test/user.test.js b/backend/test/user.test.js index 1881ba4..12e94d7 100644 --- a/backend/test/user.test.js +++ b/backend/test/user.test.js @@ -22,8 +22,8 @@ describe("Test user authentication", () => { let response = await request(app) .post("/api/auth/login") .send({ - email: 'ryan.nolan@bullpen.com', - password: 'nolan' + email: signupUser.email, + password: signupUser.password, }); expect(response.statusCode).toBe(200); expect(response.body.accessToken).not.toBeNull();