From f7324ffd1b9cde333be45c51fcef337aa433f847 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 13:16:11 -0400 Subject: [PATCH 1/9] Docker set up --- client/src/pages/LandingPage.tsx | 24 ++++++++++++------------ client/webpack.config.js | 16 ++++++++++------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/client/src/pages/LandingPage.tsx b/client/src/pages/LandingPage.tsx index a5479e1..961de71 100644 --- a/client/src/pages/LandingPage.tsx +++ b/client/src/pages/LandingPage.tsx @@ -1,17 +1,17 @@ -import React from 'react'; -import Login from '../components/Login/Login'; +import React from "react"; +import Login from "../components/Login/Login"; const LandingPage: React.FC = () => { - return ( -
-

Code Hammers

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce - scelerisque iaculis libero. -

- -
- ); + return ( +
+

Code Hammers

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce + scelerisque iaculis libero. +

+ +
+ ); }; export default LandingPage; diff --git a/client/webpack.config.js b/client/webpack.config.js index ca782bb..4f8a159 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -7,7 +7,7 @@ module.exports = { output: { path: path.resolve(__dirname, "build"), filename: "bundle.js", - publicPath: '/' + publicPath: "/", }, mode: process.env.NODE_ENV, @@ -19,6 +19,9 @@ module.exports = { }), ], devServer: { + //REQUIRED FOR DOCKER + host: "0.0.0.0", + port: 8080, proxy: { "/api": "http://localhost:3000", }, @@ -28,10 +31,11 @@ module.exports = { historyApiFallback: { rewrites: [ { - from: /^\/app/, to: '/index.html' - } - ] - } + from: /^\/app/, + to: "/index.html", + }, + ], + }, }, module: { rules: [ @@ -57,7 +61,7 @@ module.exports = { { test: /\.(png|jpe?g|gif|webp)$/i, - type: 'asset/resource', + type: "asset/resource", }, ], }, From 253b67ae92ece86f91bbb4da47147e604927b13d Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 13:26:25 -0400 Subject: [PATCH 2/9] Docker setup --- dist/controllers/userController.js | 148 +++++++++++++++++++++-------- dist/index.js | 16 +++- dist/routes/userRoutes.js | 10 +- package.json | 3 +- 4 files changed, 127 insertions(+), 50 deletions(-) diff --git a/dist/controllers/userController.js b/dist/controllers/userController.js index 2d24371..4ae145f 100644 --- a/dist/controllers/userController.js +++ b/dist/controllers/userController.js @@ -12,58 +12,128 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.authUser = exports.registerUser = void 0; -const express_async_handler_1 = __importDefault(require("express-async-handler")); +exports.deleteUserByEmail = exports.getUserById = exports.authUser = exports.registerUser = void 0; const userModel_1 = __importDefault(require("../models/userModel")); const generateToken_1 = __importDefault(require("../utils/generateToken")); -// ENDPOINT POST api/users +// ENDPOINT POST api/users/register // PURPOSE Register a new user // ACCESS Public -const registerUser = (0, express_async_handler_1.default)((req, res, next) => __awaiter(void 0, void 0, void 0, function* () { +const registerUser = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { const { name, email, password } = req.body; - const isValidEmail = email.match(/[\w\d\.]+@[a-z]+\.[\w]+$/gim); - if (!isValidEmail) { - return next(); - } - const userExists = yield userModel_1.default.findOne({ email }); - if (userExists) { - res.status(400).json({ message: "User already exists!" }); - return; - } - const user = yield userModel_1.default.create({ - name, - email, - password, - }); - if (user) { - res.status(201).json({ - _id: user._id, - name: user.name, - email: user.email, - token: (0, generateToken_1.default)(user._id.toString()), + try { + const isValidEmail = email.match(/[\w\d\.]+@[a-z]+\.[\w]+$/gim); + if (!isValidEmail) { + return res.status(400).json("Invalid Email"); + } + const userExists = yield userModel_1.default.findOne({ email }); + if (userExists) { + return res.status(400).json({ message: "User already exists!" }); + } + const user = yield userModel_1.default.create({ + name, + email, + password, }); + if (user) { + res.locals.user = { + _id: user._id, + name: user.name, + email: user.email, + token: (0, generateToken_1.default)(user._id.toString()), + }; + return res.status(201).json(res.locals.user); + } } - else { - res.status(400).json({ message: "Invalid user data!" }); + catch (error) { + console.error("Error during user signup:", error); + return next({ + log: "Express error in createUser Middleware", + status: 503, + message: { err: "An error occurred during sign-up" }, + }); } -})); +}); exports.registerUser = registerUser; // ENDPOINT POST api/users/login // PURPOSE Authenticate User and get token // ACCESS Public -const authUser = (0, express_async_handler_1.default)((req, res, next) => __awaiter(void 0, void 0, void 0, function* () { +const authUser = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { const { email, password } = req.body; - const user = yield userModel_1.default.findOne({ email }); - if (user && (yield user.matchPassword(password))) { - res.json({ - _id: user._id, - name: user.name, - email: user.email, - token: (0, generateToken_1.default)(user._id.toString()), - }); + const isValidEmail = email.match(/[\w\d\.]+@[a-z]+\.[\w]+$/gim); + if (!isValidEmail) { + return res.status(400).json({ msg: "Please enter a valid email" }); //TODO Move to global error handler } - else { - res.status(400).json({ message: "Invalid email or password!" }); + if (!email || !password) { + return res.status(400).json({ msg: "Email and password are required!" }); //TODO Move to global error handler } -})); + try { + const user = yield userModel_1.default.findOne({ email }); + if (!user) { + return res.status(401).json({ msg: "User not found!" }); //TODO Move to global error handler + } + if (user && (yield user.matchPassword(password))) { + res.locals.user = { + _id: user._id, + name: user.name, + email: user.email, + token: (0, generateToken_1.default)(user._id.toString()), + }; + return res.status(200).json(res.locals.user); + } + else { + return res.status(401).json({ msg: "Incorrect password" }); //TODO Move to global error handler + } + } + catch (error) { + console.error("Error during user authentication:", error); + return next({ + log: "Express error in createUser Middleware", + status: 503, + message: { err: "An error occurred during login" }, + }); + } +}); exports.authUser = authUser; +// ENDPOINT GET api/users/:userId +// PURPOSE Get user by id +// ACCESS Private +const getUserById = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { + const { userId } = req.params; + try { + const user = yield userModel_1.default.findOne({ _id: userId }); + if (!user) { + return res.status(401).json({ msg: "User not found!" }); //TODO Move to global error handler + } + res.locals.user = user; + return res.status(200).json(res.locals.user); + } + catch (error) { + return next({ + log: "Express error in getUserById Middleware", + status: 500, + message: { err: "An error occurred during retrieval" }, + }); + } +}); +exports.getUserById = getUserById; +// ENDPOINT DELETE api/users/:email +// PURPOSE Delete user by email +// ACCESS Private +const deleteUserByEmail = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { + const { email } = req.params; + try { + const user = yield userModel_1.default.findOneAndRemove({ email }); + if (!user) { + return res.status(404).json({ msg: "User not found!" }); //TODO Move to global error handler + } + return res.status(200).json({ msg: "User successfully deleted!" }); + } + catch (error) { + return next({ + log: "Express error in getUserByEmail Middleware", + status: 500, + message: { err: "An error occurred during removal" }, + }); + } +}); +exports.deleteUserByEmail = deleteUserByEmail; diff --git a/dist/index.js b/dist/index.js index 68494f2..798c489 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3,12 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.startServer = void 0; const path_1 = __importDefault(require("path")); const express_1 = __importDefault(require("express")); const userRoutes_1 = __importDefault(require("./routes/userRoutes")); const db_1 = __importDefault(require("./config/db")); -const errorMIddleware_1 = require("./middleware/errorMIddleware"); const dotenv_1 = __importDefault(require("dotenv")); +const errorControllers_1 = require("./controllers/errorControllers"); dotenv_1.default.config(); const app = (0, express_1.default)(); app.use(express_1.default.json()); @@ -23,7 +24,14 @@ else { res.json({ message: "API Running - Hazzah!" }); }); } -app.use(errorMIddleware_1.notFound); -app.use(errorMIddleware_1.errorHandler); +app.use(errorControllers_1.notFound); +app.use(errorControllers_1.errorHandler); const PORT = Number(process.env.PORT) || 3000; -app.listen(PORT, () => console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`)); +const startServer = () => { + return app.listen(PORT, () => console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`)); +}; +exports.startServer = startServer; +if (require.main === module) { + (0, exports.startServer)(); +} +exports.default = app; diff --git a/dist/routes/userRoutes.js b/dist/routes/userRoutes.js index 6ab275b..e6c76d4 100644 --- a/dist/routes/userRoutes.js +++ b/dist/routes/userRoutes.js @@ -6,10 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const userController_1 = require("../controllers/userController"); const router = express_1.default.Router(); -router.post('/login', userController_1.authUser, (res) => { - return res.status(200).json({ msg: "Successful login!" }); -}); -router.post('/', userController_1.registerUser, (res) => { - return res.status(200).json({ msg: "Successful register!" }); -}); +router.post("/login", userController_1.authUser); +router.post("/register", userController_1.registerUser); +router.delete("/:email", userController_1.deleteUserByEmail); +router.get("/:userId", userController_1.getUserById); exports.default = router; diff --git a/package.json b/package.json index e83b77a..3ac7465 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "A social platform for Codesmith Alumni to continue mentoring and learning together.", "main": "/dist/index.js", - "scripts": { + "scripts": { "build": "tsc", "test": "jest --detectOpenHandles --coverage", "client": "cd client && npm start", @@ -11,6 +11,7 @@ "server-ts": "ts-node-dev server/index.ts", "dev-ts": "concurrently --kill-others \"npm run server-ts\" \"npm run client\"", "dev": "concurrently --kill-others \"npm run server\" \"npm run client\"", + "docker-dev": "docker-compose -f docker-compose-dev.yml up", "test:client": "cd client && npm test", "test:all": "concurrently \"npm test\" \"npm run test:client\"" }, From aa46ddc383a54f448795286d2423271401a3dc87 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 13:27:15 -0400 Subject: [PATCH 3/9] Docker Setup --- .dockerignore | 2 ++ Dockerfile | 30 ++++++++++++++++++++++++++++++ Dockerfile-dev | 21 +++++++++++++++++++++ docker-compose-dev.yml | 17 +++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 Dockerfile-dev create mode 100644 docker-compose-dev.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..93f1361 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +node_modules +npm-debug.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..de77517 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +#SET NODE VERSION +FROM node:18.17.1 as builder + +#CONTAINER WORKING DIRECTORY +WORKDIR /usr/src/app + +#COPY FILES INTO CONTAINER AT /usr/src/app +COPY . . + +#INSTALL ROOT PACKAGES +RUN npm install + +#INSTALL CLIENT PACKAGES +RUN cd client && npm install && npm run build + +#SERVE BUILT FILES +FROM node:18.17.1 + +#SET WORKING DIRECTORY +WORKDIR /usr/src/app + +#COPY FROM BUILDER STAGE +COPY --from=builder /usr/src/app/client/build ./client/build +COPY --from=builder /usr/src/app/node_modules ./node_modules + +#EXPOSE PORT +EXPOSE 80 + +#DEFAULT CMD TO SERVE BUILT FILES +CMD ["npx", "serve", "-s", "client/build", "-l", "80"] diff --git a/Dockerfile-dev b/Dockerfile-dev new file mode 100644 index 0000000..9b9493f --- /dev/null +++ b/Dockerfile-dev @@ -0,0 +1,21 @@ +#SET NODE VERSION +FROM node:18.17.1 + +#CONTAINER WORKING DIRECTORY +WORKDIR /usr/src/app + +#COPY FILES INTO CONTANER AT /usr/src/app +COPY . . + +#TYING TO EXPLICITLY COPY THE CLIENT FOLDER +COPY ./client /usr/src/app/client + +#INSTALL ROOT PACKAGES +RUN npm install + +#INSTAL CLIENT PACKAGES +RUN cd client && npm install + +#EXPOSE THE WEBPACK-DEV-SERVER PORT +EXPOSE 3000 + diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000..144f7ca --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,17 @@ +version: "3" +services: + dev: + image: codehammers/mm-dev + container_name: mm-ch-dev + ports: + - "8080:8080" + volumes: + - .:/usr/src/app + - node_modules:/usr/src/app/node_modules + - client_node_modules:/usr/src/app/client/node_modules + command: npm run dev-ts + environment: + - NODE_ENV=development +volumes: + node_modules: + client_node_modules: From 6b4f7848251f912ad543a10994ed362a7d4e1fa3 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 13:48:15 -0400 Subject: [PATCH 4/9] docker-dev script fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3ac7465..15fc2db 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "server-ts": "ts-node-dev server/index.ts", "dev-ts": "concurrently --kill-others \"npm run server-ts\" \"npm run client\"", "dev": "concurrently --kill-others \"npm run server\" \"npm run client\"", - "docker-dev": "docker-compose -f docker-compose-dev.yml up", + "docker-dev": "docker-compose -f docker-compose-dev.yml up --build", "test:client": "cd client && npm test", "test:all": "concurrently \"npm test\" \"npm run test:client\"" }, From d5ff984ea82310827cdb1e895c44e2be5cbf1f33 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 14:07:50 -0400 Subject: [PATCH 5/9] build context added to yaml file --- docker-compose-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 144f7ca..526db61 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,6 +1,7 @@ version: "3" services: dev: + build: . image: codehammers/mm-dev container_name: mm-ch-dev ports: From fa8d78b758b5bac1791151fc3c8fc3a7f8195268 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 14:24:39 -0400 Subject: [PATCH 6/9] Additional yaml edit to set up explicit build directions for local image --- docker-compose-dev.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 526db61..fa007e2 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,7 +1,9 @@ version: "3" services: dev: - build: . + build: + context: . + dockerfile: Dockerfile-dev image: codehammers/mm-dev container_name: mm-ch-dev ports: From 3c083aacc86838026d9e121d1be7951503f1bd7b Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 24 Sep 2023 16:13:14 -0400 Subject: [PATCH 7/9] further yaml edits to troubleshoot remote pulls --- docker-compose-dev.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index fa007e2..420b064 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,10 +1,7 @@ version: "3" services: dev: - build: - context: . - dockerfile: Dockerfile-dev - image: codehammers/mm-dev + image: brok3turtl3/codehammers:latest-dev container_name: mm-ch-dev ports: - "8080:8080" From 79c12f885c906bd26f8cae3f8c7ebb9d711f8ad2 Mon Sep 17 00:00:00 2001 From: Brok3Turtl3 Date: Sun, 26 Nov 2023 09:58:07 -0500 Subject: [PATCH 8/9] README updated to reflect correct instructions for dev env start up --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 963703e..321229e 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,8 @@ ## dev environment setup - Clone the repo down to your local machine. -- Run **npm i** in the root directory. -- Run **npm i** in the root of the client folder. - Before servers are spun up you will need to run the initial tailwind script. - - In the **client** folder run **npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch** in your terminal. This will run the inital css build. It will also leave it running and provide live compiles for any changes to styling. -- Open a new terminal and in the **root** run **npm run dev-ts**. This will spin up the backend server and a localhost render on 8080. + - In the **client** folder run **npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch** in your terminal. You will be prompted to install Tailwind - Choose YES. This will run the inital css build. It will also leave it running and provide live compiles for any changes to styling. +- Open a new terminal and in the **root** run **npm run docker-dev**. This will spin up the containerized backend server and a localhost render on 8080. You will ned to set up the .env file. This should include **"NODE_ENV=development"** as well as any database connection strings, api keys, seeder phrases as required. - - - From 794c4c80663fc074c055028c27b738268646d920 Mon Sep 17 00:00:00 2001 From: Brok3Turtl3 Date: Sun, 26 Nov 2023 10:51:13 -0500 Subject: [PATCH 9/9] YAML adjusted for dev compose file --- docker-compose-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 420b064..3950632 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -1,7 +1,7 @@ version: "3" services: dev: - image: brok3turtl3/codehammers:latest-dev + image: brok3turtl3/codehammers:latest container_name: mm-ch-dev ports: - "8080:8080"