Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 4x 4x 4x 4x 3x 3x 2x 2x 2x 2x 2x 8x 8x 8x 8x 8x 8x 8x 8x 1x 1x 7x 6x 6x 6x 6x 1x 1x 5x 4x 4x 4x 4x 4x 4x 2x 2x 2x 2x 2x 2x | import {
InviteId,
Invite,
InviteRepository,
MembershipRepository,
MembershipService,
} from '@models';
import db from '@db';
import {
MembershipNotFoundError,
NotMemberOfGroupError,
UnauthorizedError,
CouldNotAssignToGroupError,
} from '@errors';
import debug from 'debug';
import {bindUser} from '@util/user-bound-logging';
/**
* Logging method for errors.
*/
const error = debug('group-car:invite:service:error');
/**
* Method for logging.
*/
const log = debug('group-car:invite:service');
/**
* Service for invites.
*/
export const InviteService = {
/**
* Assigns the given user to the group with the given groupId.
*
* Assigns the user only if the user has an invite for the group.
* @param currentUser - The user to assign to a group.
* Should be the currently logged in user
* @param groupId - The id of the group the user should be assigned to
*/
async assignUserToGroup(
currentUser: Express.User,
groupId: number,
): Promise<void> {
const userLog = bindUser(log, currentUser.id);
const userError = bindUser(error, currentUser.id);
userLog('Request to use invite to join group %d', groupId);
const inviteId = {
userId: currentUser.id,
groupId,
};
userLog('Check if the invite %o exists', inviteId);
// Check if the user has an invite for the group, throws if it doesn't exist
await InviteRepository.findById(inviteId);
/*
* Delete invitation and create membership.
* To avoid that only one of those is executed (other one throws)
* do it in a transaction.
*/
const transaction = await db.transaction();
// Delete invitation
try {
userLog('Delete invite %o', inviteId);
await InviteRepository.deleteById(inviteId, {transaction});
userLog('Create membership for group %d', groupId);
await MembershipRepository.create(
currentUser,
groupId,
false,
{transaction},
);
} catch (e) {
userError(`Could not assign user ` +
`to group %d: %s`, groupId, e);
await transaction.rollback();
throw new CouldNotAssignToGroupError(inviteId.userId, inviteId.groupId);
}
await transaction.commit();
userLog('Successfully joined group %d', groupId);
},
/**
* Searches for an invite with the given id.
*
* @param currentUser - The currently logged-in user
* @param id - The id for which to search
*
* @throws {@link UnauthorizedError}
* If `currentUser` is neither a member of the group nor
* user mentioned in the invite
*/
async findById(
currentUser: Express.User,
id: InviteId,
): Promise<Invite> {
const userLog = bindUser(log, currentUser.id);
const userError = bindUser(error, currentUser.id);
userLog('Request to find invite %o', id);
// Get memberships of user
let membership = null;
try {
userLog('Check if user is a member of group %d', id.groupId);
membership = await MembershipService.findById(
currentUser,
{
userId: currentUser.id,
groupId: id.groupId,
},
);
} catch (_) {}
if (
// Current user is not user of invite
currentUser.id !== id.userId &&
// Current user has no membership with group
membership === null) {
userError('User is not the the invitee and not a member of the group');
throw new UnauthorizedError('Not authorized to request this invite');
}
return InviteRepository.findById(id);
},
/**
* Gets a list of all invites for the given user.
*
* This method will only return the list if the current user
* has the same id as the given userId.
* @param currentUser - The currently logged in user.
* @param userId - The id of the user of whom the
* list of invites should be returned
*/
async findAllForUser(
currentUser: Express.User,
userId: number,
): Promise<Invite[]> {
const userLog = bindUser(log, currentUser.id);
const userError = bindUser(error, currentUser.id);
userLog('Requests to find all invites of user %d', userId);
if (currentUser.id !== userId) {
userError('Is not the specified user %d', userId);
throw new UnauthorizedError();
}
return InviteRepository.findAllForUser(
userId,
{
withGroupData: true,
withInvitedByData: true,
},
);
},
/**
* Gets all invites of the specified group.
*
* If the specified user is not a member of the specified
* group an `NotMemberOfGroupError` will be thrown.
* @param currentUser - The user which request this
* @param groupId - The id of the group
*/
async findAllForGroup(
currentUser: Express.User,
groupId: number,
): Promise<Invite[]> {
const userLog = bindUser(log, currentUser.id);
const userError = bindUser(error, currentUser.id);
userLog('Find all invites for group %d', groupId);
// Check if current user is a member of the group
try {
userLog('Check if member of group %d', groupId);
await MembershipService.findById(
currentUser, {
userId: currentUser.id,
groupId,
},
);
userLog('Is member of group %d', groupId);
} catch (e) {
Eif (e instanceof MembershipNotFoundError) {
userError(
'Is not a member of group %d',
groupId,
);
throw new NotMemberOfGroupError();
} else {
userError(
'Unexpected error while checking membership of group %d: %s',
groupId,
e,
);
throw e;
}
}
userLog('Get all invites for group %d', groupId);
return InviteRepository.findAllForGroup(
groupId,
{
withInvitedByData: true,
withUserData: true,
},
);
},
};
|