@@ -17,8 +17,13 @@ import {
1717  EntraInvitationError , 
1818  InternalServerError , 
1919  NotFoundError , 
20+   ValidationError , 
2021}  from  "../../common/errors/index.js" ; 
21- import  {  DynamoDBClient ,  PutItemCommand  }  from  "@aws-sdk/client-dynamodb" ; 
22+ import  { 
23+   DynamoDBClient , 
24+   PutItemCommand , 
25+   UpdateItemCommand , 
26+ }  from  "@aws-sdk/client-dynamodb" ; 
2227import  { 
2328  GENERIC_CACHE_SECONDS , 
2429  genericConfig , 
@@ -96,19 +101,59 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
96101          message : "Could not find token payload and/or username." , 
97102        } ) ; 
98103      } 
104+       const  netId  =  request . username . replace ( "@illinois.edu" ,  "" ) ; 
105+       if  ( netId . includes ( "@" ) )  { 
106+         request . log . error ( 
107+           `Found username ${ request . username }   which cannot be turned into NetID via simple replacement.` , 
108+         ) ; 
109+         throw  new  ValidationError ( { 
110+           message : "Username could not be parsed." , 
111+         } ) ; 
112+       } 
99113      const  userOid  =  request . tokenPayload . oid ; 
100114      const  entraIdToken  =  await  getEntraIdToken ( { 
101115        clients : await  getAuthorizedClients ( ) , 
102116        clientId : fastify . environmentConfig . AadValidClientId , 
103117        secretName : genericConfig . EntraSecretName , 
104118        logger : request . log , 
105119      } ) ; 
106-       await  patchUserProfile ( 
120+       const  {  discordUsername }  =  request . body ; 
121+       const  ddbUpdateCommand  =  fastify . dynamoClient . send ( 
122+         new  UpdateItemCommand ( { 
123+           TableName : genericConfig . UserInfoTable , 
124+           Key : { 
125+             id : { 
126+               S : request . username , 
127+             } , 
128+           } , 
129+           UpdateExpression : `SET #netId = :netId, #updatedAt = :updatedAt, #firstName = :firstName, #lastName = :lastName ${ discordUsername  ? ", #discordUsername = :discordUsername"  : "" }  ` , 
130+           ExpressionAttributeNames : { 
131+             "#netId" : "netId" , 
132+             "#updatedAt" : "updatedAt" , 
133+             "#firstName" : "firstName" , 
134+             "#lastName" : "lastName" , 
135+             ...( discordUsername 
136+               ? {  "#discordUsername" : "discordUsername"  } 
137+               : { } ) , 
138+           } , 
139+           ExpressionAttributeValues : { 
140+             ":netId" : {  S : netId  } , 
141+             ":firstName" : {  S : request . body . givenName  } , 
142+             ":lastName" : {  S : request . body . surname  } , 
143+             ":updatedAt" : {  S : new  Date ( ) . toISOString ( )  } , 
144+             ...( discordUsername 
145+               ? {  ":discordUsername" : {  S : discordUsername  }  } 
146+               : { } ) , 
147+           } , 
148+         } ) , 
149+       ) ; 
150+       const  entraUpdateCommand  =  patchUserProfile ( 
107151        entraIdToken , 
108152        request . username , 
109153        userOid , 
110154        request . body , 
111155      ) ; 
156+       await  Promise . all ( [ ddbUpdateCommand ,  entraUpdateCommand ] ) ; 
112157      reply . status ( 201 ) . send ( ) ; 
113158    } , 
114159  ) ; 
@@ -170,7 +215,7 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
170215        } ) ; 
171216        const  groupMembers  =  listGroupMembers ( entraIdToken ,  groupId ) ; 
172217        const  command  =  new  PutItemCommand ( { 
173-           TableName : `${ genericConfig . IAMTablePrefix } - grouproles` , 
218+           TableName : `${ genericConfig . IAMTablePrefix }  -  grouproles` , 
174219          Item : marshall ( { 
175220            groupUuid : groupId , 
176221            roles : request . body . roles , 
@@ -190,7 +235,7 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
190235        await  fastify . dynamoClient . send ( command ) ; 
191236        await  logPromise ; 
192237        fastify . nodeCache . set ( 
193-           `grouproles- ${ groupId }  ` , 
238+           `grouproles -  ${ groupId }  ` , 
194239          request . body . roles , 
195240          GENERIC_CACHE_SECONDS , 
196241        ) ; 
@@ -202,7 +247,7 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
202247        } ) ; 
203248        reply . send ( {  message : "OK"  } ) ; 
204249      }  catch  ( e : unknown )  { 
205-         fastify . nodeCache . del ( `grouproles- ${ groupId }  ` ) ; 
250+         fastify . nodeCache . del ( `grouproles -  ${ groupId }  ` ) ; 
206251        if  ( e  instanceof  BaseError )  { 
207252          throw  e ; 
208253        } 
@@ -462,7 +507,7 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
462507              content : ` 
463508Hello, 
464509
465- We're letting you know that you have been added to the "${ groupMetadata . displayName }  " access group by ${ request . username }  . Changes may take up to 2 hours to reflect in all systems. 
510+            We're letting you know that you have been added to the "${ groupMetadata . displayName }  " access group by ${ request . username }  . Changes may take up to 2 hours to reflect in all systems.
466511
467512No action is required from you at this time. 
468513          ` , 
@@ -484,7 +529,7 @@ No action is required from you at this time.
484529              content : ` 
485530Hello, 
486531
487- We're letting you know that you have been removed from the "${ groupMetadata . displayName }  " access group by ${ request . username }  . 
532+            We're letting you know that you have been removed from the "${ groupMetadata . displayName }  " access group by ${ request . username }  .
488533
489534No action is required from you at this time. 
490535          ` , 
0 commit comments