-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
context.ts
94 lines (80 loc) · 2.27 KB
/
context.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
/* SPDX-FileCopyrightText: 2016-present Kriasoft <[email protected]> */
/* SPDX-License-Identifier: MIT */
import DataLoader from "dataloader";
import { Request } from "express";
import { Forbidden, Unauthorized } from "http-errors";
import db, { Identity, User } from "../db";
import { mapTo, mapToMany } from "./utils";
/**
* GraphQL execution context.
* @see https://graphql.org/learn/execution/
*/
export class Context {
private readonly req: Request;
constructor(req: Request) {
this.req = req;
// Add the currently logged in user object to the cache
if (req.user) {
this.userById.prime(req.user.id, req.user);
if (req.user.username) {
this.userByUsername.prime(req.user.username, req.user);
}
}
}
/*
* Authentication and authorization
* ------------------------------------------------------------------------ */
get user(): User | null {
return this.req.user;
}
signIn(user: User | null | undefined): Promise<User | null> {
return this.req.signIn(user);
}
signOut(): void {
this.req.signOut();
}
ensureAuthorized(check?: (user: User) => boolean): void {
if (!this.req.user) {
throw new Unauthorized();
}
if (check && !check(this.req.user)) {
throw new Forbidden();
}
}
/*
* Data loaders
* ------------------------------------------------------------------------ */
userById = new DataLoader<string, User | null>((keys) =>
db
.table<User>("user")
.whereIn("id", keys)
.select()
.then((rows) =>
rows.map((x) => {
if (x.username) this.userByUsername.prime(x.username, x);
return x;
})
)
.then((rows) => mapTo(rows, keys, (x) => x.id))
);
userByUsername = new DataLoader<string, User | null>((keys) =>
db
.table<User>("user")
.whereIn("username", keys)
.select()
.then((rows) =>
rows.map((x) => {
this.userById.prime(x.id, x);
return x;
})
)
.then((rows) => mapTo(rows, keys, (x) => x.username))
);
identitiesByUserId = new DataLoader<string, Identity[]>((keys) =>
db
.table<Identity>("identity")
.whereIn("user_id", keys)
.select()
.then((rows) => mapToMany(rows, keys, (x) => x.user_id))
);
}