Skip to content

Commit 98f0af7

Browse files
Commiting everything that lets us deploy to AWS.
1 parent 5f44876 commit 98f0af7

18 files changed

+1057
-24
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ node_modules
33

44
# Built files
55
/dist
6-
/src/schema.ts
6+
/src/schema.ts
7+
*.zip
8+
/packaged.template

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## Deployment
2+
3+
To deploy this stack:
4+
5+
``` shell
6+
yarn build
7+
yarn pack-build
8+
yarn aws-package
9+
yarn aws-deploy
10+
```

aws/secured-headers/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
exports.handler = (event, context, callback) => {
3+
4+
//Get contents of response
5+
const response = event.Records[0].cf.response;
6+
const headers = response.headers;
7+
8+
//Set new headers
9+
headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload'}];
10+
// headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}];
11+
headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
12+
headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
13+
headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];
14+
headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];
15+
16+
//Return modified response
17+
callback(null, response);
18+
};

aws/witch/nodejs/package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aws/witch/witch.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
const aws = require("aws-sdk");
2+
const fs = require("fs");
3+
const path = require("path");
4+
const mime = require("mime-types");
5+
6+
const s3 = new aws.S3();
7+
8+
const SUCCESS = "SUCCESS";
9+
const FAILED = "FAILED";
10+
11+
const BUCKET = process.env.BUCKET;
12+
13+
exports.staticHandler = function(event, context) {
14+
if (event.RequestType !== "Create" && event.RequestType !== "Update") {
15+
return respond(event, context, SUCCESS, {});
16+
}
17+
18+
Promise.all(walkSync("./").map(file => {
19+
var fileType = mime.lookup(file) || "application/octet-stream";
20+
21+
console.log(`${file} -> ${fileType}`);
22+
23+
return s3.upload({
24+
Body: fs.createReadStream(file),
25+
Bucket: BUCKET,
26+
ContentType: fileType,
27+
Key: file,
28+
ACL: "private",
29+
}).promise();
30+
})).then((msg) => {
31+
respond(event, context, SUCCESS, {});
32+
}).catch(err => {
33+
respond(event, context, FAILED, {Message: err});
34+
});
35+
};
36+
37+
// List all files in a directory in Node.js recursively in a synchronous fashion
38+
function walkSync(dir, filelist) {
39+
var files = fs.readdirSync(dir);
40+
filelist = filelist || [];
41+
42+
files.forEach(function(file) {
43+
if (fs.statSync(path.join(dir, file)).isDirectory()) {
44+
filelist = walkSync(path.join(dir, file), filelist);
45+
} else {
46+
filelist.push(path.join(dir, file));
47+
}
48+
});
49+
50+
return filelist;
51+
};
52+
53+
function respond(event, context, responseStatus, responseData, physicalResourceId, noEcho) {
54+
var responseBody = JSON.stringify({
55+
Status: responseStatus,
56+
Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
57+
PhysicalResourceId: physicalResourceId || context.logStreamName,
58+
StackId: event.StackId,
59+
RequestId: event.RequestId,
60+
LogicalResourceId: event.LogicalResourceId,
61+
NoEcho: noEcho || false,
62+
Data: responseData
63+
});
64+
65+
console.log("Response body:\n", responseBody);
66+
67+
var https = require("https");
68+
var url = require("url");
69+
70+
var parsedUrl = url.parse(event.ResponseURL);
71+
var options = {
72+
hostname: parsedUrl.hostname,
73+
port: 443,
74+
path: parsedUrl.path,
75+
method: "PUT",
76+
headers: {
77+
"content-type": "",
78+
"content-length": responseBody.length
79+
}
80+
};
81+
82+
var request = https.request(options, function(response) {
83+
console.log("Status code: " + response.statusCode);
84+
console.log("Status message: " + response.statusMessage);
85+
context.done();
86+
});
87+
88+
request.on("error", function(error) {
89+
console.log("send(..) failed executing https.request(..): " + error);
90+
context.done();
91+
});
92+
93+
request.write(responseBody);
94+
request.end();
95+
}

