-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
233 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
lib/lambda/submit/submissionPayloads/temporary-extension.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// can/should add the additional frontend checks here | ||
|
||
import { events } from "shared-types/events"; | ||
import { | ||
isAuthorized, | ||
getAuthDetails, | ||
lookupUserAttributes, | ||
} from "../../../libs/api/auth/user"; | ||
import { type APIGatewayEvent } from "aws-lambda"; | ||
import { itemExists } from "libs/api/package"; | ||
|
||
export const temporaryExtension = async (event: APIGatewayEvent) => { | ||
if (!event.body) return; | ||
|
||
const parsedResult = events["temporary-extension"].baseSchema.safeParse( | ||
JSON.parse(event.body), | ||
); | ||
if (!parsedResult.success) { | ||
throw parsedResult.error; | ||
} | ||
|
||
// This is the backend check for auth | ||
if (!(await isAuthorized(event, parsedResult.data.id.slice(0, 2)))) { | ||
throw "Unauthorized"; | ||
} | ||
|
||
// This is the backend check for the item already existing | ||
if (await itemExists({ id: parsedResult.data.id })) { | ||
throw "Item Already Exists"; | ||
} | ||
|
||
if (!(await itemExists({ id: parsedResult.data.waiverNumber }))) { | ||
throw "Original Waiver does not exist"; | ||
} | ||
|
||
const authDetails = getAuthDetails(event); | ||
const userAttr = await lookupUserAttributes( | ||
authDetails.userId, | ||
authDetails.poolId, | ||
); | ||
const submitterEmail = userAttr.email; | ||
const submitterName = `${userAttr.given_name} ${userAttr.family_name}`; | ||
|
||
const transformedData = events["temporary-extension"].schema.parse({ | ||
...parsedResult.data, | ||
submitterName, | ||
submitterEmail, | ||
timestamp: Date.now(), | ||
}); | ||
|
||
return transformedData; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
lib/packages/shared-types/opensearch/changelog/transforms/temporary-extension.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { events } from "shared-types"; | ||
export const transform = (offset: number) => { | ||
return events["temporary-extension"].schema.transform((data) => { | ||
const attachments = Object.entries(data.attachments).flatMap( | ||
//eslint-disable-next-line | ||
([_title, attachment]) => { | ||
// Check if 'attachment' exists and has a non-empty 'files' array | ||
if ( | ||
attachment && | ||
Array.isArray(attachment.files) && | ||
attachment.files.length > 0 | ||
) { | ||
// Map each file in 'files' array to the desired shape | ||
return attachment.files.map((file) => ({ | ||
filename: file.filename, | ||
title: attachment.label, | ||
bucket: file.bucket, | ||
key: file.key, | ||
uploadDate: file.uploadDate, | ||
})); | ||
} | ||
// If there are no files or the files array is empty, return an empty array | ||
return []; | ||
}, | ||
); | ||
return { | ||
...data, | ||
attachments, | ||
packageId: data.id, | ||
id: `${data.id}-${offset}`, | ||
}; | ||
}); | ||
}; | ||
|
||
export type Schema = ReturnType<typeof transform>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
lib/packages/shared-types/opensearch/main/transforms/temporary-extension.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { events, SEATOOL_STATUS, getStatus } from "shared-types"; | ||
import { | ||
getNextBusinessDayTimestamp, | ||
seaToolFriendlyTimestamp, | ||
} from "../../../../shared-utils/seatool-date-helper"; | ||
|
||
export const transform = () => { | ||
// any adhoc logic | ||
return events["temporary-extension"].schema.transform((data) => { | ||
const { stateStatus, cmsStatus } = getStatus(SEATOOL_STATUS.PENDING); | ||
const timestampDate = new Date(data.timestamp); | ||
const todayEpoch = seaToolFriendlyTimestamp(timestampDate); | ||
const nextBusinessDayEpoch = getNextBusinessDayTimestamp(timestampDate); | ||
|
||
return { | ||
additionalInformation: data.additionalInformation, | ||
authority: data.authority, | ||
changedDate: new Date(data.timestamp).toISOString(), | ||
cmsStatus, | ||
description: null, | ||
id: data.id, | ||
makoChangedDate: new Date(data.timestamp).toISOString(), | ||
origin: "OneMAC", | ||
raiWithdrawEnabled: false, // Set to false for new submissions | ||
seatoolStatus: SEATOOL_STATUS.PENDING, | ||
state: data.id.split("-")[0], | ||
stateStatus, | ||
statusDate: new Date(todayEpoch).toISOString(), | ||
subject: null, | ||
submissionDate: new Date(nextBusinessDayEpoch).toISOString(), | ||
submitterEmail: data.submitterEmail, | ||
submitterName: data.submitterName, | ||
actionType: data.actionType, | ||
}; | ||
}); | ||
}; | ||
|
||
export type Schema = ReturnType<typeof transform>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { events } from "shared-types/events"; | ||
import { isAuthorizedState } from "@/utils"; | ||
import { getItem, idIsApproved, itemExists } from "@/api"; | ||
import { z } from "zod"; | ||
|
||
export const formSchema = events["temporary-extension"].baseSchema | ||
.extend({ | ||
id: events["temporary-extension"].baseSchema.shape.id | ||
.refine(isAuthorizedState, { | ||
message: | ||
"You can only submit for a state you have access to. If you need to add another state, visit your IDM user profile to request access.", | ||
}) | ||
.refine(async (value) => !(await itemExists(value)), { | ||
message: | ||
"According to our records, this Temporary Extension Request Number already exists. Please check the Temporary Extension Request Number and try entering it again.", | ||
}), | ||
waiverNumber: events["temporary-extension"].baseSchema.shape.waiverNumber | ||
.refine(async (value) => await itemExists(value), { | ||
message: | ||
"According to our records, this Approved Initial or Renewal Waiver Number does not yet exist. Please check the Approved Initial or Renewal Waiver Number and try entering it again.", | ||
}) | ||
.refine(async (value) => idIsApproved(value), { | ||
message: | ||
"According to our records, this Approved Initial or Renewal Waiver Number is not approved. You must supply an approved Initial or Renewal Waiver Number.", | ||
}), | ||
}) | ||
.superRefine(async (data, ctx) => { | ||
// Check that the authorities match | ||
try { | ||
const originalWaiverData = await getItem(data.waiverNumber); | ||
if (originalWaiverData._source.authority !== data.authority) { | ||
ctx.addIssue({ | ||
message: | ||
"The selected Temporary Extension Type does not match the Approved Initial or Renewal Waiver's type.", | ||
code: z.ZodIssueCode.custom, | ||
fatal: true, | ||
path: ["authority"], | ||
}); | ||
} | ||
|
||
// Check that the original waiver and temp extension have the same id up to the last period | ||
const waiverNumberPrefix = data.waiverNumber.substring( | ||
0, | ||
data.waiverNumber.lastIndexOf("."), | ||
); | ||
const idPrefix = data.id.substring(0, data.id.lastIndexOf(".")); | ||
if (waiverNumberPrefix !== idPrefix) { | ||
ctx.addIssue({ | ||
message: | ||
"The Approved Initial or Renewal Waiver Number and the Temporary Extension Request Number must be identical until the last period.", | ||
code: z.ZodIssueCode.custom, | ||
fatal: true, | ||
path: ["id"], | ||
}); | ||
} | ||
return z.never; | ||
} catch (error) { | ||
// If we've failed here, the item does not exist, and the originalWaiverNumberSchema validation will throw the correct errors. | ||
console.error(error); | ||
return z.never; | ||
} | ||
}); | ||
|
||
// export type Schema = Awaited<ReturnType<typeof transform>>; |