-
-
Notifications
You must be signed in to change notification settings - Fork 141
/
context-builder.ts
107 lines (98 loc) · 2.75 KB
/
context-builder.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
import AccountsServer from '@accounts/server';
import { IncomingMessage } from 'http';
import { getClientIp } from 'request-ip';
import { IContext, User } from '@accounts/types';
import { Application } from 'graphql-modules';
export type AccountsContextOptions<Ctx extends object> = {
createOperationController: Application['createOperationController'];
ctx?: Ctx;
headerName?: string;
excludeAddUserInContext?: boolean;
};
function isFetchRequest(request: Request | IncomingMessage): request is Request {
return (request as Request).headers.get != null;
}
function getHeader(request: Request | IncomingMessage, headerName: string): string | null {
const header = isFetchRequest(request)
? request.headers.get(headerName)
: request.headers[headerName];
if (Array.isArray(header)) {
throw new Error('Header should be a string, not array');
}
return header ?? null;
}
export const context = async <IUser extends User = User, Ctx extends object = object>(
{
req,
request,
}:
| {
req: IncomingMessage;
request?: undefined;
}
| {
req?: undefined;
request: Request;
},
{ createOperationController, ctx, ...options }: AccountsContextOptions<Ctx>
): AccountsContextOptions<Ctx> extends { ctx: any }
? Promise<IContext<IUser> & Ctx>
: Promise<IContext<IUser>> => {
console.log('context builder');
const reqOrRequest = request ?? req;
/*const controller = createOperationController({
context: { ...ctx },
autoDestroy: false,
});*/
if (!reqOrRequest) {
return {
ip: '',
userAgent: '',
infos: {
ip: '',
userAgent: '',
},
...ctx,
};
}
const headerName = options.headerName || 'Authorization';
let authToken =
getHeader(reqOrRequest, headerName) ??
getHeader(reqOrRequest, headerName.toLowerCase()) ??
undefined;
authToken = authToken && authToken.replace('Bearer ', '');
let user;
if (authToken && !options.excludeAddUserInContext) {
const controller = createOperationController({
context: { ...ctx },
autoDestroy: false,
});
try {
user = await controller.injector
.get<AccountsServer<IUser>>(AccountsServer)
.resumeSession(authToken);
} catch (error) {
// Empty catch
console.error(error);
}
controller.destroy();
}
//controller.destroy();
const ip = getClientIp(req!); // TODO: we should be able to retrieve the ip with the request object as well
const userAgent =
/* special case of UC Browser */ getHeader(reqOrRequest, 'x-ucbrowser-ua') ??
getHeader(reqOrRequest, 'user-agent') ??
'';
return {
authToken,
user,
userId: user?.id,
userAgent,
ip,
infos: {
userAgent,
ip,
},
...ctx,
};
};