Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added .gitignore
Binary file not shown.
60 changes: 60 additions & 0 deletions app/src/scripts/script.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
// --- Professional OAuth Modal Logic ---
const googleLoginBtn = document.getElementById('googleLoginBtn');
const githubLoginBtn = document.getElementById('githubLoginBtn');
const profileBtn = document.getElementById('profileBtn');
const userProfileImg = document.getElementById('userProfileImg');
const loginBtn = document.getElementById('loginBtn');
const loginModal = document.getElementById('loginModal');
const closeLoginModal = document.getElementById('closeLoginModal');

function showLoginModal() {
loginModal.style.display = 'flex';
}
function hideLoginModal() {
loginModal.style.display = 'none';
}
function showProfile(user) {
loginBtn.style.display = 'none';
profileBtn.style.display = 'inline-block';
if (user && user.photo) {
userProfileImg.src = user.photo;
userProfileImg.alt = user.displayName || 'User';
}
}
function showLoginButtonOnly() {
loginBtn.style.display = 'inline-block';
profileBtn.style.display = 'none';
}

async function fetchUserProfile() {
try {
const res = await fetch('http://localhost:4000/api/user', {
credentials: 'include',
});
if (res.ok) {
const user = await res.json();
showProfile(user);
window.opendotsUser = user;
} else {
showLoginButtonOnly();
}
} catch (e) {
showLoginButtonOnly();
}
}

