Skip to content

Commit

Permalink
Updated auth, passport
Browse files Browse the repository at this point in the history
  • Loading branch information
hkirat committed Apr 19, 2024
1 parent bbabfb5 commit 8cdc65c
Show file tree
Hide file tree
Showing 19 changed files with 678 additions and 290 deletions.
18 changes: 15 additions & 3 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,30 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc -b",
"build": "npx esbuild src/index.ts --bundle --platform=node --outfile=dist/index.js",
"start": "node dist/index.js",
"dev": "npm run build && npm run start"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@types/express": "^4.17.21",
"express": "^4.19.2"
"@repo/db": "*",
"@types/express-session": "^1.18.0",
"cookie-session": "^2.1.0",
"cors": "^2.8.5",
"express": "^4.19.2",
"express-session": "^1.18.0",
"jsonwebtoken": "^9.0.2",
"passport": "^0.7.0",
"passport-facebook": "^3.0.0",
"passport-github2": "^0.1.12",
"passport-google-oauth20": "^2.0.0"
},
"devDependencies": {
"@types/cookie-session": "^2.0.49",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jsonwebtoken": "^9.0.6",
"@types/passport": "^1.0.16"
}
Expand Down
5 changes: 5 additions & 0 deletions apps/backend/src/db/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PrismaClient } from "@prisma/client";

const client = new PrismaClient()

export const db = client;
31 changes: 15 additions & 16 deletions apps/backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import express from "express";
import v1Router from "./router/v1";
const cookieSession = require("cookie-session");
const cors = require("cors");
const passportSetup = require("./passport");
const passport = require("passport");
import cors from "cors";
import { initPassport } from "./passport";
import authRoute from "./router/auth";
import dotenv from "dotenv";
import session from 'express-session';
import passport from "passport";

const app = express();

dotenv.config();
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false,
cookie: { secure: false, maxAge: 360000}
}));

app.use(
cookieSession({
name: "session",
keys: ["lama"],
maxAge: 24 * 60 * 60 * 100,
})
);

initPassport();
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.authenticate('session'));

app.use(
cors({
origin: "http://localhost:5173/",
origin: "http://localhost:5173",
methods: "GET,POST,PUT,DELETE",
credentials: true,
})
Expand All @@ -33,7 +32,7 @@ app.use(
app.use("/auth", authRoute);
app.use("/v1", v1Router);

const PORT = process.env.PORT || 5173;
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
});
121 changes: 75 additions & 46 deletions apps/backend/src/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,91 @@ const GithubStrategy = require("passport-github2").Strategy;
const FacebookStrategy = require("passport-facebook").Strategy;
import passport from "passport";
import dotenv from "dotenv";
import { db } from "./db";

dotenv.config();

const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID || "your_google_client_id";
const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET || "your_google_client_secret";
const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID || "your_github_client_id";
const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET || "your_github_client_secret";
const FACEBOOK_APP_ID = process.env.FACEBOOK_APP_ID || "your_facebook_app_id";
const FACEBOOK_APP_SECRET = process.env.FACEBOOK_APP_SECRET || "your_facebook_app_secret";

if (!GOOGLE_CLIENT_ID || !GOOGLE_CLIENT_SECRET || !GITHUB_CLIENT_ID || !GITHUB_CLIENT_SECRET || !FACEBOOK_APP_ID || !FACEBOOK_APP_SECRET) {
throw new Error('Missing environment variables for authentication providers');
}
passport.use(
new GoogleStrategy(
{
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback",
},
function (accessToken: string, refreshToken: string, profile: any, done: (error: any, user?: any) => void) {
done(null, profile);
}
)
);

passport.use(
new GithubStrategy(
{
clientID: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
callbackURL: "/auth/github/callback",
},
function (accessToken: string, refreshToken: string, profile: any, done: (error: any, user?: any) => void) {
done(null, profile);
}
)
);
export function initPassport() {

if (!GOOGLE_CLIENT_ID || !GOOGLE_CLIENT_SECRET || !GITHUB_CLIENT_ID || !GITHUB_CLIENT_SECRET || !FACEBOOK_APP_ID || !FACEBOOK_APP_SECRET) {
throw new Error('Missing environment variables for authentication providers');
}

passport.use(
new GoogleStrategy(
{
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback",
},
async function (accessToken: string, refreshToken: string, profile: any, done: (error: any, user?: any) => void) {
const user = await db.user.upsert({
create: {
email: profile.emails[0].value,
name: profile.displayName,
provider: "GOOGLE",
},
update: {
name: profile.displayName,
},
where: {
email: profile.emails[0].value,
}
});

passport.use(
new FacebookStrategy(
{
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "/auth/facebook/callback",
},
function (accessToken: string, refreshToken: string, profile: any, done: (error: any, user?: any) => void) {
done(null, profile);
}
)
);
done(null, user);
}
)
);

passport.serializeUser((user: any, done: (error: any, id?: any) => void) => {
done(null, user);
});
passport.use(
new GithubStrategy(
{
clientID: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
callbackURL: "/auth/github/callback",
},
async function (accessToken: string, refreshToken: string, profile: any, done: (error: any, user?: any) => void) {
const user = await db.user.upsert({
create: {
email: profile.emails[0].value,
name: profile.displayName,
provider: "GITHUB",
},
update: {
name: profile.displayName,
},
where: {
email: profile.emails[0].value,
}
});

passport.deserializeUser((user: any, done: (error: any, user?: any) => void) => {
done(null, user);
});
done(null, user);
}
)
);

passport.serializeUser(function(user: any, cb) {
process.nextTick(function() {
return cb(null, {
id: user.id,
username: user.username,
picture: user.picture
});
});
});

passport.deserializeUser(function(user: any, cb) {
process.nextTick(function() {
return cb(null, user);
});
});

}
14 changes: 9 additions & 5 deletions apps/backend/src/router/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ interface User {
_id: string;
}