index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title><%= htmlWebpackPlugin.options.title %></title>
6+
7+
<script type="application/json" src="">window.NONCE_ID = document.currentScript.getAttribute('nonce');</script>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
</body>
12+
</html>

package.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,34 @@
4444
"@types/throttle-debounce": "^2.1.0",
4545
"babel-loader": "^8.2.2",
4646
"babel-plugin-transform-class-properties": "^6.24.1",
47+
"concurrently": "^5.3.0",
48+
"csp-html-webpack-plugin": "^5.1.0",
49+
"css-loader": "^5.0.1",
4750
"html-webpack-plugin": "^5.0.0-beta.4",
4851
"http-server-spa": "^1.3.0",
4952
"json-schema-to-typescript": "^10.1.2",
5053
"source-map-loader": "^2.0.0",
54+
"style-loader": "^2.0.0",
5155
"ts-loader": "^8.0.14",
5256
"ts-node": "^9.1.1",
5357
"typescript": "^4.1.3",
5458
"webpack": "^5.12.2",
5559
"webpack-cdn-plugin": "^3.3.1",
5660
"webpack-cli": "^4.3.1",
57-
"webpack-dev-server": "^3.11.1"
61+
"webpack-dev-server": "^3.11.1",
62+
"webpack-merge": "^5.7.3"
5863
},
5964
"scripts": {
60-
"build": "webpack",
65+
"build-dev": "webpack -c webpack.dev.js",
66+
"build-prod": "webpack -c webpack.prod.js",
67+
"build": "rm -fr dist && webpack -c webpack.prod.js",
68+
"pack-clean": "rm -rf *.zip source/witch/nodejs/node_modules/",
69+
"pack-witch": "cd aws/witch && npm install --prefix nodejs mime-types && cp witch.js nodejs/node_modules/ && zip -r ../../witch.zip nodejs",
70+
"pack-secured-headers": "cd aws/secured-headers/ && zip -r ../../s-headers.zip index.js",
71+
"pack-website": "cd dist && zip -r ../website.zip *",
72+
"pack-build": "npm run pack-clean && concurrently npm:pack-witch npm:pack-secured-headers npm:pack-website",
73+
"aws-package": "aws cloudformation package --template-file templates/main.yaml --s3-bucket json-schema-viewer-cloudformation --output-template-file packaged.template",
74+
"aws-deploy": "aws --region us-east-1 cloudformation deploy --stack-name json-schema-viewer --template-file packaged.template --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND --parameter-overrides DomainName=json-schema.app SubDomain=www CreateApex=yes",
6175
"storybook": "start-storybook -p 6006",
6276
"build-storybook": "build-storybook",
6377
"gen-schema": "json2ts json-schema.draft-07.json > src/schema.ts",

src/Start.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class StartWR extends React.PureComponent<StartProps, StartState> {
4141
description={`Put in the url to the JSON schema that you want to see documented here.`}
4242
primaryAction={(
4343
<StartWR.InputWidth>
44-
<TextField isCompact={false} value={this.state.urlInput || ''} onChangeCapture={onTextChange} />
44+
<TextField isCompact={false} value={this.state.urlInput || ''} onChange={onTextChange} />
4545
<Button label="submit" onClick={handleOnClick}>Load Schema</Button>
4646
</StartWR.InputWidth>
4747
)}

src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
33
import { App } from './BrowserApp';
4+
import './style.css';
45

5-
ReactDOM.render(React.createElement(App), document.body);
6+
/* global __webpack_nonce__ */ // eslint-disable-line no-unused-vars
7+
8+
// CSP: Set a special variable to add `nonce` attributes to all styles/script tags
9+
// See https://github.com/webpack/webpack/pull/3210
10+
__webpack_nonce__ = (window as any).NONCE_ID; // eslint-disable-line no-global-assign, camelcase
11+
12+
ReactDOM.render(React.createElement(App), document.getElementById('root'));

src/style.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "@atlaskit/css-reset/dist/bundle.css"

0 commit comments

Comments
 (0)