-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpsu.mjs
More file actions
139 lines (128 loc) · 4.33 KB
/
psu.mjs
File metadata and controls
139 lines (128 loc) · 4.33 KB
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
import {v4 as uuidv4} from "uuid"
import {getAccessToken} from "./auth.mjs"
import pino from "pino"
const logger = pino()
let oauthToken
let tokenExpiryTime
export function getBody(
isValid = true,
status = "in-progress",
odsCode = "C9Z10",
nhsNumber = "9449304130",
businessStatus = "With Pharmacy",
) {
// If this is intended to be a failed request, mangle the prescription ID.
const prescriptionID = isValid ? shortPrescId() : invalidShortPrescId();
const task_identifier = uuidv4()
const prescriptionOrderItemNumber = uuidv4()
const currentTimestamp = new Date().toISOString()
const body = {
resourceType: "Bundle",
type: "transaction",
entry: [
{
fullUrl: `urn:uuid:${task_identifier}`,
resource: {
resourceType: "Task",
id: `${task_identifier}`,
basedOn: [
{
identifier: {
system: "https://fhir.nhs.uk/Id/prescription-order-number",
value: prescriptionID
}
}
],
status: status,
businessStatus: {
coding: [
{
system: "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt",
code: businessStatus
}
]
},
intent: "order",
focus: {
identifier: {
system: "https://fhir.nhs.uk/Id/prescription-order-item-number",
value: prescriptionOrderItemNumber
}
},
for: {
identifier: {
system: "https://fhir.nhs.uk/Id/nhs-number",
value: nhsNumber
}
},
lastModified: currentTimestamp,
owner: {
identifier: {
system: "https://fhir.nhs.uk/Id/ods-organization-code",
value: odsCode
}
}
},
request: {
method: "POST",
url: "Task"
}
}
]
}
return body
}
function shortPrescId() {
const _PRESC_CHECKDIGIT_VALUES = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+"
const hexString = uuidv4().replace(/-/g, "").toUpperCase()
const first = hexString.substring(0, 6)
const middle = "A12345"
const last = hexString.substring(12, 17)
let prescriptionID = `${first}-${middle}-${last}`
const prscID = prescriptionID.replace(/-/g, "")
const prscIDLength = prscID.length
let runningTotal = 0
const strings = prscID.split("")
strings.forEach((character, index) => {
runningTotal = runningTotal + parseInt(character, 36) * 2 ** (prscIDLength - index)
})
const checkValue = (38 - (runningTotal % 37)) % 37
const checkDigit = _PRESC_CHECKDIGIT_VALUES.substring(checkValue, checkValue + 1)
prescriptionID += checkDigit
return prescriptionID
}
function invalidShortPrescId() {
// Generate an invalid prescription ID by removing the last character
let invalidId = shortPrescId();
invalidId = invalidId.slice(0, -1); // Remove last character to invalidate
return invalidId;
}
export async function getSharedAuthToken(vuContext) {
// This checks if we have a valid oauth token and if not gets a new one
if (!tokenExpiryTime || tokenExpiryTime < Date.now()) {
logger.info("Token has expired. Fetching new token")
logger.info(`Current expiry time: ${tokenExpiryTime}`)
// Fetch keys from environment variables
const privateKey = process.env.psu_private_key
const api_key = process.env.psu_api_key
const kid = process.env.psu_kid
// And use them to fetch the access token
const response = await getAccessToken(logger, vuContext.vars.target, privateKey, api_key, kid)
tokenExpiryTime = Date.now() + response.expires_in * 1000
oauthToken = response.access_token
logger.info(`New expiry time: ${tokenExpiryTime}`)
} else {
logger.info("Using cached token")
}
vuContext.vars.authToken = oauthToken
}
export async function getPSUParams(requestParams, vuContext) {
// Some requests are intended to be invalid ones.
// Check if this request is supposed to be valid, and fetch an appropriate body
const isValid = vuContext.scenario.tags.isValid
const body = getBody(isValid)
// This sets the body of the request and some variables so headers are unique
requestParams.json = body
vuContext.vars.x_request_id = uuidv4()
vuContext.vars.x_correlation_id = uuidv4()
}