window.addEventListener('DOMContentLoaded', () => {
fetchUserProfile();
loginBtn.onclick = showLoginModal;
closeLoginModal.onclick = hideLoginModal;
loginModal.onclick = (e) => { if (e.target === loginModal) hideLoginModal(); };
googleLoginBtn.onclick = () => {
window.location.href = 'http://localhost:4000/auth/google';
};
githubLoginBtn.onclick = () => {
window.location.href = 'http://localhost:4000/auth/github';
};
profileBtn.onclick = () => {
alert(window.opendotsUser ? `Logged in as ${window.opendotsUser.displayName}` : 'No user info');
};
});
Chart.defaults.interaction.mode = 'nearest';
Chart.defaults.interaction.axis = 'x';
Chart.defaults.interaction.intersect = false;
Expand Down
113 changes: 113 additions & 0 deletions app/src/styles/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,104 @@
/* --- Enhanced Modal Styles --- */
.modal-overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(10, 10, 20, 0.82);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.modal-content {
background: linear-gradient(135deg, #181818 80%, #23234a 100%);
padding: 2.7rem 2.2rem 2.2rem 2.2rem;
border-radius: 18px;
box-shadow: 0 8px 40px #000c, 0 1.5px 0 #2e2e2e;
min-width: 340px;
max-width: 95vw;
text-align: center;
position: relative;
border: 1.5px solid #23234a;
animation: modalPop 0.25s cubic-bezier(.68,-0.55,.27,1.55);
}
@keyframes modalPop {
from { transform: scale(0.95); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.modal-content h2 {
margin-bottom: 0.5em;
color: #fff;
font-size: 2em;
letter-spacing: 0.5px;
}
.modal-content p {
color: #bdbdbd;
margin-bottom: 1.7em;
font-size: 1.08em;
}
.oauth-btn {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
margin-bottom: 1.1em;
padding: 0.85em 1.2em;
font-size: 1.13em;
border: none;
border-radius: 8px;
background: #23272f;
color: #fff;
font-weight: 500;
box-shadow: 0 1.5px 0 #23234a;
transition: background 0.18s, box-shadow 0.18s, transform 0.13s;
outline: none;
}
.oauth-btn img {
width: 28px;
height: 28px;
border-radius: 50%;
background: #fff;
box-shadow: 0 0.5px 2px #0002;
}
.oauth-btn.google {
background: #fff;
color: #222;
border: 1.5px solid #e0e0e0;
box-shadow: 0 2px 8px #0001;
}
.oauth-btn.google:hover {
background: #f5f5f5;
transform: translateY(-1px) scale(1.03);
box-shadow: 0 4px 16px #0002;
}
.oauth-btn.github {
background: #23272f;
color: #fff;
border: 1.5px solid #444;
box-shadow: 0 2px 8px #0002;
}
.oauth-btn.github:hover {
background: #444;
transform: translateY(-1px) scale(1.03);
box-shadow: 0 4px 16px #0003;
}
.close-modal {
margin-top: 0.7em;
background: none;
color: #aaa;
border: none;
font-size: 1.08em;
cursor: pointer;
transition: color 0.18s;
}
.close-modal:hover {
color: #fff;
text-decoration: underline;
}
/*list of variables*/
/*text input bg color: #151515*/
:root {
Expand Down Expand Up @@ -49,6 +150,18 @@ button {
cursor: pointer;
border: 1px solid var(--border-color);
}
#loginBtn {
padding: 7px 25px;
border-radius: 5px;
color: white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
min-width: 90px;
text-align: center;
box-sizing: border-box;
}

main {
padding-top: 47px;
Expand Down
18 changes: 17 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,27 @@
<span></span>
</div>
</button>
<button><img src="app/resrc/images/user.png" alt="user" class="headerIcon" id="user"></button>
<button id="loginBtn">Login</button>
<button id="profileBtn" style="display:none"><img src="app/resrc/images/user.png" alt="user" class="headerIcon" id="userProfileImg"></button>
<button onclick="toggleAi()" id="infinity"><img src="app/resrc/images/infinity.png" alt="infinity" class="headerIcon"></button>
</div>
<a href="https://opendots.gitbook.io/docs/"><img src="app/resrc/images/OpenDots.png" alt="OpenDots" class="icon">OpenDots</a>
</header>

<!-- Login Modal -->
<div id="loginModal" class="modal-overlay" style="display:none;">
<div class="modal-content">
<h2>Sign in to OpenDots</h2>
<p>Choose a provider to continue</p>
<button class="oauth-btn google" id="googleLoginBtn">
<img src="https://img.icons8.com/color/32/000000/google-logo.png" alt="Google"> Sign in with Google
</button>
<button class="oauth-btn github" id="githubLoginBtn">
<img src="https://img.icons8.com/ios-glyphs/32/000000/github.png" alt="GitHub"> Sign in with GitHub
</button>
<button class="close-modal" id="closeLoginModal">Cancel</button>
</div>
</div>
<main class="container">
<div id="config">
<h4>Configure</h4>
Expand Down
48 changes: 48 additions & 0 deletions server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

const express = require('express');
const session = require('express-session');
const passport = require('passport');
const cors = require('cors');
require('dotenv').config();
require('./passport');

const app = express();
app.use(cors({ origin: 'http://localhost:3000', credentials: true }));
app.use(express.json());
app.use(session({ secret: process.env.SESSION_SECRET || 'opendots_secret', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());

// --- Auth Routes ---
app.get('/', (req, res) => res.send('OpenDots Auth Server Running'));

// Google OAuth
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/' }), (req, res) => {
res.redirect('http://localhost:3000/profile');
});

// GitHub OAuth
app.get('/auth/github', passport.authenticate('github', { scope: ['user:email'] }));
app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/' }), (req, res) => {
res.redirect('http://localhost:3000/profile');
});

// Get current user profile
app.get('/api/user', (req, res) => {
if (req.isAuthenticated()) {
res.json(req.user);
} else {
res.status(401).json({ error: 'Not authenticated' });
}
});

// Logout
app.get('/auth/logout', (req, res) => {
req.logout(() => {
res.redirect('http://localhost:3000/');
});
});

const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
16 changes: 16 additions & 0 deletions server/node_modules/.bin/mime

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions server/node_modules/.bin/mime.cmd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions server/node_modules/.bin/mime.ps1

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading