Skip to content

Commit

Permalink
ATO-1070: Set up micro rp
Browse files Browse the repository at this point in the history
For acceptance tests, we need to run an RP alongside the simulator
  • Loading branch information
CarlyG55 committed Oct 30, 2024
1 parent 60f2d56 commit 7590449
Show file tree
Hide file tree
Showing 8 changed files with 1,563 additions and 40 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"scripts": {
"build": "npx tsc",
"start": "node dist/src/server.js",
"start": "node dist/server.js",
"start:micro-rp": "node dist/tests/acceptance/micro-rp/app.js",
"check:lint": "eslint . --ext .ts,.js",
"check:pretty": "prettier --check \"*/**/*.{ts,json}\"",
Expand Down
4 changes: 4 additions & 0 deletions tests/acceptance/micro-rp/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.dockerignore
dist
node_modules

18 changes: 18 additions & 0 deletions tests/acceptance/micro-rp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:22.9.0@sha256:69e667a79aa41ec0db50bc452a60e705ca16f35285eaf037ebe627a65a5cdf52 as base
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build

FROM node:22.9.0@sha256:69e667a79aa41ec0db50bc452a60e705ca16f35285eaf037ebe627a65a5cdf52 as release
WORKDIR /app
COPY --chown=node:node --from=base /app/package*.json ./
COPY --chown=node:node --from=base /app/node_modules/ node_modules
COPY --chown=node:node --from=base /app/dist/ dist

ENV NODE_ENV "production"
ENV PORT 3001

EXPOSE $PORT
USER node
CMD ["npm", "start"]
90 changes: 51 additions & 39 deletions tests/acceptance/micro-rp/app.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import express, { Request, Response } from "express";
import { logger } from "../../../src/logger";
import { Config } from "../../../src/config";
import { randomUUID } from "crypto";
import { importPKCS8, SignJWT } from "jose";

const app = express();
const port = 3001
const config = Config.getInstance();
const port = 3001;
const simulatorUrl = "http://localhost:3000";
const clientId = "HGIOgho9HIRhgoepdIOPFdIUWgewi0jw";
const sub = "urn:fdc:gov.uk:2022:56P4CMsGh_02YOlWpd8PAOI-2sVlB2nsNU7mcLZYhYw=";

app.get("/callback", async (req: Request, res: Response) => {
const tokenResponse = await makeTokenRequest(req.params["code"]);
const userInfoResponse = await makeUserInfoRequest(tokenResponse["access_token"]);
const tokenResponse = await makeTokenRequest(req.params["code"]);
const userInfoResponse = await makeUserInfoRequest(
tokenResponse["access_token"]
);

res.send(`
res.send(`
<html>
<head><title>Example - GOV.UK - User Info</title></title>
<body>
<span>${JSON.stringify(userInfoResponse)}</span>
</body>
</html>
`);
})
});

app.listen(port, () => {
logger.info(`Micro RP listening on port ${port}`);
console.log(`Micro RP listening on port ${port}`);

Check failure on line 28 in tests/acceptance/micro-rp/app.ts

View workflow job for this annotation

GitHub Actions / style-checks

Unexpected console statement
});

const makeTokenRequest = async (code: string): Promise<TokenResponse> => {
const privateKey = `-----BEGIN PRIVATE KEY-----
const privateKey = `-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCZddHcSxG9QxWE
Qky1DXB7EmN9DTRDQxDsBF9KE3ncGc5AQ8WdL8jye0F12Qp0Ter68xMjvbDoW/dK
wwz5yJHYsgd0RB8qCwu3o8Y1xXWQboYb/edJbemxbzDrlDd+bLzU/Xvjyp7MOtV9
Expand All @@ -54,38 +56,48 @@ df6adXwKBKAiwz0k9hks9ivK2C6QN10csT8eLx5djQKBgQCiVnIJ3JcjNXHlygCW
eZG4zLcylZXusOv3VYBJKypBLVI74buoFfrvMcV/lQrI3Yo+6V95rNYGm+2MVxIc
iZSejbyqjUjJBAH9GHkPsiA+w1vutdd2PuPKOV05TLmV5ZM06bmLHQjMCGMiWK0G
8qVxFvr2NWRDB3otAjxVHR/ZQA==
-----END PRIVATE KEY-----`
const tokenUri = `${config.getSimulatorUrl()}/token`;
const claims = {
aud: tokenUri,
iss: config.getClientId(),
sub: config.getSub(),
exp: (Date.now() / 1000) + 5 * 60,
iat: Date.now() / 1000,
jti: randomUUID()
}
const tokenSigningKey = await importPKCS8(privateKey, "RSA");
const jwt = await new SignJWT(claims).sign(tokenSigningKey);
const body = {
code: code,
redirect_uri: "http://localhost:3001/callback",
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: jwt,
grant_type: "authorization_code"
};
const response = await fetch(tokenUri, { "method": "POST", "body": new URLSearchParams(body).toString() } );
return await response.json();
}
-----END PRIVATE KEY-----`;
const tokenUri = `${simulatorUrl}/token`;
const claims = {
aud: tokenUri,
iss: clientId,
sub: sub,
exp: Date.now() / 1000 + 5 * 60,
iat: Date.now() / 1000,
jti: randomUUID(),
};
const tokenSigningKey = await importPKCS8(privateKey, "RSA");
const jwt = await new SignJWT(claims)
.setProtectedHeader({
alg: "RS256",
})
.sign(tokenSigningKey);
const body = {
code: code,
redirect_uri: "http://localhost:3001/callback",
client_assertion_type:
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: jwt,
grant_type: "authorization_code",
};
const response = await fetch(tokenUri, {
method: "POST",
body: new URLSearchParams(body).toString(),
});
return response.json();
};

const makeUserInfoRequest = async (accessToken: string) => {
const userInfoResponse = await fetch(`${config.getSimulatorUrl()}/userinfo`, { headers: { "Authorization": `Bearer ${accessToken}` } })
const userInfoResponse = await fetch(`${simulatorUrl}/userinfo`, {
headers: { Authorization: `Bearer ${accessToken}` },
});

return await userInfoResponse.json();
}
return userInfoResponse.json();
};

interface TokenResponse {
access_token: string,
token_type: string,
expires_in: number,
id_token: string
access_token: string;
token_type: string;
expires_in: number;
id_token: string;
}
9 changes: 9 additions & 0 deletions tests/acceptance/micro-rp/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
micro-rp:
build:
context: .
dockerfile: Dockerfile
ports:
- "3001:3001"
restart: on-failure
network_mode: host
Loading

0 comments on commit 7590449

Please sign in to comment.