11import { FastifyPluginAsync } from "fastify" ;
22import rateLimiter from "api/plugins/rateLimiter.js" ;
33import {
4+ roomRequestBaseSchema ,
45 RoomRequestFormValues ,
56 roomRequestPostResponse ,
67 roomRequestSchema ,
@@ -10,19 +11,81 @@ import { AppRoles } from "common/roles.js";
1011import { zodToJsonSchema } from "zod-to-json-schema" ;
1112import {
1213 BaseError ,
14+ DatabaseFetchError ,
1315 DatabaseInsertError ,
1416 InternalServerError ,
1517} from "common/errors/index.js" ;
16- import { PutItemCommand } from "@aws-sdk/client-dynamodb" ;
18+ import { PutItemCommand , QueryCommand } from "@aws-sdk/client-dynamodb" ;
1719import { genericConfig } from "common/config.js" ;
18- import { marshall } from "@aws-sdk/util-dynamodb" ;
20+ import { marshall , unmarshall } from "@aws-sdk/util-dynamodb" ;
21+ import { z } from "zod" ;
1922
2023const roomRequestRoutes : FastifyPluginAsync = async ( fastify , _options ) => {
2124 await fastify . register ( rateLimiter , {
22- limit : 5 ,
25+ limit : 20 ,
2326 duration : 30 ,
2427 rateLimitIdentifier : "roomRequests" ,
2528 } ) ;
29+ fastify . get < {
30+ Body : undefined ;
31+ Params : { semesterId : string } ;
32+ } > (
33+ "/:semesterId" ,
34+ {
35+ schema : {
36+ response : {
37+ 200 : zodToJsonSchema (
38+ z . array (
39+ roomRequestBaseSchema . extend ( { requestId : z . string ( ) . uuid ( ) } ) ,
40+ ) ,
41+ ) ,
42+ } ,
43+ } ,
44+ onRequest : async ( request , reply ) => {
45+ await fastify . authorize ( request , reply , [ AppRoles . ROOM_REQUEST_CREATE ] ) ;
46+ } ,
47+ } ,
48+ async ( request , reply ) => {
49+ const semesterId = request . params . semesterId ;
50+ if ( ! request . username ) {
51+ throw new InternalServerError ( {
52+ message : "Could not retrieve username." ,
53+ } ) ;
54+ }
55+ let command : QueryCommand ;
56+ if ( request . userRoles ?. has ( AppRoles . BYPASS_OBJECT_LEVEL_AUTH ) ) {
57+ command = new QueryCommand ( {
58+ TableName : genericConfig . RoomRequestsTableName ,
59+ KeyConditionExpression : "semesterId = :semesterValue" ,
60+ ExpressionAttributeValues : {
61+ ":semesterValue" : { S : semesterId } ,
62+ } ,
63+ } ) ;
64+ } else {
65+ command = new QueryCommand ( {
66+ TableName : genericConfig . RoomRequestsTableName ,
67+ KeyConditionExpression : "semesterId = :semesterValue" ,
68+ FilterExpression : "begins_with(#hashKey, :username)" ,
69+ ExpressionAttributeNames : {
70+ "#hashKey" : "userId#requestId" ,
71+ } ,
72+ ProjectionExpression : "requestId, host, title" ,
73+ ExpressionAttributeValues : {
74+ ":semesterValue" : { S : semesterId } ,
75+ ":username" : { S : request . username } ,
76+ } ,
77+ } ) ;
78+ }
79+ const response = await fastify . dynamoClient . send ( command ) ;
80+ if ( ! response . Items ) {
81+ throw new DatabaseFetchError ( {
82+ message : "Could not get room requests." ,
83+ } ) ;
84+ }
85+ const items = response . Items . map ( ( x ) => unmarshall ( x ) ) ;
86+ return reply . status ( 200 ) . send ( items ) ;
87+ } ,
88+ ) ;
2689 fastify . post < { Body : RoomRequestFormValues } > (
2790 "/" ,
2891 {
0 commit comments