Skip to content

Commit

Permalink
Merge pull request #114 from rogershi-dev/feature/registration-auth
Browse files Browse the repository at this point in the history
Added user profile drop down menu.
  • Loading branch information
rogershi-dev authored Jul 14, 2024
2 parents 7e53f8e + 8c4ae10 commit fde7685
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 72 deletions.
10 changes: 6 additions & 4 deletions server/routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ router.get('/github/callback', async (req, res) => {
});
// Extract the user's GitHub username
const githubUsername = githubResponse.data.login;
const githubProfileUrl = githubResponse.data.avatar_url;
console.log(githubResponse.data);
console.log(githubUsername);

Expand Down Expand Up @@ -86,7 +87,7 @@ router.get('/github/callback', async (req, res) => {
await connection.beginTransaction();

// Perform the UPDATE operation to refresh github_token
await connection.query('UPDATE users SET github_token = ? WHERE github_username = ?', [accessToken, githubUsername]);
await connection.query('UPDATE users SET github_token = ?, github_profileurl = ? WHERE github_username = ?', [accessToken, githubProfileUrl, githubUsername]);

// Perform a SELECT query to retrieve the updated row data
const [updatedRows, updatedFields] = await connection.query('SELECT * FROM users WHERE github_username = ?', [githubUsername]);
Expand Down Expand Up @@ -125,6 +126,7 @@ router.get('/github/callback', async (req, res) => {
// Store Github username and access token in session for later use with LinkedIn OAuth
req.session.githubUsername = githubUsername;
req.session.githubAccessToken = accessToken;
req.session.githubProfileUrl = githubProfileUrl;
req.session.save((err) => {
if (err) {
console.log('Error saving session data:', err);
Expand Down Expand Up @@ -178,7 +180,7 @@ function getKey(header, callback) {
router.get('/linkedin/callback', async (req, res) => {
// Extract the temporary authorization code from LinkedIn
const { code } = req.query;
const { githubUsername, githubAccessToken } = req.session;
const { githubUsername, githubAccessToken, githubProfileUrl } = req.session;

try {
// Exchange the authorization code for an access token
Expand Down Expand Up @@ -275,8 +277,8 @@ router.get('/linkedin/callback', async (req, res) => {
} else {
// Otherwise, retrieve the github credentials from session store and save all of them in local DB
await pool.query(
'INSERT INTO users (github_username, linkedin_id, github_token, linkedin_token) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE github_token = VALUES(github_token), linkedin_token = VALUES(linkedin_token)',
[githubUsername, linkedinId, githubAccessToken, accessToken]
'INSERT INTO users (github_username, linkedin_id, github_token, linkedin_token, github_profileurl) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE github_token = VALUES(github_token), linkedin_token = VALUES(linkedin_token), github_profileurl = VALUES(github_profileurl)',
[githubUsername, linkedinId, githubAccessToken, accessToken, githubProfileUrl]
);

// Once it's done, there's no need to keep the session data, destroy them.
Expand Down
5 changes: 3 additions & 2 deletions server/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ router.get('/', async function(req, res, next) {
// Once I have the userInfo, I wan to fetch all the repositories and show them.
const githubRepos = await fetchGitHubRepos(userInfo[0].github_token, page, perPage);
res.render('index', {
title: 'LinkedIn Auto-Post App',
title: 'LinkedIn Auto-Post',
error,
userInfo,
githubRepos,
Expand All @@ -43,7 +43,7 @@ router.get('/', async function(req, res, next) {
} catch (fetchError) {
console.error('Error while fetching GitHub repositories:', fetchError);
res.render('index', {
title: 'LinkedIn Auto-Post App',
title: 'LinkedIn Auto-Post',
error,
userInfo,
githubRepos: [],
Expand Down Expand Up @@ -244,6 +244,7 @@ router.post('/webhook', async (req, res) => {
console.log('Data received from GitHub webhook:', req.body);
const commitMessage = req.body.head_commit.message;
console.log(commitMessage);
// const linkedinAccessToken = req.session.user[0].linkedin_token;

try {
// Expand the commit message into a full post
Expand Down
118 changes: 59 additions & 59 deletions server/routes/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,64 +75,64 @@ router.get('/register', (req, res) => {
res.render('register', { githubUsername, linkedinId, error });
});

async function getUserRepositories(githubToken) {
try {
const response = await axios.get('https://api.github.com/user/repos', {
headers: {
Authorization: `token ${githubToken}`
},
params: {
visibility: 'all' // to get both public and private repositories
}
});

// Extract general information from the response
const repos = response.data.map(repo => ({
name: repo.name,
description: repo.description,
language: repo.language,
stars: repo.stargazers_count,
forks: repo.forks_count,
private: repo.private,
}));

return repos;
} catch (error) {
console.error('Error fetching repositories:', error);
throw error;
}
}

// Route to register account and save access tokens
router.post('/register/save-tokens', async (req, res) => {
const { githubToken, mastodonToken } = req.body;

try {
// Fetch user information from GitHub
const githubResponse = await axios.get('https://api.github.com/user', {
headers: {
Authorization: `token ${githubToken}`
}
});

const githubUsername = githubResponse.data.login;
console.log(githubResponse.data);
console.log(githubUsername);

getUserRepositories(githubToken).then(repos => {
console.log(repos);
}).catch(error => {
console.error('Error:', error);
});


const [rows, fields] = await pool.query('INSERT INTO access_tokens (github_token, mastodon_token) VALUES (?, ?)', [githubToken, mastodonToken]);

res.status(200).json({ message: 'Tokens saved successfully' });
} catch (error) {
console.error('Error saving tokens:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
// async function getUserRepositories(githubToken) {
// try {
// const response = await axios.get('https://api.github.com/user/repos', {
// headers: {
// Authorization: `token ${githubToken}`
// },
// params: {
// visibility: 'all' // to get both public and private repositories
// }
// });

// // Extract general information from the response
// const repos = response.data.map(repo => ({
// name: repo.name,
// description: repo.description,
// language: repo.language,
// stars: repo.stargazers_count,
// forks: repo.forks_count,
// private: repo.private,
// }));

// return repos;
// } catch (error) {
// console.error('Error fetching repositories:', error);
// throw error;
// }
// }

// // Route to register account and save access tokens
// router.post('/register/save-tokens', async (req, res) => {
// const { githubToken, mastodonToken } = req.body;

// try {
// // Fetch user information from GitHub
// const githubResponse = await axios.get('https://api.github.com/user', {
// headers: {
// Authorization: `token ${githubToken}`
// }
// });

// const githubUsername = githubResponse.data.login;
// console.log(githubResponse.data);
// console.log(githubUsername);

// getUserRepositories(githubToken).then(repos => {
// console.log(repos);
// }).catch(error => {
// console.error('Error:', error);
// });


// const [rows, fields] = await pool.query('INSERT INTO access_tokens (github_token, mastodon_token) VALUES (?, ?)', [githubToken, mastodonToken]);

// res.status(200).json({ message: 'Tokens saved successfully' });
// } catch (error) {
// console.error('Error saving tokens:', error);
// res.status(500).json({ message: 'Internal Server Error' });
// }
// });

module.exports = router;
79 changes: 73 additions & 6 deletions server/views/index.pug
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,29 @@ extends layout
block content
.container-fluid
.container.custom-container
.text-center
h1= title
//- Profile Dropdown Menu
.profile-dropdown
button#dropdownMenuButton.btn.btn-link(type='button', onclick='toggleDropdown()')
img(src=userInfo[0].github_profileurl, alt='Profile Image', class='rounded-circle', style='width: 40px; height: 40px;')
.dropdown-content#dropdownContent
.dropdown-item(style="font-weight: bolder;") Hi, #{userInfo[0].github_username}
.dropdown-divider(style="margin-left: 10px;")
a.dropdown-item(href='/users/logout', style="display: flex; align-items: center;")
i.fa-solid.fa-arrow-right-from-bracket(style='margin-right: 8px;')
span Log Out

.text-center(style="margin-top: 30px; margin-bottom: 40px;")
h1= title
if error == 'logoutError'
.alert.alert-danger(role='alert') There was an error logging you out! Please try again!
if error == 'setWebhookError'
.alert.alert-danger(role='alert') There was an error setting webhooks for the selected repo! Please try again!
if githubRepoError
.alert.alert-danger(role='alert') #{githubRepoError}
if userInfo && userInfo.length > 0
p Welcome our GitHub guest: #{userInfo[0].github_username}
//- Logout Button
a.btn.btn-danger(href='/users/logout', style="margin-bottom: 20px;") Log Out
//- if userInfo && userInfo.length > 0
//- p Welcome our GitHub guest: #{userInfo[0].github_username}
//- //- Logout Button
//- a.btn.btn-danger(href='/users/logout', style="margin-bottom: 20px;") Log Out
//- Display GitHub Repositories
if githubRepos && githubRepos.length > 0
Expand Down Expand Up @@ -99,6 +109,45 @@ block content

//- Custom Styles
style.
.profile-dropdown {
position: absolute;
top: 10px;
right: 10px;
//- z-index: 1051;
}
.dropdown-content {
display: none;
position: absolute;
background-color: white;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1052;
border-radius: 10px;
right: 0px;
top: 50px;
overflow: hidden;
padding-right: 10px;
}
.dropdown-content .dropdown-item {
padding: 12px 16px;
text-decoration: none;
display: block;
color: black;
border-radius: 10px;
margin: 5px;
}
.dropdown-content .dropdown-item:hover {
background-color: #f5f5f5;
}
.dropdown-content .dropdown-divider {
height: 1px;
margin: .5rem 0;
//- overflow: hidden;
background-color: #eceeef;
}
.show {
display: block;
}
.custom-badge:not(:first-child) {
margin-left: 0px;
}
Expand Down Expand Up @@ -196,6 +245,10 @@ block content

//- Custom Script
script.
function toggleDropdown() {
document.getElementById('dropdownContent').classList.toggle('show');
}

function showModal(event, currentPage, perPage) {
const repoName = event.currentTarget.getAttribute('data-repo-name');
const hasSetWebhook = event.currentTarget.getAttribute('webhook-repo-status');
Expand Down Expand Up @@ -265,6 +318,20 @@ block content
}

window.onclick = function(event) {
// If the user clicks outside of the drop down menu, close the drop down menu
if (!event.target.matches('#dropdownMenuButton') && !event.target.closest('.profile-dropdown')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
//- dropdowns.style.display = 'none';
//- document.getElementById('dropdownContent').classList.toggle('show');
for (var i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}

// If the user clicks places outside of the .modal-dialog, which is .modal, close the dialog window
const modal = document.getElementById('repoModal');
if (event.target == modal) {
modal.style.display = 'none';
Expand Down
3 changes: 2 additions & 1 deletion server/views/layout.pug
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ html
meta(name='viewport', content='width=device-width, initial-scale=1')
title= title
link(href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous")
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css')
//- link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css')
link(href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet")
link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.8.1/font/bootstrap-icons.min.css')
link(rel='stylesheet' href='/stylesheets/style.css')
body
Expand Down

0 comments on commit fde7685

Please sign in to comment.