From b8125aa31eb5bccd8ebd9701b6360cdaf0cbbcc7 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 15:10:53 -0600 Subject: [PATCH 01/16] ref: server.ts to include port number in console log --- api/src/server.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/server.ts b/api/src/server.ts index cd7a639..09df5d9 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -16,4 +16,6 @@ app.use("/workshop", routes.workshop); connectDB(); -app.listen(process.env.PORT || 8000, () => console.log("Server running...")); +app.listen(process.env.PORT || 8000, () => + console.log(`Server running on port ${process.env.PORT || 8000}`) +); From 60773ed4234239fafb170fc4f401cf9d85289e83 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 15:17:21 -0600 Subject: [PATCH 02/16] fix: server starts from server.ts and uses dev script without typechecking --- api/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/package.json b/api/package.json index a4c2d8f..a3b45e4 100644 --- a/api/package.json +++ b/api/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "tsc", "start": "node src/index.ts", - "dev": "nodemon ./src/server.ts", + "dev": "npx ts-node-dev --respawn --pretty --transpile-only src/server.ts", "test": "echo \"Error: no test specified\" && exit 1", "prettier": "prettier --single-quote --write 'src/**/*.{js,ts}'", "format": "prettier --check ." From 0e531ac0bd5676595970cd84073888eafb16e888 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 15:23:33 -0600 Subject: [PATCH 03/16] package: added auth0 middleware --- api/package-lock.json | 33 +++++++++++++++++++++++++++++++++ api/package.json | 1 + 2 files changed, 34 insertions(+) diff --git a/api/package-lock.json b/api/package-lock.json index 1b26ce5..f470e21 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -12,6 +12,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.21.0", + "express-oauth2-jwt-bearer": "^1.6.0", "mongodb": "^6.9.0", "mongoose": "^8.4.1", "ts-node-dev": "^2.0.0", @@ -608,6 +609,17 @@ "node": ">= 0.10.0" } }, + "node_modules/express-oauth2-jwt-bearer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", + "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", + "dependencies": { + "jose": "^4.13.1" + }, + "engines": { + "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0 || ^20.2.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -883,6 +895,14 @@ "node": ">=0.12.0" } }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/kareem": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", @@ -2248,6 +2268,14 @@ "vary": "~1.1.2" } }, + "express-oauth2-jwt-bearer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", + "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", + "requires": { + "jose": "^4.13.1" + } + }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2436,6 +2464,11 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==" + }, "kareem": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", diff --git a/api/package.json b/api/package.json index a3b45e4..3bc955a 100644 --- a/api/package.json +++ b/api/package.json @@ -18,6 +18,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.21.0", + "express-oauth2-jwt-bearer": "^1.6.0", "mongodb": "^6.9.0", "mongoose": "^8.4.1", "ts-node-dev": "^2.0.0", From 7359344aabb8e42e4d4f127a2cb52c896c5b741a Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 15:36:13 -0600 Subject: [PATCH 04/16] ref: get dotenv config from one central location so that is is accessible throughout app --- api/src/config/db.ts | 2 -- api/src/server.ts | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/config/db.ts b/api/src/config/db.ts index 553460f..24fa884 100644 --- a/api/src/config/db.ts +++ b/api/src/config/db.ts @@ -2,8 +2,6 @@ import mongoose from "mongoose"; import dotenv from "dotenv"; import path from "path"; -dotenv.config({ path: path.resolve(__dirname, "../../.env") }); - // Connect to MongoDB const dbConnect = async () => { try { diff --git a/api/src/server.ts b/api/src/server.ts index 09df5d9..a9c5d8d 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -1,6 +1,10 @@ import express from "express"; import bodyParser from "body-parser"; import connectDB from "./config/db"; +import dotenv from "dotenv"; +import path from "path"; + +dotenv.config({ path: path.resolve(__dirname, "../.env") }); import * as routes from "./routes/index"; From 5cfceaa713f04d8017d23fb2865fade9dd3db0c0 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 17:11:51 -0600 Subject: [PATCH 05/16] fix: remove env file from tracking and store secrets remotely --- app/.env | 1 - app/.env.example | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) delete mode 100644 app/.env create mode 100644 app/.env.example diff --git a/app/.env b/app/.env deleted file mode 100644 index 61fb955..0000000 --- a/app/.env +++ /dev/null @@ -1 +0,0 @@ -REACT_APP_API_URL = http://127.0.0.1:8000 \ No newline at end of file diff --git a/app/.env.example b/app/.env.example new file mode 100644 index 0000000..c53f8e6 --- /dev/null +++ b/app/.env.example @@ -0,0 +1,6 @@ +REACT_APP_API_URL = http://127.0.0.1:8000 + +# auth +REACT_APP_AUTH0_DOMAIN=##check notion## +REACT_APP_AUTH0_CLIENT_ID=##check notion## +REACT_APP_AUTH0_CALLBACK_URL=http://localhost:3000/callback From 6d2a27f2cd3be4df52e1f35c081ead00b2870825 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 17:12:44 -0600 Subject: [PATCH 06/16] packages: added auth0 sdk --- app/package-lock.json | 31 +++++++++++++++++++++++++++++++ app/package.json | 1 + 2 files changed, 32 insertions(+) diff --git a/app/package-lock.json b/app/package-lock.json index 4cb3bea..0eb6ef8 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -8,6 +8,7 @@ "name": "my-app", "version": "0.1.0", "dependencies": { + "@auth0/auth0-react": "^2.2.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -57,6 +58,23 @@ "node": ">=6.0.0" } }, + "node_modules/@auth0/auth0-react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.2.4.tgz", + "integrity": "sha512-l29PQC0WdgkCoOc6WeMAY26gsy/yXJICW0jHfj0nz8rZZphYKrLNqTRWFFCMJY+sagza9tSgB1kG/UvQYgGh9A==", + "dependencies": { + "@auth0/auth0-spa-js": "^2.1.3" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17 || ^18", + "react-dom": "^16.11.0 || ^17 || ^18" + } + }, + "node_modules/@auth0/auth0-spa-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz", + "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==" + }, "node_modules/@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", @@ -18406,6 +18424,19 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "@auth0/auth0-react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.2.4.tgz", + "integrity": "sha512-l29PQC0WdgkCoOc6WeMAY26gsy/yXJICW0jHfj0nz8rZZphYKrLNqTRWFFCMJY+sagza9tSgB1kG/UvQYgGh9A==", + "requires": { + "@auth0/auth0-spa-js": "^2.1.3" + } + }, + "@auth0/auth0-spa-js": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz", + "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ==" + }, "@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", diff --git a/app/package.json b/app/package.json index 1460a5e..5a89bbd 100644 --- a/app/package.json +++ b/app/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@auth0/auth0-react": "^2.2.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", From 2cc131c2b74bc3205898e2d74332b980c3424da3 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 17:16:00 -0600 Subject: [PATCH 07/16] feat: added frontend basic auth0 solution Implements full auth using auth0 on the frontend. Does not include route guards. --- app/src/App.tsx | 7 ++++--- app/src/index.tsx | 13 +++++++++--- app/src/utils/auth0-provider.tsx | 36 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 app/src/utils/auth0-provider.tsx diff --git a/app/src/App.tsx b/app/src/App.tsx index acc3ce2..a44b132 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -4,18 +4,19 @@ import Home from "./pages/Home"; import MentorDashboard from "./pages/MentorDashboard"; import CreateWorkshop from "./pages/CreateWorkshop"; import CreateMeeting from "./pages/CreateMeeting"; +import AuthCallback from "./pages/auth-callback"; + function App(): ReactElement { return (
- } /> } /> } /> } /> } /> - - + } /> +
); } diff --git a/app/src/index.tsx b/app/src/index.tsx index cf4e546..906ae28 100644 --- a/app/src/index.tsx +++ b/app/src/index.tsx @@ -3,14 +3,21 @@ import ReactDOM from "react-dom/client"; import "./styles/main.scss"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; +import { Auth0ProviderWithNavigate } from "./utils/auth0-provider"; +import { BrowserRouter } from "react-router-dom"; +document.title = "PWW"; const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement, + document.getElementById("root") as HTMLElement ); root.render( - - , + + + + + + ); // If you want to start measuring performance in your app, pass a function diff --git a/app/src/utils/auth0-provider.tsx b/app/src/utils/auth0-provider.tsx new file mode 100644 index 0000000..717efe7 --- /dev/null +++ b/app/src/utils/auth0-provider.tsx @@ -0,0 +1,36 @@ +import { Auth0Provider } from "@auth0/auth0-react"; +import React from "react"; +import { useNavigate } from "react-router-dom"; + +export const Auth0ProviderWithNavigate = ({ + children, +}: { + children: React.ReactNode; +}) => { + const navigate = useNavigate(); + + const domain = process.env.REACT_APP_AUTH0_DOMAIN; + const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID; + const redirectUri = process.env.REACT_APP_AUTH0_CALLBACK_URL; + + const onRedirectCallback = (appState: any) => { + navigate(appState?.returnTo || window.location.pathname); + }; + + if (!(domain && clientId && redirectUri)) { + return null; + } + + return ( + + {children} + + ); +}; From 1cbc9335ccee1507f6e54c26512ec677cab83062 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 17:18:50 -0600 Subject: [PATCH 08/16] feat: mock frontend files for testing auth Added files to make it easier to test auth. Files need to be changed for a better UX --- app/src/components/Navbar.tsx | 15 +++++++++ app/src/components/mock-login-button.tsx | 34 +++++++++++++++++++++ app/src/components/mock-logout-button.tsx | 34 +++++++++++++++++++++ app/src/components/mock-sign-up.tsx | 37 +++++++++++++++++++++++ app/src/pages/auth-callback.tsx | 8 +++++ 5 files changed, 128 insertions(+) create mode 100644 app/src/components/mock-login-button.tsx create mode 100644 app/src/components/mock-logout-button.tsx create mode 100644 app/src/components/mock-sign-up.tsx create mode 100644 app/src/pages/auth-callback.tsx diff --git a/app/src/components/Navbar.tsx b/app/src/components/Navbar.tsx index f0f8ef6..6f0d9ec 100644 --- a/app/src/components/Navbar.tsx +++ b/app/src/components/Navbar.tsx @@ -1,8 +1,14 @@ import react, { type ReactElement } from "react"; import { useNavigate } from "react-router-dom"; +import { LoginButton } from "./mock-login-button"; +import { SignupButton } from "./mock-sign-up"; +import { LogoutButton } from "./mock-logout-button"; +import { useAuth0 } from "@auth0/auth0-react"; const Navbar = (): ReactElement => { const navigate = useNavigate(); + const { isAuthenticated } = useAuth0(); + return ( <>
@@ -47,6 +53,15 @@ const Navbar = (): ReactElement => { Create Meeting
+
+ {!isAuthenticated && ( + <> + + + + )} + {isAuthenticated && } +
diff --git a/app/src/components/mock-login-button.tsx b/app/src/components/mock-login-button.tsx new file mode 100644 index 0000000..9be1df9 --- /dev/null +++ b/app/src/components/mock-login-button.tsx @@ -0,0 +1,34 @@ +import { useAuth0 } from "@auth0/auth0-react"; +import React from "react"; + +export const LoginButton = () => { + const { loginWithRedirect } = useAuth0(); + + const handleLogin = async () => { + await loginWithRedirect({ + appState: { + returnTo: "/home", + }, + }); + }; + + return ( + + ); +}; diff --git a/app/src/components/mock-logout-button.tsx b/app/src/components/mock-logout-button.tsx new file mode 100644 index 0000000..37a5400 --- /dev/null +++ b/app/src/components/mock-logout-button.tsx @@ -0,0 +1,34 @@ +import { useAuth0 } from "@auth0/auth0-react"; +import React from "react"; + +export const LogoutButton = () => { + const { logout } = useAuth0(); + + const handleLogout = () => { + logout({ + logoutParams: { + returnTo: window.location.origin, + }, + }); + }; + + return ( + + ); +}; diff --git a/app/src/components/mock-sign-up.tsx b/app/src/components/mock-sign-up.tsx new file mode 100644 index 0000000..59e4560 --- /dev/null +++ b/app/src/components/mock-sign-up.tsx @@ -0,0 +1,37 @@ +import { useAuth0 } from "@auth0/auth0-react"; +import React from "react"; + +export const SignupButton = () => { + const { loginWithRedirect } = useAuth0(); + + const handleSignUp = async () => { + await loginWithRedirect({ + appState: { + returnTo: "/profile", + }, + authorizationParams: { + screen_hint: "signup", + }, + }); + }; + + return ( + + ); +}; diff --git a/app/src/pages/auth-callback.tsx b/app/src/pages/auth-callback.tsx new file mode 100644 index 0000000..d3a4b6f --- /dev/null +++ b/app/src/pages/auth-callback.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import Navbar from "../components/Navbar"; + +const AuthCallback = () => { + return ; +}; + +export default AuthCallback; From 5378afa827bd99aeb11cce2cb4d724ac8f116489 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 17:30:39 -0600 Subject: [PATCH 09/16] lint: configure pretttier for frontend --- api/src/server.ts | 2 +- app/package-lock.json | 24 ++++++++++++++++++++++++ app/package.json | 7 ++++++- app/src/App.tsx | 14 +++++++------- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/api/src/server.ts b/api/src/server.ts index a9c5d8d..b5b7054 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -21,5 +21,5 @@ app.use("/workshop", routes.workshop); connectDB(); app.listen(process.env.PORT || 8000, () => - console.log(`Server running on port ${process.env.PORT || 8000}`) + console.log(`Server running on port ${process.env.PORT || 8000}`), ); diff --git a/app/package-lock.json b/app/package-lock.json index 0eb6ef8..57f4d2c 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -28,6 +28,9 @@ "typescript": "^4.9.5", "web-vitals": "^2.1.4", "yup": "^1.4.0" + }, + "devDependencies": { + "prettier": "^3.3.3" } }, "node_modules/@adobe/css-tools": { @@ -14485,6 +14488,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -28443,6 +28461,12 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, + "prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true + }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", diff --git a/app/package.json b/app/package.json index 5a89bbd..73ea78c 100644 --- a/app/package.json +++ b/app/package.json @@ -28,7 +28,9 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "format": "npx prettier --write \"src/**/*.{js,jsx,ts,tsx}\"", + "format-check": "npx prettier --check \"src/**/*.{js,jsx,ts,tsx}\"" }, "eslintConfig": { "extends": [ @@ -47,5 +49,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "prettier": "^3.3.3" } } diff --git a/app/src/App.tsx b/app/src/App.tsx index a44b132..4321c72 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -9,13 +9,13 @@ import AuthCallback from "./pages/auth-callback"; function App(): ReactElement { return (
- - } /> - } /> - } /> - } /> - } /> - } /> + + } /> + } /> + } /> + } /> + } /> + } />
); From 7378a50049a58f5e1a6951044a4130cb767b6d08 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 17:46:45 -0600 Subject: [PATCH 10/16] vcs: ignore all .env --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e35094d..232fd4d 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +**/**/.env From d0897040f4c08edf29f4c9f4a9eb61af93e7a2cc Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 18:37:13 -0600 Subject: [PATCH 11/16] vcs: add example env file --- api/.env.example | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 api/.env.example diff --git a/api/.env.example b/api/.env.example new file mode 100644 index 0000000..295e10f --- /dev/null +++ b/api/.env.example @@ -0,0 +1,16 @@ +## copy this file and rename it to .env. Fill in the values from Notion + +# server +PORT=8000 + +# email service +SEND_GRID_API_KEY=##check notion## +SEND_GRID_TEST_EMAIL=##check notion## + +# database +MONGO_URI=##check notion## + +# backend auth +CLIENT_ORIGIN_URL=http://localhost:4040 +AUTH0_AUDIENCE=##check notion## +AUTH0_DOMAIN=##check notion## \ No newline at end of file From 7bd479ced631e85423b2ed0a52bf16e5444fc679 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 19:47:51 -0600 Subject: [PATCH 12/16] feat: protect all api endpoints --- api/src/config/db.ts | 2 ++ api/src/controllers/auth0-errors.ts | 35 +++++++++++++++++++++++++ api/src/controllers/auth0-middleware.ts | 21 +++++++++++++++ api/src/controllers/auth0-notFound.ts | 11 ++++++++ api/src/routes/user.ts | 3 +++ api/src/routes/workshop.ts | 11 +++++++- api/src/server.ts | 13 ++++++--- 7 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 api/src/controllers/auth0-errors.ts create mode 100644 api/src/controllers/auth0-middleware.ts create mode 100644 api/src/controllers/auth0-notFound.ts diff --git a/api/src/config/db.ts b/api/src/config/db.ts index 24fa884..553460f 100644 --- a/api/src/config/db.ts +++ b/api/src/config/db.ts @@ -2,6 +2,8 @@ import mongoose from "mongoose"; import dotenv from "dotenv"; import path from "path"; +dotenv.config({ path: path.resolve(__dirname, "../../.env") }); + // Connect to MongoDB const dbConnect = async () => { try { diff --git a/api/src/controllers/auth0-errors.ts b/api/src/controllers/auth0-errors.ts new file mode 100644 index 0000000..eaa874a --- /dev/null +++ b/api/src/controllers/auth0-errors.ts @@ -0,0 +1,35 @@ +import { Request, Response, NextFunction } from "express"; +import { + InvalidTokenError, + UnauthorizedError, +} from "express-oauth2-jwt-bearer"; + +export const errorHandler = ( + error: any, + request: Request, + response: Response, + next: NextFunction +) => { + console.log("Auth Error"); + + if (error instanceof InvalidTokenError) { + const message = "Bad credentials"; + + response.status(error.status).json({ message }); + + return; + } + + if (error instanceof UnauthorizedError) { + const message = "Requires authentication"; + + response.status(error.status).json({ message }); + + return; + } + + const status = 500; + const message = "Internal Server Error"; + + response.status(status).json({ message }); +}; diff --git a/api/src/controllers/auth0-middleware.ts b/api/src/controllers/auth0-middleware.ts new file mode 100644 index 0000000..ed88db0 --- /dev/null +++ b/api/src/controllers/auth0-middleware.ts @@ -0,0 +1,21 @@ +import { auth } from "express-oauth2-jwt-bearer"; +import dotenv from "dotenv"; +import path from "path"; + +dotenv.config({ path: path.resolve(__dirname, "../.env") }); + +const auth0Domain = process.env.AUTH0_DOMAIN; +const auth0Audience = process.env.AUTH0_AUDIENCE; + +try { + if (!auth0Domain || !auth0Audience) { + throw new Error("AUTH0_DOMAIN or AUTH0_AUDIENCE is not set"); + } +} catch (error) { + console.error(error); +} + +export const validateAccessToken = auth({ + issuerBaseURL: `https://${auth0Domain}`, + audience: auth0Audience, +}); diff --git a/api/src/controllers/auth0-notFound.ts b/api/src/controllers/auth0-notFound.ts new file mode 100644 index 0000000..56914e5 --- /dev/null +++ b/api/src/controllers/auth0-notFound.ts @@ -0,0 +1,11 @@ +import { Request, Response, NextFunction } from "express"; + +export const notFoundHandler = ( + request: Request, + response: Response, + next: NextFunction +) => { + const message = "Not Found"; + + response.status(404).json({ message }); +}; diff --git a/api/src/routes/user.ts b/api/src/routes/user.ts index a734b81..1edc571 100644 --- a/api/src/routes/user.ts +++ b/api/src/routes/user.ts @@ -1,9 +1,12 @@ import express from "express"; import mongoose from "mongoose"; import dbConnect from "../config/db"; +import { validateAccessToken } from "../controllers/auth0-middleware"; const router = express.Router(); +router.use(validateAccessToken); + // Call the dbConnect function to connect to MongoDB dbConnect(); diff --git a/api/src/routes/workshop.ts b/api/src/routes/workshop.ts index 4fa779c..57d92a0 100644 --- a/api/src/routes/workshop.ts +++ b/api/src/routes/workshop.ts @@ -1,11 +1,14 @@ import express from "express"; import mongoose from "mongoose"; import dbConnect from "../config/db"; // Import the dbConnect function +import { validateAccessToken } from "../controllers/auth0-middleware"; import { createWorkshop, getWorkshop } from "../controllers/workshopController"; const router = express.Router(); +router.use(validateAccessToken); + // Call the dbConnect function to connect to MongoDB dbConnect(); @@ -48,9 +51,15 @@ router.get( "/workshops/:id", async (req: express.Request, res: express.Response) => { await getWorkshop(req, res); - }, + } ); +router.post("/testId/:id", async (req: any, res: any) => { + res + .status(200) + .json({ message: "Workshop test successful", id: req.params.id }); +}); + // POPULATE VERSION (if details of mentor/mentee objects are needed on the frontend like name or picture) // import express from 'express'; diff --git a/api/src/server.ts b/api/src/server.ts index b5b7054..a7e3b84 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -1,11 +1,13 @@ -import express from "express"; -import bodyParser from "body-parser"; -import connectDB from "./config/db"; import dotenv from "dotenv"; import path from "path"; dotenv.config({ path: path.resolve(__dirname, "../.env") }); +import express from "express"; +import bodyParser from "body-parser"; +import connectDB from "./config/db"; +import { errorHandler } from "./controllers/auth0-errors"; +import { notFoundHandler } from "./controllers/auth0-notFound"; import * as routes from "./routes/index"; var cors = require("cors"); @@ -20,6 +22,9 @@ app.use("/workshop", routes.workshop); connectDB(); +app.use(notFoundHandler); +app.use(errorHandler); + app.listen(process.env.PORT || 8000, () => - console.log(`Server running on port ${process.env.PORT || 8000}`), + console.log(`Server running on port ${process.env.PORT || 8000}`) ); From ce7feb1a41b63e97ad7f174073d14d0adaa3dfb8 Mon Sep 17 00:00:00 2001 From: Lyton Date: Sat, 9 Nov 2024 19:53:12 -0600 Subject: [PATCH 13/16] lint: fixed linting errors --- api/src/controllers/auth0-errors.ts | 2 +- api/src/controllers/auth0-notFound.ts | 2 +- api/src/routes/workshop.ts | 2 +- api/src/server.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/controllers/auth0-errors.ts b/api/src/controllers/auth0-errors.ts index eaa874a..23dcee5 100644 --- a/api/src/controllers/auth0-errors.ts +++ b/api/src/controllers/auth0-errors.ts @@ -8,7 +8,7 @@ export const errorHandler = ( error: any, request: Request, response: Response, - next: NextFunction + next: NextFunction, ) => { console.log("Auth Error"); diff --git a/api/src/controllers/auth0-notFound.ts b/api/src/controllers/auth0-notFound.ts index 56914e5..752e809 100644 --- a/api/src/controllers/auth0-notFound.ts +++ b/api/src/controllers/auth0-notFound.ts @@ -3,7 +3,7 @@ import { Request, Response, NextFunction } from "express"; export const notFoundHandler = ( request: Request, response: Response, - next: NextFunction + next: NextFunction, ) => { const message = "Not Found"; diff --git a/api/src/routes/workshop.ts b/api/src/routes/workshop.ts index 57d92a0..6fba172 100644 --- a/api/src/routes/workshop.ts +++ b/api/src/routes/workshop.ts @@ -51,7 +51,7 @@ router.get( "/workshops/:id", async (req: express.Request, res: express.Response) => { await getWorkshop(req, res); - } + }, ); router.post("/testId/:id", async (req: any, res: any) => { diff --git a/api/src/server.ts b/api/src/server.ts index a7e3b84..2a4ecb9 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -26,5 +26,5 @@ app.use(notFoundHandler); app.use(errorHandler); app.listen(process.env.PORT || 8000, () => - console.log(`Server running on port ${process.env.PORT || 8000}`) + console.log(`Server running on port ${process.env.PORT || 8000}`), ); From ad79fc7beda6e249d399c1b5e2325467d1cf4e3a Mon Sep 17 00:00:00 2001 From: Lyton Date: Mon, 11 Nov 2024 16:34:45 -0600 Subject: [PATCH 14/16] ref: remove token validation from backend --- api/src/routes/user.ts | 15 +++++++++++---- api/src/routes/workshop.ts | 7 ++++--- api/src/server.ts | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/api/src/routes/user.ts b/api/src/routes/user.ts index 1edc571..fc60779 100644 --- a/api/src/routes/user.ts +++ b/api/src/routes/user.ts @@ -1,11 +1,12 @@ import express from "express"; import mongoose from "mongoose"; import dbConnect from "../config/db"; -import { validateAccessToken } from "../controllers/auth0-middleware"; +// import { validateAccessToken } from "../controllers/auth0-middleware"; const router = express.Router(); -router.use(validateAccessToken); +// TODO: Add auth0 middleware +// router.use(validateAccessToken); // Call the dbConnect function to connect to MongoDB dbConnect(); @@ -69,9 +70,15 @@ router.post("/create-user", async (req: any, res: any) => { // Test route to check if the API is working router.post("/test", async (req: any, res: any) => { console.log("Received group data:"); - const { name } = req.body; - return res.status(200).json({ name }); + let name; + if (req.body.name === undefined) { + name = "empty"; + } else { + ({ name } = req.body); + } + + return res.status(200).json(`Your name is ${name}`); }); export default router; diff --git a/api/src/routes/workshop.ts b/api/src/routes/workshop.ts index 6fba172..dade82d 100644 --- a/api/src/routes/workshop.ts +++ b/api/src/routes/workshop.ts @@ -1,13 +1,14 @@ import express from "express"; import mongoose from "mongoose"; import dbConnect from "../config/db"; // Import the dbConnect function -import { validateAccessToken } from "../controllers/auth0-middleware"; +// import { validateAccessToken } from "../controllers/auth0-middleware"; import { createWorkshop, getWorkshop } from "../controllers/workshopController"; const router = express.Router(); -router.use(validateAccessToken); +// TODO: Add auth0 middleware +// router.use(validateAccessToken); // Call the dbConnect function to connect to MongoDB dbConnect(); @@ -51,7 +52,7 @@ router.get( "/workshops/:id", async (req: express.Request, res: express.Response) => { await getWorkshop(req, res); - }, + } ); router.post("/testId/:id", async (req: any, res: any) => { diff --git a/api/src/server.ts b/api/src/server.ts index 2a4ecb9..a7e3b84 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -26,5 +26,5 @@ app.use(notFoundHandler); app.use(errorHandler); app.listen(process.env.PORT || 8000, () => - console.log(`Server running on port ${process.env.PORT || 8000}`), + console.log(`Server running on port ${process.env.PORT || 8000}`) ); From 8d4fd773a18c9b5ae6d9f448b2989b1d51d46979 Mon Sep 17 00:00:00 2001 From: Lyton Date: Mon, 11 Nov 2024 16:42:08 -0600 Subject: [PATCH 15/16] lint: fixed linting errors --- api/src/routes/workshop.ts | 2 +- api/src/server.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/routes/workshop.ts b/api/src/routes/workshop.ts index dade82d..13d47a8 100644 --- a/api/src/routes/workshop.ts +++ b/api/src/routes/workshop.ts @@ -52,7 +52,7 @@ router.get( "/workshops/:id", async (req: express.Request, res: express.Response) => { await getWorkshop(req, res); - } + }, ); router.post("/testId/:id", async (req: any, res: any) => { diff --git a/api/src/server.ts b/api/src/server.ts index a7e3b84..2a4ecb9 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -26,5 +26,5 @@ app.use(notFoundHandler); app.use(errorHandler); app.listen(process.env.PORT || 8000, () => - console.log(`Server running on port ${process.env.PORT || 8000}`) + console.log(`Server running on port ${process.env.PORT || 8000}`), ); From fe25c5ecd96cf50e6a1b9fa2c3df385513f0a5be Mon Sep 17 00:00:00 2001 From: Lyton Date: Mon, 11 Nov 2024 16:46:04 -0600 Subject: [PATCH 16/16] fix: change sign up callback route and remove redundant code --- app/src/App.tsx | 2 +- app/src/components/mock-sign-up.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/App.tsx b/app/src/App.tsx index 4321c72..e225897 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,5 +1,5 @@ import React, { type ReactElement } from "react"; -import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import { Routes, Route } from "react-router-dom"; import Home from "./pages/Home"; import MentorDashboard from "./pages/MentorDashboard"; import CreateWorkshop from "./pages/CreateWorkshop"; diff --git a/app/src/components/mock-sign-up.tsx b/app/src/components/mock-sign-up.tsx index 59e4560..4fdd26e 100644 --- a/app/src/components/mock-sign-up.tsx +++ b/app/src/components/mock-sign-up.tsx @@ -7,7 +7,7 @@ export const SignupButton = () => { const handleSignUp = async () => { await loginWithRedirect({ appState: { - returnTo: "/profile", + returnTo: "/home", }, authorizationParams: { screen_hint: "signup",