70 lines
2 KiB
TypeScript
70 lines
2 KiB
TypeScript
import { ApolloServer } from '@apollo/server';
|
|
import { expressMiddleware } from '@apollo/server/express4';
|
|
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
|
|
import cors from 'cors';
|
|
import 'dotenv/config';
|
|
import express, { Request, Response } from 'express';
|
|
import fs from 'fs';
|
|
import http from 'http';
|
|
import jwt from 'jsonwebtoken';
|
|
import path from 'path';
|
|
import ViteExpress from 'vite-express';
|
|
|
|
import { Mutation, Query } from './graphql/graphql';
|
|
import { prisma } from './prisma/client';
|
|
|
|
const __dirname = import.meta.dirname;
|
|
const HOST = process.env.VITE_HOST || 'localhost';
|
|
const PORT = parseInt(process.env.VITE_PORT || '3000');
|
|
const MOTD = `\n\n\n\x1b[35m-server is listening at...-\x1b[0m\n\nhttp://${HOST}:${PORT}\nhttp://localhost:${PORT}\n\n\n`;
|
|
|
|
const app = express();
|
|
const server = http.createServer(app);
|
|
|
|
const typeDefs = fs.readFileSync(path.join(__dirname, 'graphql', 'schema.graphql'), 'utf8');
|
|
|
|
const resolvers = {
|
|
Query,
|
|
Mutation
|
|
// Subscription,
|
|
};
|
|
|
|
interface IdentityContext {
|
|
authScope?: String;
|
|
}
|
|
|
|
const apollo = new ApolloServer<IdentityContext>({
|
|
typeDefs,
|
|
resolvers,
|
|
plugins: [ApolloServerPluginDrainHttpServer({ httpServer: server })]
|
|
});
|
|
|
|
await apollo.start();
|
|
|
|
app.use(
|
|
'/graphql',
|
|
cors<cors.CorsRequest>(),
|
|
express.json(),
|
|
expressMiddleware(apollo, {
|
|
context: getUser
|
|
})
|
|
);
|
|
|
|
await new Promise<void>(resolve => server.listen({ hostname: HOST, port: PORT }, resolve));
|
|
|
|
process.stdout.write(MOTD);
|
|
|
|
ViteExpress.bind(app, server);
|
|
|
|
async function getUser({ req, res }: { req: Request; res: Response }) {
|
|
const authHeader = req.headers.authorization;
|
|
if (!authHeader) return { identity: null };
|
|
const token = authHeader.split(' ')[1];
|
|
|
|
const accessTokenSecret = process.env.ACCESS_TOKEN_SECRET;
|
|
if (accessTokenSecret == null) throw Error('No `accessToken`');
|
|
|
|
const decoded = jwt.verify(token, accessTokenSecret) as { userId: string };
|
|
const identity = await prisma.user.findUnique({ where: { id: decoded.userId } });
|
|
return { identity };
|
|
}
|