-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
126 lines (104 loc) · 3.4 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* eslint-disable @typescript-eslint/no-unused-vars */
import cookieParser from 'cookie-parser';
import express, { Request, Response, NextFunction } from 'express';
import graphqlHTTP, { RequestInfo } from 'express-graphql';
import 'reflect-metadata';
import jwt from 'express-jwt';
import { buildSchema } from 'type-graphql';
import baseContext from './src/buildContext';
import { ResolverContext } from './src/context';
import { Role } from './src/models/Role';
import { User, UserWithRole } from './src/models/User';
import { registerEnums } from './src/resolvers/registerEnums';
import files from './src/routes/files';
import proposalDownload from './src/routes/pdf';
import { logger } from './src/utils/Logger';
interface Req extends Request {
user?: {
user?: User;
currentRole?: Role;
roles?: Role[];
};
}
interface MiddlewareError extends Error {
code: string | number;
}
async function bootstrap() {
const app = express();
const secret = process.env.secret as string;
// authentication middleware
const authMiddleware = jwt({
credentialsRequired: false,
secret,
});
const extensions = async (info: RequestInfo) => {
if (info.result.errors) {
logger.logError('Failed GRAPHQL execution', {
result: info.result,
operationName: info.operationName,
user: info.context.user,
});
}
};
app.use(
authMiddleware,
(err: MiddlewareError, req: Request, res: Response, next: NextFunction) => {
/**
* TODO: Check if this is really useful. We have general error handling middleware on line 108.
* Where that invalid_token code comes from???
* What is the scenario where we can enter this block???
*/
if (err.code === 'invalid_token') {
return res.status(401).send('jwt expired');
}
return res.sendStatus(400);
}
);
registerEnums();
app.use(cookieParser());
const schema = await buildSchema({
resolvers: [
__dirname + '/src/resolvers/**/*Query.{ts,js}',
__dirname + '/src/resolvers/**/*Mutation.{ts,js}',
__dirname + '/src/resolvers/**/*Resolver.{ts,js}',
],
validate: false,
});
app.use(
'/graphql',
graphqlHTTP(async (req: Req) => {
// Adds the currently logged-in user to the context object, which makes it available to the resolvers
// The user sends a JWT token that is decrypted, this JWT token contains information about roles and ID
let user = null;
const userId = req.user?.user?.id as number;
if (req.user) {
user = {
...(await baseContext.queries.user.getAgent(userId)),
currentRole:
req.user.currentRole || (req.user.roles ? req.user.roles[0] : null),
} as UserWithRole;
}
const context: ResolverContext = { ...baseContext, user };
return {
schema,
graphiql: true,
context,
extensions,
};
})
);
app.use(files);
app.use(proposalDownload);
app.listen(process.env.PORT || 4000);
app.use(
(err: Error | string, req: Request, res: Response, next: NextFunction) => {
logger.logException('Unhandled EXPRESS JS exception', err, { req, res });
res.status(500).send('SERVER EXCEPTION');
}
);
process.on('uncaughtException', error => {
logger.logException('Unhandled NODE exception', error);
});
console.log('Running a GraphQL API server at localhost:4000/graphql');
}
bootstrap();