Skip to content

Commit 7c67b6c

Browse files
committed
restored guest upgrade behavior
1 parent 3a7b4ca commit 7c67b6c

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

lib/routes/guests.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ guestsRouter
5757

5858
return ctx.body = guest;
5959
} catch(e) {
60-
if(e.code === 'INVALID') throw ctx.throw(400);
60+
if(e.code === 'INVALID') throw ctx.throw(400, e, {expose: false});
6161

6262
throw ctx.throw(e);
6363
}

lib/services/guests.ts

+36-5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const guestColumns = [
3636
'admission_tier',
3737
'created',
3838
'updated',
39+
'updated_by',
3940
'created_by',
4041
'created_reason',
4142
'status',
@@ -130,7 +131,7 @@ export async function getCurrentGuestTicketQrCode(guestId) {
130131
export async function updateGuest(id, updates) {
131132
for(const u in updates) {
132133
// Update whitelist
133-
if(!['status', 'firstName', 'lastName', 'updatedBy', 'meta'].includes(u)) throw new GuestsServiceError('Invalid guest data', 'INVALID');
134+
if(!['status', 'firstName', 'lastName', 'updatedBy', 'meta', 'admissionTier'].includes(u)) throw new GuestsServiceError('Invalid guest data', 'INVALID');
134135
}
135136

136137
if(Object.keys(updates).length === 1 && updates.updatedBy) throw new GuestsServiceError('Invalid guest data', 'INVALID');
@@ -147,9 +148,39 @@ export async function updateGuest(id, updates) {
147148

148149
if(Object.keys(updates).length === 1 && updates.updatedBy) throw new GuestsServiceError('Invalid product data', 'INVALID');
149150

150-
let guest;
151+
// Prevent accidental downgrading of a guest below their purchased tier
152+
let minimumAdmissionTier;
153+
if (updates.admissionTier) {
154+
try {
155+
[minimumAdmissionTier] = await sql`
156+
SELECT p.admission_tier
157+
FROM guests AS g
158+
LEFT JOIN order_items AS oi
159+
ON g.order_id = oi.order_id
160+
LEFT JOIN products AS p
161+
ON oi.product_id = p.id
162+
AND g.event_id = p.event_id
163+
WHERE g.id = ${id}
164+
AND p.id IS NOT NULL
165+
`;
166+
} catch(e) {
167+
throw new GuestsServiceError('Could not query guest', 'UNKNOWN', e);
168+
}
169+
170+
if(!minimumAdmissionTier) throw new GuestsServiceError('Guest not found', 'NOT_FOUND');
171+
172+
// TODO: make this a tiered access list similar to user roles so we can support multiple levels in the future
173+
if(
174+
minimumAdmissionTier.admissionTier === 'vip' &&
175+
updates.admissionTier === 'general'
176+
) {
177+
throw new GuestsServiceError('Cannot downgrade VIP guest to general admission', 'INVALID');
178+
}
179+
}
180+
181+
let updatedGuest;
151182
try {
152-
[guest] = await sql`
183+
[updatedGuest] = await sql`
153184
UPDATE guests
154185
SET ${sql(updates)}, updated = now()
155186
WHERE id = ${id}
@@ -159,9 +190,9 @@ export async function updateGuest(id, updates) {
159190
throw new GuestsServiceError('Could not update guest', 'UNKNOWN', e);
160191
}
161192

162-
if(!guest) throw new GuestsServiceError('guest not found', 'NOT_FOUND');
193+
if(!updatedGuest) throw new GuestsServiceError('guest not found', 'NOT_FOUND');
163194

164-
return guest;
195+
return updatedGuest;
165196
}
166197

167198
export async function archiveGuest(id, updatedBy) {

0 commit comments

Comments
 (0)