router.get('/login/success', (req: Request, res: Response) => {
router.get('/auth/refresh', (req: Request, res: Response) => {
if (req.user) {
const user = req.user as User;

// Token is issued so it can be shared b/w HTTP and ws server
// Todo: Make this temporary and add refresh logic here
const token = jwt.sign({ userId: user._id }, JWT_SECRET);
res.cookie('jwt', token, { httpOnly: true, sameSite: 'strict' });
res.status(200).json({ success: true, message: 'successful' });
res.json({
token
});
} else {
res.status(401).json({ success: false, message: 'Unauthorized' });
}
Expand All @@ -37,14 +41,14 @@ router.get('/logout', (req: Request, res: Response) => {
});
});

router.get('/google', passport.authenticate('google', { scope: ['profile'] }));
router.get('/google', passport.authenticate('google', { scope: ['profile', 'email'] }));

router.get('/google/callback', passport.authenticate('google', {
successRedirect: CLIENT_URL,
failureRedirect: '/login/failed',
}));

router.get('/github', passport.authenticate('github', { scope: ['profile'] }));
router.get('/github', passport.authenticate('github', { scope: ['profile', 'email'] }));

router.get('/github/callback', passport.authenticate('github', {
successRedirect: CLIENT_URL,
Expand Down
1 change: 1 addition & 0 deletions apps/backend/src/router/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Router } from "express";

const v1Router = Router();


v1Router.get("/", (req, res) => {
res.send("Hello, World!");
});
Expand Down
3 changes: 2 additions & 1 deletion apps/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function App() {
useEffect(() => {
const fetchToken = async () => {
try {
const response = await fetch('http://localhost:5173/auth/login/success', {
const response = await fetch('http://localhost:3000/auth/auth/refresh', {
method: 'GET',
credentials: 'include',
headers: {
Expand All @@ -22,6 +22,7 @@ function App() {

if (response.ok) {
setIsAuthenticated(true);
localStorage.setItem("token", (await response.json()).token);
} else {
throw new Error('Authentication failed');
}
Expand Down
8 changes: 5 additions & 3 deletions apps/frontend/src/screens/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import Facebook from "../assets/facebook.png";
import Github from "../assets/github.png";
import { useNavigate } from 'react-router-dom';

const BACKEND_URL = "http://localhost:3000";

const Login = () => {
const navigate = useNavigate();

const google = () => {
window.open("http://localhost:5173/auth/google", "_self");
window.open(`${BACKEND_URL}/auth/google`, "_self");
};

const github = () => {
window.open("http://localhost:5173/auth/github", "_self");
window.open(`${BACKEND_URL}/auth/github`, "_self");
};

const facebook = () => {
window.open("http://localhost:5173/auth/facebook", "_self");
window.open(`${BACKEND_URL}/auth/facebook`, "_self");
};

return (
Expand Down
3 changes: 2 additions & 1 deletion apps/ws/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"@prisma/client": "^5.12.1",
"@types/ws": "^8.5.10",
"chess.js": "^1.0.0-beta.8",
"ws": "^8.16.0"
"ws": "^8.16.0",
"@repo/db": "*"
},
"devDependencies": {
"@types/node": "^20.12.7",
Expand Down
2 changes: 1 addition & 1 deletion apps/ws/src/Game.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WebSocket } from "ws";
import { Chess } from 'chess.js'
import { GAME_OVER, INIT_GAME, MOVE } from "./messages";
import db from "@repo/db"
import db from "@repo/db/client"
import { randomUUID } from "crypto";

export class Game {
Expand Down
2 changes: 1 addition & 1 deletion apps/ws/src/GameManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WebSocket } from "ws";
import { INIT_GAME, JOIN_GAME, MOVE } from "./messages";
import { Game } from "./Game";
import db from "@repo/db"
import db from "@repo/db/client"

export class GameManager {
private games: Game[];
Expand Down
Loading

0 comments on commit 8cdc65c

Please sign in to comment.