Skip to content

Commit 711dcfd

Browse files
authored
Create basic sandbox application (#638)
* Add sandbox application * Parameterize use of DOJ demo branding, so we can turn it off on the sandbox deployment. * Update lockfile
1 parent 4d297c0 commit 711dcfd

21 files changed

Lines changed: 538 additions & 301 deletions

File tree

apps/sandbox/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist/
2+
*.db

apps/sandbox/CHANGELOG.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# @gsa-tts/forms-server-doj
2+
3+
## 0.1.4
4+
5+
### Patch Changes
6+
7+
- Updated dependencies
8+
- @gsa-tts/forms-infra-core@0.1.4
9+
10+
## 0.1.3
11+
12+
### Patch Changes
13+
14+
- Updated dependencies
15+
- @gsa-tts/forms-infra-core@0.1.3
16+
17+
## 0.1.2
18+
19+
### Patch Changes
20+
21+
- Initial prerelease
22+
- Updated dependencies
23+
- @gsa-tts/forms-database@0.1.2
24+
- @gsa-tts/forms-server@0.1.2
25+
- @gsa-tts/forms-infra-core@0.1.2
26+
27+
## 0.1.1
28+
29+
### Patch Changes
30+
31+
- Initial prerelease
32+
- Updated dependencies
33+
- @gsa-tts/forms-database@0.1.1
34+
- @gsa-tts/forms-server@0.1.1
35+
- @gsa-tts/forms-infra-core@0.1.1
36+
37+
## 0.1.0
38+
39+
### Minor Changes
40+
41+
- Initial prerelease
42+
43+
### Patch Changes
44+
45+
- Updated dependencies
46+
- @gsa-tts/forms-database@0.1.0
47+
- @gsa-tts/forms-server@0.1.0
48+
- @gsa-tts/forms-infra-core@0.1.0

apps/sandbox/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# @gsa-tts/forms-sandbox
2+
3+
Sandbox application to evaluate platform functionality.

apps/sandbox/build.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import esbuild from 'esbuild';
2+
3+
esbuild
4+
.build({
5+
bundle: true,
6+
entryPoints: ['./src/index.ts'],
7+
format: 'esm',
8+
minify: true,
9+
outdir: './dist',
10+
platform: 'node',
11+
sourcemap: true,
12+
target: 'esnext',
13+
})
14+
.catch(() => process.exit(1));

apps/sandbox/package.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "@gsa-tts/forms-sandbox",
3+
"version": "0.1.4",
4+
"description": "Form server sandbox for evaluating functionality.",
5+
"type": "module",
6+
"license": "CC0",
7+
"main": "src/index.ts",
8+
"private": true,
9+
"scripts": {
10+
"build": "tsup src/* --format esm",
11+
"clean": "rimraf dist tsconfig.tsbuildinfo coverage",
12+
"dev": "tsup src/* --watch --format esm",
13+
"start": "VCAP_SERVICES='{\"aws-rds\": [{ \"credentials\": { \"uri\": \"\" }}]}' node dist/index.js",
14+
"test": "vitest run --coverage"
15+
},
16+
"dependencies": {
17+
"@gsa-tts/forms-database": "workspace:*",
18+
"@gsa-tts/forms-infra-core": "workspace:*",
19+
"@gsa-tts/forms-server": "workspace:*"
20+
},
21+
"devDependencies": {
22+
"@types/supertest": "^6.0.2",
23+
"supertest": "^7.0.0"
24+
}
25+
}

