Some checks failed
Deploy to Firebase Hosting on merge / build_and_deploy (push) Has been cancelled
154 lines
4.6 KiB
JavaScript
Executable File
154 lines
4.6 KiB
JavaScript
Executable File
const express = require('express');
|
|
const router = express.Router();
|
|
const passport = require('passport');
|
|
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
|
const jwt = require('jsonwebtoken');
|
|
const db = require('./db');
|
|
const { generateUniqueId } = require('../shared/utils/crypto');
|
|
|
|
// Check user session (GET)
|
|
router.get('/api/auth/session', (req, res) => {
|
|
const token = req.cookies.token;
|
|
|
|
if (!token) {
|
|
return res.json({ userId: null });
|
|
}
|
|
|
|
try {
|
|
// Verify the token
|
|
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
res.json({ userId: decoded.userId });
|
|
} catch (error) {
|
|
console.error('Invalid token:', error);
|
|
res.status(401).json({ userId: null, error: 'Invalid token' });
|
|
}
|
|
});
|
|
|
|
// Sign in anonymously (POST)
|
|
router.post('/api/auth/signin-anonymous', async (req, res) => {
|
|
const userId = generateUniqueId(); // Generate unique ID for anonymous user
|
|
console.error('??????????????? signing-in as anonymous', userId);
|
|
|
|
try {
|
|
// Insert the anonymous user into the database (no sensitive data, just ID)
|
|
await db.query('INSERT INTO users (id, provider) VALUES (?, ?)', [
|
|
userId,
|
|
'anonymous',
|
|
]);
|
|
|
|
// Generate JWT token for the anonymous user
|
|
const token = jwt.sign(
|
|
{ userId, provider: 'anonymous' },
|
|
process.env.JWT_SECRET,
|
|
{ expiresIn: '1h' }
|
|
);
|
|
|
|
// Set the JWT in an httpOnly cookie for better security
|
|
res.cookie('token', token, { httpOnly: true, secure: true });
|
|
console.error('!!!!!!!!!!!!!!! signed-in as anonymous', userId, token);
|
|
|
|
res.status(200).json({ message: 'Anonymous user signed in' });
|
|
} catch (error) {
|
|
console.error('Error creating anonymous user:', error);
|
|
res.status(500).json({ error: 'Server error' });
|
|
}
|
|
});
|
|
|
|
router.post('/api/auth/refresh-token', (req, res) => {
|
|
const refreshToken = req.cookies.refreshToken;
|
|
if (!refreshToken) return res.status(403).send('Refresh token required');
|
|
|
|
// Verify the refresh token and issue a new JWT
|
|
try {
|
|
const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
|
|
const newToken = jwt.sign(
|
|
{ userId: decoded.userId },
|
|
process.env.JWT_SECRET,
|
|
{ expiresIn: '1h' }
|
|
);
|
|
res.cookie('token', newToken, { httpOnly: true, secure: true });
|
|
res.json({ message: 'Token refreshed' });
|
|
} catch (error) {
|
|
res.status(403).send('Invalid refresh token');
|
|
}
|
|
});
|
|
|
|
// Initialize Passport
|
|
router.use(passport.initialize());
|
|
|
|
// Google OAuth Strategy
|
|
passport.use(
|
|
new GoogleStrategy(
|
|
{
|
|
clientID: process.env.GOOGLE_CLIENT_ID,
|
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
callbackURL: process.env.GOOGLE_REDIRECT_URI,
|
|
},
|
|
async (accessToken, refreshToken, profile, done) => {
|
|
const googleId = profile.id; // This is the unique ID from Google
|
|
|
|
try {
|
|
// Insert the Google user into the database if they don't exist
|
|
await db.query(
|
|
'INSERT INTO users (id, provider) VALUES (?, ?) ON DUPLICATE KEY UPDATE id = id',
|
|
[googleId, 'google']
|
|
);
|
|
|
|
// Generate JWT token for the Google user
|
|
const token = jwt.sign(
|
|
{ userId: googleId, provider: 'google' },
|
|
process.env.JWT_SECRET,
|
|
{ expiresIn: '1h' }
|
|
);
|
|
|
|
// Pass the token back
|
|
return done(null, token);
|
|
} catch (error) {
|
|
return done(error);
|
|
}
|
|
}
|
|
)
|
|
);
|
|
|
|
// Start Google OAuth login
|
|
router.get(
|
|
'/api/auth/google',
|
|
passport.authenticate('google', { scope: ['profile', 'email'] })
|
|
);
|
|
|
|
// Callback route for Google OAuth
|
|
router.get(
|
|
'/api/auth/google/callback',
|
|
passport.authenticate('google', { failureRedirect: '/' }),
|
|
(req, res) => {
|
|
// After successful authentication, generate the JWT (which is in req.user)
|
|
const token = req.user; // Passport's Google strategy should return the JWT
|
|
|
|
// Set the JWT in an httpOnly cookie
|
|
res.cookie('token', token, { httpOnly: true, secure: true });
|
|
|
|
// Redirect to the frontend dashboard or a secure page without the token in the URL
|
|
res.redirect('/dashboard');
|
|
}
|
|
);
|
|
|
|
// Example of a protected route (no neeaxios.d for query token)
|
|
router.get('/dashboard', (req, res) => {
|
|
// Extract token from cookies (JWT is automatically sent as a cookie)
|
|
const token = req.cookies.token;
|
|
|
|
if (!token) {
|
|
return res.status(403).send('Token is required');
|
|
}
|
|
|
|
try {
|
|
// Verify the token and decode it
|
|
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
res.send(`Welcome, user with ID: ${decoded.userId}`);
|
|
} catch (err) {
|
|
res.status(403).send('Invalid token');
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|