-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathusersMiddleware.ts
117 lines (105 loc) · 3.48 KB
/
usersMiddleware.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
import { NextFunction, Response } from 'express';
import { z } from 'zod';
import { User } from '../entities/User';
import { getLoggers, getTraceId } from '../helpers/loggingHelpers';
import { UserParticipantRequest } from '../services/participantsService';
import { findUserByEmail, UserRequest } from '../services/usersService';
import { isSuperUser, isUid2Support } from './userRoleMiddleware';
export const isUserBelongsToParticipant = async (
email: string,
participantId: number,
traceId: string
) => {
const userWithParticipants = await User.query()
.findOne({ email, deleted: 0 })
.modify('withParticipants');
if (!userWithParticipants) {
const { errorLogger } = getLoggers();
errorLogger.error(`User with email ${email} not found`, traceId);
return false;
}
for (const participant of userWithParticipants.participants!) {
if (participant.id === participantId) {
return true;
}
}
return false;
};
export const canUserAccessParticipant = async (
requestingUserEmail: string,
participantId: number,
traceId: string
) => {
return (
(await isUid2Support(requestingUserEmail)) ||
(await isUserBelongsToParticipant(requestingUserEmail, participantId, traceId))
);
};
export const enrichCurrentUser = async (req: UserRequest, res: Response, next: NextFunction) => {
const userEmail = req.auth?.payload?.email as string;
const user = await findUserByEmail(userEmail);
if (!user) {
return res.status(404).send([{ message: 'The user cannot be found.' }]);
}
if (user.locked) {
return res.status(403).send([{ message: 'Unauthorized.' }]);
}
req.user = user;
return next();
};
export const enrichUserWithSupportRoles = async (user: User) => {
const userIsUid2Support = await isUid2Support(user.email);
const userIsSuperUser = await isSuperUser(user.email);
return {
...user,
isUid2Support: userIsUid2Support,
isSuperUser: userIsSuperUser,
};
};
export const enrichUserWithSuperUser = async (user: User) => {
const userIsSuperUser = await isSuperUser(user.email);
return {
...user,
isSuperUser: userIsSuperUser,
};
};
const userIdSchema = z.object({
userId: z.coerce.number(),
});
export const verifyAndEnrichUser = async (
req: UserParticipantRequest,
res: Response,
next: NextFunction
) => {
const { userId } = userIdSchema.parse(req.params);
const { participant } = req;
const traceId = getTraceId(req);
const targetUser = await User.query().findById(userId).modify('withParticipants');
if (!targetUser) {
return res.status(404).send([{ message: 'The user cannot be found.' }]);
}
if (targetUser.participants?.length === 0) {
return res.status(404).send([{ message: 'The participant for that user cannot be found.' }]);
}
const targetUserBelongsToParticipant = await isUserBelongsToParticipant(
targetUser.email,
participant!.id,
traceId
);
if (!targetUserBelongsToParticipant) {
const { infoLogger } = getLoggers();
infoLogger.info('Target user does not belong to participant', traceId);
return res.status(404).send([{ message: 'The user cannot be found.' }]);
}
const requestingUserEmail = req.auth?.payload?.email as string;
const canRequestingUserAccessParticipant = await canUserAccessParticipant(
requestingUserEmail,
participant!.id,
traceId
);
if (!canRequestingUserAccessParticipant) {
return res.status(403).send([{ message: 'You do not have permission to that user account.' }]);
}
req.user = targetUser;
return next();
};