Skip to content

Commit bd7ea05

Browse files
committed
Public GitHub OAuth, clean routes
1 parent 79c1475 commit bd7ea05

File tree

13 files changed

+1347
-122
lines changed

13 files changed

+1347
-122
lines changed

app.js

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,41 +34,35 @@ app.use(
3434
}),
3535
);
3636

37-
// Define routes and middleware here
37+
// Public routes
3838
app.get("/", (req, res) => {
39-
res.sendFile(__dirname + "/public/index.html");
39+
res.render("home");
4040
});
4141

42-
app.get("/token/:service", (req, res) => {
43-
const service = req.params.service;
44-
console.log(
45-
service.toUpperCase() + "_TOKEN",
46-
process.env[service.toUpperCase() + "_TOKEN"],
47-
);
48-
res.send(process.env[service.toUpperCase() + "_TOKEN"] || "No token found");
42+
app.get("/gh-username-search", (req, res) => {
43+
res.render("pages/gh-username-search");
4944
});
5045

51-
// GitHub OAuth
52-
let github_access_token = "not logged in";
53-
54-
function loggedIn() {
55-
if (github_access_token === "not logged in") {
56-
return false;
57-
}
58-
return true;
59-
}
60-
6146
app.get("/profile", (req, res) => {
6247
if (!req.session.user) {
63-
return res.send("log in");
48+
return res.render("pages/login", { client_id: process.env.GITHUB_CLIENT_ID });
6449
}
6550
return res.render("pages/profile", { userData: req.session.user });
6651
});
6752

68-
app.get("/gh", (req, res) => {
69-
res.render("pages/index", { client_id: process.env.GITHUB_CLIENT_ID });
53+
54+
// Token fetching stuff
55+
app.get("/token/:service", (req, res) => {
56+
const service = req.params.service;
57+
console.log(
58+
service.toUpperCase() + "_TOKEN",
59+
process.env[service.toUpperCase() + "_TOKEN"],
60+
);
61+
res.send(process.env[service.toUpperCase() + "_TOKEN"] || "No token found");
7062
});
7163

64+
65+
// GitHub OAuth
7266
// Callback
7367
app.get("/auth/github", (req, res) => {
7468
// The req.query object has the query params that were sent to this route.
@@ -77,22 +71,21 @@ app.get("/auth/github", (req, res) => {
7771
axios({
7872
method: "post",
7973
url: `https://github.com/login/oauth/access_token?client_id=${process.env.GITHUB_CLIENT_ID}&client_secret=${process.env.GITHUB_CLIENT_SECRET}&code=${requestToken}`,
80-
// Set the content type header, so that we get the response in JSON
8174
headers: {
8275
accept: "application/json",
8376
},
8477
}).then((response) => {
85-
github_access_token = response.data.access_token;
78+
req.session.github_access_token = response.data.access_token;
8679
res.redirect("/github/login");
8780
});
8881
});
8982

90-
app.get("/github/login", function (req, res) {
83+
app.get("/github/login", (req, res) => {
9184
axios({
9285
method: "get",
9386
url: `https://api.github.com/user`,
9487
headers: {
95-
Authorization: "token " + github_access_token,
88+
Authorization: "token " + req.session.github_access_token,
9689
},
9790
}).then((response) => {
9891
req.session.user = response.data;

package.json

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
{
2-
"name": "fetchcv",
3-
"version": "0.0.1",
4-
"description": "Your developer profile",
5-
"main": "app.js",
6-
"scripts": {
7-
"start": "node app.js",
8-
"watch-app": "nodemon app.js",
9-
"watch-tailwind": "npx tailwindcss -i ./public/styles/tailwind.config.css -o ./public/styles/styles.css --watch",
10-
"watch-typescript": "tsc -w",
11-
"watch": "npm-run-all --parallel watch-tailwind watch-typescript",
12-
"dev": "npm-run-all --parallel watch-app watch"
13-
},
14-
"repository": {
15-
"type": "git",
16-
"url": "git+https://github.com/FetchCV/fetchcv.git"
17-
},
18-
"author": "Ave and Hamza",
19-
"license": "GPL-3.0-or-later",
20-
"bugs": {
21-
"url": "https://github.com/FetchCV/fetchcv/issues"
22-
},
23-
"homepage": "https://github.com/FetchCV/fetchcv#readme",
24-
"dependencies": {
25-
"axios": "^1.7.2",
26-
"dotenv": "^16.4.5",
27-
"ejs": "^3.1.10",
28-
"express": "^4.18.2",
29-
"express-session": "^1.18.0",
30-
"mongoose": "^8.5.1",
31-
"node": "^21.6.2",
32-
"tailwind": "^4.0.0"
33-
},
34-
"devDependencies": {
35-
"kill-port": "^2.0.1",
36-
"nodemon": "^3.1.0",
37-
"npm-run-all": "^4.1.5",
38-
"typescript": "^5.3.3"
39-
}
2+
"name": "fetchcv",
3+
"version": "0.0.1",
4+
"description": "Your developer profile",
5+
"main": "app.js",
6+
"scripts": {
7+
"start": "node app.js",
8+
"watch-app": "nodemon app.js",
9+
"watch-tailwind": "npx tailwindcss -i ./public/styles/tailwind.config.css -o ./public/styles/tailwind.css --watch",
10+
"watch-typescript": "tsc -w",
11+
"watch": "npm-run-all --parallel watch-tailwind watch-typescript",
12+
"dev": "npm-run-all --parallel watch-app watch"
13+
},
14+
"repository": {
15+
"type": "git",
16+
"url": "git+https://github.com/FetchCV/fetchcv.git"
17+
},
18+
"author": "Ave and Hamza",
19+
"license": "GPL-3.0-or-later",
20+
"bugs": {
21+
"url": "https://github.com/FetchCV/fetchcv/issues"
22+
},
23+
"homepage": "https://github.com/FetchCV/fetchcv#readme",
24+
"dependencies": {
25+
"axios": "^1.7.2",
26+
"dotenv": "^16.4.5",
27+
"ejs": "^3.1.10",
28+
"express": "^4.18.2",
29+
"express-session": "^1.18.0",
30+
"mongoose": "^8.5.1",
31+
"node": "^21.6.2",
32+
"tailwind": "^4.0.0"
33+
},
34+
"devDependencies": {
35+
"kill-port": "^2.0.1",
36+
"nodemon": "^3.1.0",
37+
"npm-run-all": "^4.1.5",
38+
"typescript": "^5.3.3"
39+
}
4040
}

public/index.html renamed to public/home.ejs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!doctype html>
22
<html lang="en">
33
<head>
4-
<link rel="stylesheet" href="styles/styles.css" />
4+
<link rel="stylesheet" href="styles/tailwind.css" />
55
<meta charset="UTF-8" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<link
@@ -53,14 +53,14 @@ <h4 class="text-zinc-500 dark:text-zinc-300">
5353
<div class="block text-center">
5454
<h2 class="text-2xl p-4 font-semibold text-zinc-900 dark:text-zinc-200">Get started!</h2>
5555
<!-- GitHub username profile -->
56-
<a href="profile.html">
56+
<a href="/gh-username-search">
5757
<div class="inline-flex justify-center transition-all p-2 mx-1 shadow-lg bg-zinc-200 dark:bg-zinc-800 border-[1px] border-zinc-300 dark:border-zinc-700 border-t-zinc-100 dark:border-t-zinc-600 rounded-md dark:text-white">
5858
<span class="material-symbols-rounded text-public mr-2">search</span>
5959
<p>GitHub username search</p>
6060
</div>
6161
</a>
6262
<!-- Profile Link -->
63-
<a href="/gh">
63+
<a href="/profile">
6464
<div class="inline-flex justify-center transition-all p-2 mx-1 shadow-lg bg-zinc-200 dark:bg-zinc-800 border-[1px] border-zinc-300 dark:border-zinc-700 border-t-zinc-100 dark:border-t-zinc-600 rounded-md dark:text-white">
6565
<span class="material-symbols-rounded text-public mr-2">account_circle</span>
6666
<p>My Profile</p>

public/profile.html renamed to public/pages/gh-username-search.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<head>
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7-
<link rel="stylesheet" type="text/css" href="styles/styles.css">
7+
<link rel="stylesheet" type="text/css" href="styles/tailwind.css">
88
<link rel="stylesheet" href="styles/profile-styles.css">
99
<link rel="stylesheet"
1010
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
@@ -18,7 +18,7 @@
1818
<div class="mb-20">
1919
<!-- top bar -->
2020
<div class="flex my-2">
21-
<a href="index.html">
21+
<a href="../">
2222
<div
2323
class="inline-flex justify-center transition-all p-2 mr-2 shadow-lg bg-zinc-100 dark:bg-zinc-800 border-[1px] border-zinc-300 dark:border-zinc-700 border-t-zinc-100 dark:border-t-zinc-600 hover:bg-zinc-200 dark:hover:bg-zinc-700 rounded-md dark:text-white">
2424
<span class="material-symbols-rounded text-public">home</span>

public/pages/index.ejs

Lines changed: 0 additions & 19 deletions
This file was deleted.

public/pages/login.ejs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Login | FetchCV</title>
5+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
6+
<link rel="stylesheet" href="../styles/tailwind.css">
7+
</head>
8+
<body>
9+
<div class="h-[100vh] w-full flex justify-center items-center bg-[#f5f5f5] dark:bg-[#222] text-center font-mono">
10+
<div>
11+
<h1 class="my-2 text-6xl font-extrabold">🔑</h1>
12+
<h2 class="m-4 text-3xl text-gray-700">Login options</h2>
13+
<a href="https://github.com/login/oauth/authorize?client_id=<%= client_id %>" class="m-4 py-3 px-4 rounded-lg text-2xl font-light bg-gray-600 text-white"><span class="fa fa-github"></span> Sign in with GitHub</a>
14+
</div>
15+
</div>
16+
</body>
17+
</html>

public/pages/lost.ejs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<link rel="stylesheet" href="Styles/main.css">
7+
<title>🏝️ Lost | FetchCV</title>
8+
</head>
9+
<body>
10+
<div class="h-[100vh] w-full flex justify-center items-center bg-[#f5f5f5] text-center font-mono">
11+
<div>
12+
<h1 class="my-2 text-6xl font-extrabold">🏝️</h1>
13+
<h2 class="text-3xl text-gray-700">Oh no!</h2>
14+
<a href="/" class="text-2xl font-light text-gray-600"> It looks like you're lost. Do you want to go <span class="underline text-blue-700">home</span>?</a>
15+
</div>
16+
</div>
17+
</body>
18+
</html>

public/pages/profile.ejs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<head>
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7-
<link rel="stylesheet" type="text/css" href="../styles/styles.css">
7+
<link rel="stylesheet" type="text/css" href="../styles/tailwind.css">
88
<link rel="stylesheet" href="../styles/profile-styles.css">
99
<link rel="stylesheet"
1010
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
@@ -18,21 +18,22 @@
1818
<div class="mb-20">
1919
<!-- top bar -->
2020
<div class="flex my-2">
21-
<a href="index.html">
21+
<a href="../">
2222
<div
2323
class="inline-flex justify-center transition-all p-2 mr-2 shadow-lg bg-zinc-100 dark:bg-zinc-800 border-[1px] border-zinc-300 dark:border-zinc-700 border-t-zinc-100 dark:border-t-zinc-600 hover:bg-zinc-200 dark:hover:bg-zinc-700 rounded-md dark:text-white">
2424
<span class="material-symbols-rounded text-public">home</span>
2525
</div>
2626
</a>
2727
<!-- User search (will be replaced when accounts are added) -->
28-
<strong>Name</strong>: <%= userData.name %><br>
28+
<!--<strong>Name</strong>: <%= userData.name %><br>
2929
<strong>Username</strong>: <%= userData.login %><br>
3030
<strong>Company</strong>: <%= userData.company %><br>
31-
<strong>Bio</strong>: <%= userData.bio %> </div>
31+
<strong>Bio</strong>: <%= userData.bio %> -->
32+
</div>
3233
<!-- Error box - hidden by default -->
3334
<div
3435
class="error-box shadow-2xl py-4 px-8 my-2 border-[1px] border-zinc-300 dark:border-zinc-700 border-t-zinc-100 dark:border-t-zinc-600 rounded-md hidden bg-blue-800 bg-red-800 bg-green-800">
35-
<h1 class="error-title text-2xl font-mono">Oh no! Token retriavl error</h1>
36+
<h1 class="error-title text-2xl font-mono">Oh no! Token retrival error</h1>
3637
<h1 class="error-text font-mono">We could not fetch your data</h1>
3738
</div>
3839

public/scripts/profile.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===============================================
2+
// On load
3+
//===============================================
4+
// First check for username
5+
window.addEventListener("load", () => {
6+
if (localStorage.getItem("savedUsername")) {
7+
username = JSON.parse(localStorage.getItem("savedUsername"));
8+
getUserInfo();
9+
}
10+
else {
11+
console.log("No username saved.");
12+
showError("No username", "Please enter a username.", "bg-blue-800");
13+
}
14+
});
15+
//===============================================
16+
// Setting username
17+
//===============================================
18+
function newUsername() {
19+
hideError();
20+
let usernameElement = document.getElementById("username");
21+
if (usernameElement) {
22+
username = usernameElement.value;
23+
localStorage.setItem("savedUsername", JSON.stringify(username));
24+
getUserInfo();
25+
}
26+
}
27+
const usernameInput = document.getElementById("username");
28+
if (usernameInput) {
29+
usernameInput.addEventListener("keydown", function (event) {
30+
if (event.key == "Enter") {
31+
newUsername();
32+
}
33+
});
34+
}
35+
//===============================================
36+
// Show user errors
37+
//===============================================
38+
function showError(errorTitle, errorText, color) {
39+
let errorBox = document.querySelector(".error-box");
40+
if (errorBox) {
41+
errorBox.classList.remove("hidden");
42+
errorBox.classList.remove("bg-green-800");
43+
errorBox.classList.remove("bg-red-800");
44+
errorBox.classList.remove("bg-blue-800");
45+
errorBox.classList.add(color);
46+
}
47+
let errorTitleElement = document.querySelector(".error-title");
48+
let errorTextElement = document.querySelector(".error-text");
49+
if (errorTitleElement) {
50+
errorTitleElement.innerHTML = errorTitle;
51+
}
52+
if (errorTextElement) {
53+
errorTextElement.innerHTML = errorText;
54+
}
55+
}
56+
function hideError() {
57+
let errorBox = document.querySelector(".error-box");
58+
if (errorBox) {
59+
errorBox.classList.add("hidden");
60+
}
61+
}

0 commit comments

Comments
 (0)