diff --git a/7_auth/7_1_express_js/src/app.ts b/7_auth/7_1_express_js/src/app.ts index 48bd6cc..b74a703 100644 --- a/7_auth/7_1_express_js/src/app.ts +++ b/7_auth/7_1_express_js/src/app.ts @@ -1,13 +1,13 @@ import express from "express"; import cookieParser from "cookie-parser"; import { AuthController } from "./controllers/AuthController"; -import {ProtectedController} from "./controllers/ProtectedController"; // Import the RedisController class +import {GitHubController} from "./controllers/GitHubController"; // Import the RedisController class const app = express(); const PORT = 3000; const authController = new AuthController(); -const protectedController = new ProtectedController(); +const protectedController = new GitHubController(); app.use(cookieParser()); app.use(express.json()); @@ -20,8 +20,8 @@ app.get("/callback", (req, res) => authController.callback(req, res) ) -app.get("/protected-remote-call", (req, res) => - protectedController.getSomeResource(req, res) +app.get("/github/repositories", (req, res) => + protectedController.getRepositories(req, res) ) // Start the Express server diff --git a/7_auth/7_1_express_js/src/controllers/GitHubController.ts b/7_auth/7_1_express_js/src/controllers/GitHubController.ts new file mode 100644 index 0000000..4a29e98 --- /dev/null +++ b/7_auth/7_1_express_js/src/controllers/GitHubController.ts @@ -0,0 +1,29 @@ +import { Request, Response } from "express"; +import { authenticate } from "../decorators/AuthDecorator"; +import axios from "axios"; + +const GITHUB_API_URL = "https://api.github.com"; + +export class GitHubController { + @authenticate() + async getRepositories(req: Request, res: Response) { + try { + const user = req.user; + + // Get user info from GitHub using the access token + const repoResponse = await axios.get(`${GITHUB_API_URL}/users/${user?.username}/repos`, { + headers: { Authorization: `Bearer ${user?.ghAccessToken}` }, + }); + + if (user) { + res.send({ + username: user.username, + repositories: repoResponse.data + }); + } + } catch (error) { + console.error("Error in getUsername:", error); + res.status(500).send({ error: "Internal Server Error" }); + } + } +} diff --git a/7_auth/7_1_express_js/src/controllers/ProtectedController.ts b/7_auth/7_1_express_js/src/controllers/ProtectedController.ts deleted file mode 100644 index 0a9a32d..0000000 --- a/7_auth/7_1_express_js/src/controllers/ProtectedController.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Request, Response } from "express"; -import { authenticate } from "../decorators/AuthDecorator"; - -export class ProtectedController { - @authenticate() - async getSomeResource(req: Request, res: Response) { - try { - const user = req.user; - if (user) { - res.send({ - username: user.username, - resource: "💎💰" - }); - } - } catch (error) { - console.error("Error in getUsername:", error); - res.status(500).send({ error: "Internal Server Error" }); - } - } -} diff --git a/7_auth/7_1_express_js/src/decorators/AuthDecorator.ts b/7_auth/7_1_express_js/src/decorators/AuthDecorator.ts index c870bc7..733b361 100644 --- a/7_auth/7_1_express_js/src/decorators/AuthDecorator.ts +++ b/7_auth/7_1_express_js/src/decorators/AuthDecorator.ts @@ -1,4 +1,4 @@ -import { Request, Response, NextFunction } from "express"; +import {NextFunction, Request, Response} from "express"; import jwt from "jsonwebtoken"; import Redis from "ioredis"; @@ -29,18 +29,17 @@ export function authenticate() { } try { - const decoded = jwt.verify(token, JWT_SECRET) as { username: string }; + const principal = jwt.verify(token, JWT_SECRET) as { username: string, ghAccessToken: string }; // Validate token against Redis - const storedToken = await redis.get( - `user:${decoded.username}:app_user_token` - ); + const storedToken = await redis.get(`user:${principal.username}:app_user_token`); if (storedToken !== token) { return res.status(401).send({ error: "Invalid token" }); } + principal.ghAccessToken = await redis.get(`user:${principal.username}:github_access_token`) as string; // Attach user info to the request - req.user = decoded; + req.user = principal; await originalMethod.call(this, req, res, next); // Call the original method } catch (err) { return res.status(403).send({ error: "Invalid or expired token" }); diff --git a/7_auth/7_1_express_js/src/types/express/index.d.ts b/7_auth/7_1_express_js/src/types/express/index.d.ts index 0f8f594..24bcfbe 100644 --- a/7_auth/7_1_express_js/src/types/express/index.d.ts +++ b/7_auth/7_1_express_js/src/types/express/index.d.ts @@ -2,7 +2,10 @@ import { Request } from "express"; declare global { namespace Express { interface Request { - user?: { username: string }; + user?: { + username: string + ghAccessToken: string + }; } } } diff --git a/7_auth/client/src/App.jsx b/7_auth/client/src/App.jsx index 9697edb..3087d85 100644 --- a/7_auth/client/src/App.jsx +++ b/7_auth/client/src/App.jsx @@ -1,29 +1,33 @@ -import './App.css' +import './App.css'; import { useAuth } from "../Context.jsx"; -import {useEffect, useState} from "react"; +import { useEffect, useState } from "react"; function App() { - const { isAuthenticated, userInfo } = useAuth(); - const [ remoteResource, setRemoteResource ] = useState(null); + const [repositories, setRepositories] = useState(null); useEffect(() => { if (isAuthenticated) { const savedToken = localStorage.getItem("user_token"); if (savedToken) { - fetch("/api/protected-remote-call", { + fetch("/api/github/repositories", { method: "GET", headers: { - "Authorization": `Bearer ${savedToken}` - } + "Authorization": `Bearer ${savedToken}`, + }, }) - .then(response => response.json()) - .then(data => { + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { console.log("Protected remote call response:", data); - setRemoteResource(data.resource); + setRepositories(data.repositories || []); }) - .catch(error => { + .catch((error) => { console.error("Error during protected remote call:", error); }); } @@ -34,11 +38,20 @@ function App() { <> {isAuthenticated ? ( <> -
No repositories found.
)} > ) : ( @@ -46,15 +59,24 @@ function App() {