diff --git a/.gitignore b/.gitignore index 662c3e1..d0158b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ node_modules -App.css start_in_tmux.sh default.json production.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..d2d380a --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Dev connector +--- +> Web app created with React, Redux, MUI in the front end. Express and mongoose +> on the back end. It also has docker images. + +## Docker Usage: +`docker compose -f docker-compose.yml up` +> The app is available at http://localhost:8080 + +## Run the app locally +Requires running mongodb service. + +In the client directory: +`npm run dev` +In the server directory: +```MONGO_URL=mongodb://the_username:the_password@localhost:3456/the_database JWT_SECRET=mysecrettoken npm run server``` +The app will be available at http://localhost:5173 + diff --git a/client/Dockerfile b/client/Dockerfile index 241b8ef..0f63ab6 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,5 +1,3 @@ -# The first FROM is now a stage called build-stage - FROM node:20 AS build-stage WORKDIR /usr/src/app diff --git a/client/docker-compose.dev.yml b/client/docker-compose.dev.yml deleted file mode 100644 index fd99df5..0000000 --- a/client/docker-compose.dev.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - app: - image: devcon-frontend-dev - build: - context: . # The context will pick this directory as the "build context" - dockerfile: dev.Dockerfile # This will simply tell which dockerfile to read - volumes: - - ./:/usr/src/app # The path can be relative, so ./ is enough to say "the same location as the docker-compose.yml" - ports: - - 5173:3000 - container_name: devcon-front-dev diff --git a/client/docker-compose.yml b/client/docker-compose.yml deleted file mode 100644 index 7ec6812..0000000 --- a/client/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - app: - image: todo-front-dev - build: - context: . # The context will pick this directory as the "build context" - dockerfile: dev.Dockerfile # This will simply tell which dockerfile to read - volumes: - - ./:/usr/src/app # The path can be relative, so ./ is enough to say "the same location as the docker-compose.yml" - ports: - - 5173:5173 - container_name: todo-front diff --git a/docker-compose.dev.yml b/dev.docker-compose.yml similarity index 85% rename from docker-compose.dev.yml rename to dev.docker-compose.yml index 5777984..10c5627 100644 --- a/docker-compose.dev.yml +++ b/dev.docker-compose.yml @@ -1,9 +1,9 @@ services: app: - image: devcon-frontend-dev + image: devcon-frontend build: context: ./client - dockerfile: ./dev.Dockerfile + dockerfile: ./Dockerfile ports: - 5173:5173 environment: @@ -12,10 +12,10 @@ services: - ./client:/usr/src/app server: - image: devcon-backend-dev + image: devcon-backend build: context: ./server - dockerfile: ./dev.Dockerfile + dockerfile: ./Dockerfile ports: - 5000:5000 volumes: diff --git a/docker-compose.yml b/docker-compose.yml index 713a49e..1ecb5d1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,19 +1,21 @@ services: app: - image: devcon-frontend-dev + image: devcon-frontend build: context: ./client - dockerfile: ./dev.Dockerfile + dockerfile: ./Dockerfile ports: - - 3000:3000 + - 8080:80 + environment: + VITE_BACKEND_URL: http://server:5000 volumes: - ./client:/usr/src/app server: - image: devcon-backend-dev + image: devcon-backend build: context: ./server - dockerfile: ./dev.Dockerfile + dockerfile: ./Dockerfile ports: - 5000:5000 volumes: diff --git a/server/Dockerfile b/server/Dockerfile index 4fd30f6..49d27c2 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,15 +1,13 @@ FROM node:20 - -WORKDIR /usr/src/app +WORKDIR /usr/src/app COPY --chown=node:node . . RUN npm ci ENV DEBUG=express:* - USER node -CMD npm start +CMD npm start diff --git a/server/dev.Dockerfile b/server/dev.Dockerfile index 3cae3db..6e10c7f 100644 --- a/server/dev.Dockerfile +++ b/server/dev.Dockerfile @@ -1,5 +1,5 @@ FROM node:20 - + WORKDIR /usr/src/app COPY --chown=node:node . . @@ -10,4 +10,4 @@ ENV DEBUG=express:* USER node -CMD npm start server +CMD npm run server diff --git a/server/docker-compose.dev.yml b/server/docker-compose.dev.yml deleted file mode 100644 index 9b9065a..0000000 --- a/server/docker-compose.dev.yml +++ /dev/null @@ -1,25 +0,0 @@ -services: - mongo: - image: mongo - ports: - - 3456:27017 - environment: - MONGO_INITDB_ROOT_USERNAME: root - MONGO_INITDB_ROOT_PASSWORD: example - MONGO_INITDB_DATABASE: the_database - volumes: - - ../mongo/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js - - mongo_data:/data/db - server: # The name of the service, can be anything - image: devcon-backend-dev # Declares which image to use - build: . # Declares where to build if image is not found - ports: # Declares the ports to publish - - 5000:5000 - volumes: - - ./.:/usr/src/app - environment: - MONGO_URL: "mongodb://the_username:the_password@mongo:27017/the_database" - - -volumes: - mongo_data: diff --git a/server/docker-compose.yml b/server/docker-compose.yml deleted file mode 100644 index 878b41a..0000000 --- a/server/docker-compose.yml +++ /dev/null @@ -1,20 +0,0 @@ -services: - app: # The name of the service, can be anything - image: devcon-backend # Declares which image to use - build: . # Declares where to build if image is not found - ports: # Declares the ports to publish - - 3000:3000 - mongo: - image: mongo - ports: - - 3456:27017 - environment: - MONGO_INITDB_ROOT_USERNAME: root - MONGO_INITDB_ROOT_PASSWORD: example - MONGO_INITDB_DATABASE: the_database - volumes: - - ./mongo/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js - - mongo_data:/data/db - -volumes: - mongo_data: diff --git a/server/package.json b/server/package.json index 593135a..445bcc9 100644 --- a/server/package.json +++ b/server/package.json @@ -5,9 +5,7 @@ "main": "server.ts", "scripts": { "start": "ts-node server.ts", - "server": "ts-node-dev server.ts", - "client": "npm start --prefix client --trace-depracation", - "dev": "concurrently \"npm run server\" \"npm run client\"" + "server": "ts-node-dev server.ts" }, "author": "", "license": "ISC", diff --git a/server/routers/api/auth.ts b/server/routers/api/auth.ts index dda785b..6afda3e 100755 --- a/server/routers/api/auth.ts +++ b/server/routers/api/auth.ts @@ -1,14 +1,14 @@ -import express from 'express' -import bcrypt from 'bcryptjs' -import jwt from 'jsonwebtoken'; +import express from "express"; +import bcrypt from "bcryptjs"; +import jwt from "jsonwebtoken"; -import auth from '../../middleware/auth' -import config from 'config' +import auth from "../../middleware/auth"; +import config from "config"; import { check, validationResult } from "express-validator"; -import User from '../../models/User' -import type { Request, Response } from 'express'; -import { isUserId } from '../../utils'; +import User from "../../models/User"; +import type { Request, Response } from "express"; +import { isUserId } from "../../utils"; const router = express.Router(); // @route GET api/auth @@ -16,19 +16,16 @@ const router = express.Router(); // @access Private router.get("/", auth, async (req: any, res) => { try { - let user: unknown = null + let user: unknown = null; if (isUserId(req)) { user = await User.findById(req.user.id).select("-password"); res.json(user); - } - else { - throw new Error('missing id in request') + } else { + throw new Error("missing id in request"); } } catch (err: unknown) { - if (typeof err === 'string') - console.error(err) - else if (err instanceof Error) - console.error(err.message); + if (typeof err === "string") console.error(err); + else if (err instanceof Error) console.error(err.message); res.status(500).send("Server Error"); } }); @@ -72,25 +69,23 @@ router.post( id: user.id, }, }; - const jwtSecret = config.get('jwtSecret') - if (typeof jwtSecret === 'string') jwt.sign( - payload, - jwtSecret, - { expiresIn: 360000 }, - (err, token) => { + + const jwtSecret = process.env.JWT_SECRET + ? process.env.JWT_SECRET + : config.get("jwtSecret"); + + if (typeof jwtSecret === "string") + jwt.sign(payload, jwtSecret, { expiresIn: 360000 }, (err, token) => { if (err) throw err; res.json({ token }); - } - ); - else throw new Error('Error signing the jwt token') + }); + else throw new Error("Error signing the jwt token"); } catch (err: unknown) { - if (typeof err === 'string') - console.error(err) - else if (err instanceof Error) - console.error(err.message); + if (typeof err === "string") console.error(err); + else if (err instanceof Error) console.error(err.message); res.status(500).send("Server error"); } - } + }, ); -module.exports = router +module.exports = router; diff --git a/server/routers/api/users.ts b/server/routers/api/users.ts index aec428d..5688cf2 100755 --- a/server/routers/api/users.ts +++ b/server/routers/api/users.ts @@ -8,7 +8,6 @@ import User from "../../models/User"; import normalizeUrl from "normalize-url"; - const router = express.Router(); // @route POST api/users @@ -20,7 +19,7 @@ router.post( check("email", "Please include a valid email").isEmail(), check( "password", - "Please enter a password with 6 or more characters" + "Please enter a password with 6 or more characters", ).isLength({ min: 6 }), async (req, res) => { const errors = validationResult(req); @@ -45,7 +44,7 @@ router.post( r: "pg", d: "mm", }), - { forceHttps: true } + { forceHttps: true }, ); user = new User({ @@ -67,24 +66,21 @@ router.post( }, }; - const jwtSecret = config.get('jwtSecret') - if (typeof jwtSecret === 'string') jwt.sign( - payload, - jwtSecret, - { expiresIn: "5 days" }, - (err, token) => { + const jwtSecret = process.env.JWT_SECRET + ? process.env.JWT_SECRET + : config.get("jwtSecret"); + + if (typeof jwtSecret === "string") + jwt.sign(payload, jwtSecret, { expiresIn: "5 days" }, (err, token) => { if (err) throw err; res.json({ token }); - } - ); + }); } catch (err: unknown) { - if (typeof err === 'string') - console.error(err) - else if (err instanceof Error) - console.error(err.message); + if (typeof err === "string") console.error(err); + else if (err instanceof Error) console.error(err.message); res.status(500).send("Server error"); } - } + }, ); -module.exports = router +module.exports = router; diff --git a/start_in_tmux.sh b/start_in_tmux.sh index f35a9a0..b9844de 100644 --- a/start_in_tmux.sh +++ b/start_in_tmux.sh @@ -3,11 +3,11 @@ # systemctl start mongodb.service sn=devCon -cd ~/devConnectTS/ +cd ~/dev-connect/ tmux new-session -s "$sn" -n etc -d "nvim .; exec zsh" -cd ~/devConnectTS/client +cd ~/dev-connect/client tmux new-window -t "$sn:2" -n "client" "npm run dev" -cd ~/devConnectTS/server +cd ~/dev-connect/server tmux new-window -t "$sn:3" -n "server" "npm run server" tmux select-window -t "$sn:1"