Skip to content

Commit 60e7a33

Browse files
Added support for additional security schemes and hidden paths in spec publish
1 parent 37e1827 commit 60e7a33

2 files changed

Lines changed: 84 additions & 11 deletions

File tree

packages/cdkConstructs/src/specifications/deployApi.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type ApiConfig = {
1515
clientPrivateKeyExportName: string
1616
proxygenPrivateKeyExportName: string
1717
proxygenKid: string
18+
hiddenPaths: Array<string>
1819
}
1920

2021
export async function deployApi(
@@ -30,7 +31,8 @@ export async function deployApi(
3031
clientCertExportName,
3132
clientPrivateKeyExportName,
3233
proxygenPrivateKeyExportName,
33-
proxygenKid
34+
proxygenKid,
35+
hiddenPaths
3436
}: ApiConfig,
3537
dryRun: boolean
3638
): Promise<void> {
@@ -66,16 +68,23 @@ export async function deployApi(
6668
}
6769
spec.info.version = version
6870
spec["x-nhsd-apim"].target.url = `https://${stackName}.${awsEnvironment}.eps.national.nhs.uk`
71+
72+
function replaceSchemeRefs(domain: string) {
73+
const schemes = ["nhs-cis2-aal3", "nhs-login-p9", "app-level3", "app-level0"]
74+
for (const scheme of schemes) {
75+
if (spec.components.securitySchemes[scheme]) {
76+
spec.components.securitySchemes[scheme] = {
77+
"$ref": `https://${domain}/components/securitySchemes/${scheme}`
78+
}
79+
}
80+
}
81+
}
6982
if (apigeeEnvironment === "prod") {
7083
spec.servers = [ {url: `https://api.service.nhs.uk/${instance}`} ]
71-
spec.components.securitySchemes["nhs-cis2-aal3"] = {
72-
"$ref": "https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-cis2-aal3"
73-
}
84+
replaceSchemeRefs("proxygen.prod.api.platform.nhs.uk")
7485
} else {
7586
spec.servers = [ {url: `https://${apigeeEnvironment}.api.service.nhs.uk/${instance}`} ]
76-
spec.components.securitySchemes["nhs-cis2-aal3"] = {
77-
"$ref": "https://proxygen.ptl.api.platform.nhs.uk/components/securitySchemes/nhs-cis2-aal3"
78-
}
87+
replaceSchemeRefs("proxygen.ptl.api.platform.nhs.uk")
7988
}
8089
if (apigeeEnvironment.includes("sandbox")) {
8190
delete spec["x-nhsd-apim"]["target-attributes"] // Resolve issue with sandbox trying to look up app name
@@ -132,6 +141,11 @@ export async function deployApi(
132141
spec_publish_env = "uat"
133142
}
134143
if (spec_publish_env) {
144+
for (const path of hiddenPaths) {
145+
if (spec.paths[path]) {
146+
delete spec.paths[path]
147+
}
148+
}
135149
await invokeLambda(spec_publish_lambda, {
136150
apiName,
137151
environment: spec_publish_env,

packages/cdkConstructs/tests/specifications/deployApi.test.ts

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ vi.mock("../../src/config", async (importOriginal) => {
4040
}
4141
})
4242

43-
function createSpec() {
43+
type SpecOverrides = {
44+
securitySchemes?: Record<string, unknown>,
45+
paths?: Record<string, unknown>
46+
}
47+
48+
function createSpec(overrides: SpecOverrides = {}) {
4449
return {
4550
info: {title: "EPS API", version: "0.0.1"},
4651
"x-nhsd-apim": {
@@ -52,10 +57,9 @@ function createSpec() {
5257
"target-attributes": {app: "eps"}
5358
},
5459
components: {
55-
securitySchemes: {
56-
"nhs-cis2-aal3": {}
57-
}
60+
securitySchemes: overrides.securitySchemes || {"nhs-cis2-aal3": {}}
5861
},
62+
paths: overrides.paths || {},
5963
servers: []
6064
}
6165
}
@@ -80,6 +84,7 @@ function buildConfig(overrides: Partial<ApiConfig> = {}): ApiConfig {
8084
clientPrivateKeyExportName: "clientKey",
8185
proxygenPrivateKeyExportName: "proxygenKey",
8286
proxygenKid: "kid-123",
87+
hiddenPaths: [],
8388
...overrides
8489
}
8590
}
@@ -211,6 +216,60 @@ describe("deployApi", () => {
211216
.toBe("https://sandbox.api.service.nhs.uk/eps")
212217
})
213218

219+
test("replaces all supported security scheme refs", async () => {
220+
const spec = createSpec({
221+
securitySchemes: {
222+
"nhs-cis2-aal3": {},
223+
"nhs-login-p9": {},
224+
"app-level3": {},
225+
"app-level0": {}
226+
}
227+
})
228+
await deployApi(
229+
buildConfig({
230+
specification: JSON.stringify(spec),
231+
apigeeEnvironment: "prod",
232+
awsEnvironment: "prod",
233+
stackName: "eps-prod-stack",
234+
proxygenKid: "kid-prod"
235+
}),
236+
false
237+
)
238+
const specPayload = payloadFromCall(1)
239+
const schemes = [
240+
"nhs-cis2-aal3",
241+
"nhs-login-p9",
242+
"app-level3",
243+
"app-level0"
244+
]
245+
for (const scheme of schemes) {
246+
expect(specPayload.specDefinition.components.securitySchemes[scheme].$ref)
247+
.toBe(`https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/${scheme}`)
248+
}
249+
})
250+
251+
test("removes hidden paths from published spec", async () => {
252+
const spec = createSpec({
253+
paths: {
254+
"/visible": {get: {}},
255+
"/hidden": {post: {}}
256+
}
257+
})
258+
await deployApi(
259+
buildConfig({
260+
specification: JSON.stringify(spec),
261+
apigeeEnvironment: "int",
262+
stackName: "eps-int-stack",
263+
proxygenKid: "kid-int",
264+
hiddenPaths: ["/hidden"]
265+
}),
266+
false
267+
)
268+
const publishPayload = payloadFromCall(2)
269+
expect(publishPayload.specDefinition.paths["/hidden"]).toBeUndefined()
270+
expect(publishPayload.specDefinition.paths["/visible"]).toBeDefined()
271+
})
272+
214273
test("dry run only logs intended invocations", async () => {
215274
const logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined)
216275

0 commit comments

Comments
 (0)