Skip to content

Commit

Permalink
Fix authentication routes
Browse files Browse the repository at this point in the history
  • Loading branch information
maxmwang committed Oct 8, 2023
1 parent fecbded commit a5dd159
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 51 deletions.
27 changes: 5 additions & 22 deletions backend/src/bootstrap/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
import express from "express";
import { expressMiddleware } from "@apollo/server/express4";
import loaders from "./loaders";
import { Config } from "../config";
import http from "http";

export default async (config: Config) => {
const app = express();

const server = await loaders(app);
await server.start();

app.use(
"/graphql",
expressMiddleware(server, {
context: async ({ req }) => ({
user: {
...req.user,
isAuthenticated: req.isAuthenticated(),
logout: (callback: (err: any) => void) => req.logout(callback),
},
}),
})
);
await loaders(app);

const httpServer = http.createServer(app);

await new Promise<void>((resolve) =>
httpServer.listen({ port: config.port }, resolve)
);
console.log(
`🚀 Server ready at http://localhost:${config.port}${config.graphqlPath}`
);
await httpServer.listen(config.port)

console.log(`🚀\tServer ready (in Docker network) at:\thttp://localhost:${config.port}${config.backendPath}`);
console.log(`\tServer ready (in Host network) at:\thttp://localhost:8080${config.backendPath}`)
};
7 changes: 5 additions & 2 deletions backend/src/bootstrap/loaders/apollo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin
export default async () => {
const schema = buildSchema();

return new ApolloServer({
const server = new ApolloServer({
schema,
plugins: [ApolloServerPluginLandingPageLocalDefault({ includeCookies: true })]
plugins: [ApolloServerPluginLandingPageLocalDefault({ includeCookies: true })],
});
await server.start();

return server;
};
28 changes: 24 additions & 4 deletions backend/src/bootstrap/loaders/express.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import type { Application } from "express";
import { json } from "express";
import { type Application, json } from "express";
import cookieParser from 'cookie-parser';
import cors from "cors";
import helmet from "helmet";
import type { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";

import passportLoader from "./passport";
import { config } from "../../config";

export default async (app: Application) => {
export default async (app: Application, server: ApolloServer) => {
// Body parser only needed during POST on the graphQL path
app.use(config.graphqlPath, json());
app.use(json());
app.use(cookieParser());

// Cors configuration
app.use(cors({
Expand All @@ -17,4 +21,20 @@ export default async (app: Application) => {

// Sets various HTTP headers to help protect our app
app.use(helmet());

// load authentication
passportLoader(app);

app.use(
config.graphqlPath,
expressMiddleware(server, {
context: async ({ req }) => ({
user: {
...req.user,
isAuthenticated: req.isAuthenticated(),
logout: (callback: (err: any) => void) => req.logout(callback),
},
}),
})
);
};
29 changes: 15 additions & 14 deletions backend/src/bootstrap/loaders/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import type { Application } from "express";
import type { ApolloServer } from "@apollo/server";
import { type Application, Router } from "express";
import { config } from "../../config";

// loaders
import apolloLoader from "./apollo";
import expressLoader from "./express";
import mongooseLoader from "./mongoose";
import passportLoader from './passport';

export default async (app: Application): Promise<ApolloServer> => {
// Load everything related to express
console.log("Booting up express...");
await expressLoader(app);
export default async (root: Application): Promise<void> => {
const app = Router() as Application;

console.log("Booting up passport...");
await passportLoader(app);

// Connect to mongoose
// connect to mongoose
console.log("Booting up mongo...");
await mongooseLoader();

// load apollo server config
console.log("Booting up apollo...");
return apolloLoader();
// load apollo server config. must be loaded before express
console.log("Loading apollo...");
const server = await apolloLoader();

// load everything related to express. depends on apollo
console.log("Loading express...");
await expressLoader(app, server);

// append backend path to all routes
root.use(config.backendPath, app);
};
17 changes: 10 additions & 7 deletions backend/src/bootstrap/loaders/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import GoogleStrategy from "passport-google-oauth20";
import { UserModel } from "../../db/user";
import { config } from "../../config";

// routes need to be added as authorized origins/redirect uris in google cloud console
const LOGIN_ROUTE = "/login";
const CALLBACK_ROUTE = "/login/callback";
const LOGIN_REDIRECT_ROUTE = "/login/redirect";
const LOGOUT_ROUTE = "/logout";

const SUCCESS_REDIRECT = "/graphql";
const FAILURE_REDIRECT = "/fail";
// route need to be added as authorized origins/redirect uris in google cloud console
const LOGIN_REDIRECT = config.backendPath + "/login/redirect";

const SUCCESS_REDIRECT = config.backendPath + config.graphqlPath;
const FAILURE_REDIRECT = config.backendPath + "/fail";

const SCOPE = ['profile', 'email']

Expand All @@ -32,7 +34,8 @@ export default async (app: Application) => {
cookie: {
secure: !config.isDev,
httpOnly: true,
maxAge: 1000 * 60 * 60 // 1 hour
maxAge: 1000 * 60 * 60, // 1 hour
sameSite: 'lax',
},
rolling: true,
}));
Expand All @@ -52,7 +55,7 @@ export default async (app: Application) => {
accessType: 'offline',
prompt: 'consent',
}));
app.get(CALLBACK_ROUTE, passport.authenticate('google', {
app.get(LOGIN_REDIRECT_ROUTE, passport.authenticate('google', {
failureRedirect: FAILURE_REDIRECT,
// failureMessage: "failed",
successRedirect: SUCCESS_REDIRECT,
Expand All @@ -77,7 +80,7 @@ export default async (app: Application) => {
passport.use(new GoogleStrategy.Strategy({
clientID: config.GOOGLE_CLIENT_ID,
clientSecret: config.GOOGLE_CLIENT_SECRET,
callbackURL: CALLBACK_ROUTE,
callbackURL: LOGIN_REDIRECT,
scope: SCOPE,
state: true,
}, async (accessToken, refreshToken, profile, done) => {
Expand Down
2 changes: 2 additions & 0 deletions backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const env = (name: string): string => {
export interface Config {
port: number;
url: string;
backendPath: string;
graphqlPath: string;
isDev: boolean;
mongoDB: {
Expand All @@ -29,6 +30,7 @@ export interface Config {
export const config: Config = {
port: +env("PORT"),
url: env("URL"),
backendPath: env("BACKEND_PATH"),
graphqlPath: env("GRAPHQL_PATH"),
isDev: env("NODE_ENV") === "development",
mongoDB: {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/modules/user/typedefs/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { gql } from "graphql-tag";

const typedef = gql`
"""
User accout info.
User account info.
"""
type User {
email: String!
Expand Down
1 change: 0 additions & 1 deletion nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ server {

# Backend
location /api {
rewrite ^/api(.*)$ $1 break;
proxy_set_header Host $http_host;
proxy_pass http://backend:5001;
}
Expand Down

0 comments on commit a5dd159

Please sign in to comment.