apps/sandbox/src/index.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { createPostgresDatabaseContext } from '@gsa-tts/forms-database/context';
2+
import { getAWSSecretsManagerVault } from '@gsa-tts/forms-infra-core';
3+
4+
import { createCustomServer } from './server.js';
5+
6+
const port = process.env.PORT || 4321;
7+
8+
const getCloudGovServerSecrets = () => {
9+
if (process.env.VCAP_SERVICES === undefined) {
10+
return;
11+
}
12+
const services = JSON.parse(process.env.VCAP_SERVICES || '{}');
13+
return {
14+
//loginGovClientSecret: services['user-provided']?.credentials?.SECRET_LOGIN_GOV_PRIVATE_KEY,
15+
dbUri: services['aws-rds'][0].credentials.uri as string,
16+
};
17+
};
18+
19+
const getAppRunnerSecrets = async () => {
20+
const secrets = {
21+
dbHost: process.env.DB_HOST,
22+
dbPort: process.env.DB_PORT,
23+
dbName: process.env.DB_NAME,
24+
dbSecretArn: process.env.DB_SECRET_ARN,
25+
}
26+
if (secrets.dbHost === undefined || secrets.dbPort === undefined || secrets.dbName === undefined || secrets.dbSecretArn === undefined) {
27+
return;
28+
}
29+
30+
const vault = getAWSSecretsManagerVault();
31+
const dbSecret = await vault.getSecret(secrets.dbSecretArn);
32+
if (dbSecret === undefined) {
33+
console.error('Error getting secret:', secrets.dbSecretArn);
34+
return;
35+
}
36+
const secret = JSON.parse(dbSecret);
37+
return {
38+
dbUri: `postgresql://${secret.username}:${secret.password}@${secret.dbHost}:${secret.dbPort}/${secret.dbName}`
39+
};
40+
};
41+
42+
const secrets = getCloudGovServerSecrets() || (await getAppRunnerSecrets());
43+
if (secrets === undefined) {
44+
console.error('Error getting secrets');
45+
process.exit(1);
46+
}
47+
48+
const db = await createPostgresDatabaseContext(secrets.dbUri, true);
49+
const server = await createCustomServer(db);
50+
server.listen(port, () => {
51+
console.log(`Server running on http://localhost:${port}`);
52+
});

apps/sandbox/src/server.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { type DatabaseContext } from '@gsa-tts/forms-database';
2+
import { createServer } from '@gsa-tts/forms-server';
3+
4+
export const createCustomServer = async (db: DatabaseContext): Promise<any> => {
5+
return createServer({
6+
agencyBranding: false,
7+
title: 'Form Service Sandbox',
8+
db,
9+
loginGovOptions: {
10+
loginGovUrl: 'https://idp.int.identitysandbox.gov',
11+
clientId:
12+
'urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:tts-10x-atj-dev-server-doj',
13+
//clientSecret: '', // secrets.loginGovClientSecret,
14+
},
15+
isUserAuthorized: async (email: string) => {
16+
return email.endsWith('.gov');
17+
},
18+
});
19+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import request from 'supertest';
2+
import { describe, expect, test } from 'vitest';
3+
4+
import { createInMemoryDatabaseContext } from '@gsa-tts/forms-database/context';
5+
6+
import { createCustomServer } from '../src/server';
7+
8+
describe('Form Service Sandbox', () => {
9+
test('renders the home page', async () => {
10+
const db = await createInMemoryDatabaseContext();
11+
const app = await createCustomServer(db);
12+
const response = await request(app).get('/');
13+
expect(response.ok).toBe(true);
14+
expect(response.text).toMatch(/Form Service Sandbox/);
15+
});
16+
});

apps/sandbox/tsconfig.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"module": "NodeNext",
5+
"moduleResolution": "NodeNext",
6+
"outDir": "./dist",
7+
"emitDeclarationOnly": true
8+
},
9+
"include": ["./src"],
10+
"references": []
11+
}

apps/sandbox/vitest.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineConfig } from 'vitest/config';
2+
3+
import sharedTestConfig from '../../vitest.shared';
4+
5+
export default defineConfig({
6+
...sharedTestConfig,
7+
test: {
8+
...sharedTestConfig.test,
9+
},
10+
});

0 commit comments

Comments
 (0)