Skip to content

Commit 4c287e8

Browse files
authored
feat: add nonce attribute (#62)
1 parent 961a445 commit 4c287e8

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

examples/index.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
<html>
1919
<head>
2020
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
21+
<meta
22+
http-equiv="Content-Security-Policy"
23+
content="script-src 'nonce-caffe67d7b989af3a1c7f4a1a6c79bd9fb2b4eb0'"
24+
/>
25+
2126
<title>Loader Example</title>
2227
<style>
2328
html,
@@ -28,9 +33,16 @@
2833
padding: 0;
2934
}
3035
</style>
31-
<script type="text/javascript" src="../dist/index.dev.js"></script>
36+
<script
37+
nonce="caffe67d7b989af3a1c7f4a1a6c79bd9fb2b4eb0"
38+
type="text/javascript"
39+
src="../dist/index.dev.js"
40+
></script>
3241

33-
<script type="text/javascript">
42+
<script
43+
nonce="caffe67d7b989af3a1c7f4a1a6c79bd9fb2b4eb0"
44+
type="text/javascript"
45+
>
3446
const mapOptions = {
3547
center: {
3648
lat: 0,
@@ -43,6 +55,7 @@
4355
apiKey: "",
4456
version: "weekly",
4557
libraries: ["places"],
58+
nonce: "caffe67d7b989af3a1c7f4a1a6c79bd9fb2b4eb0",
4659
});
4760

4861
// Promise
@@ -68,6 +81,5 @@
6881

6982
<body>
7083
<div id="map" class="map"></div>
71-
<div id="map2" class="map"></div>
7284
</body>
7385
</html>

src/index.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import { Loader, LoaderOptions } from ".";
1818

1919
afterEach(() => {
20-
document.getElementsByTagName('html')[0].innerHTML = '';
20+
document.getElementsByTagName("html")[0].innerHTML = "";
2121
});
2222

2323
test.each([
@@ -65,8 +65,8 @@ test("setScript adds a script to head with correct attributes", () => {
6565
});
6666

6767
test("setScript does not add second script with same id", () => {
68-
new Loader({ apiKey: "foo", id: "bar" })['setScript']();
69-
new Loader({ apiKey: "foo", id: "bar" })['setScript']();
68+
new Loader({ apiKey: "foo", id: "bar" })["setScript"]();
69+
new Loader({ apiKey: "foo", id: "bar" })["setScript"]();
7070

7171
expect(document.head.childNodes.length).toBe(1);
7272
});
@@ -143,3 +143,11 @@ test("loader should wait if already loading", () => {
143143

144144
loader.load();
145145
});
146+
147+
test("setScript adds a nonce", () => {
148+
const nonce = "bar";
149+
const loader = new Loader({ apiKey: "foo", nonce });
150+
loader["setScript"]();
151+
const script = document.head.childNodes[0] as HTMLScriptElement;
152+
expect(script.nonce).toBe(nonce);
153+
});

src/index.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ export interface LoaderOptions {
144144
* Use a custom url and path to load the Google Maps API script.
145145
*/
146146
url?: string;
147+
/**
148+
* Use a cryptographic nonce attribute.
149+
*/
150+
nonce?: string;
147151
}
148152

149153
/**
@@ -197,6 +201,11 @@ export class Loader {
197201
*/
198202
mapIds: string[];
199203

204+
/**
205+
* See [[LoaderOptions.nonce]]
206+
*/
207+
nonce: string | null;
208+
200209
/**
201210
* See [[LoaderOptions.url]]
202211
*/
@@ -225,6 +234,7 @@ export class Loader {
225234
region,
226235
version,
227236
mapIds,
237+
nonce,
228238
url = "https://maps.googleapis.com/maps/api/js",
229239
}: LoaderOptions) {
230240
this.version = version;
@@ -234,6 +244,7 @@ export class Loader {
234244
this.language = language;
235245
this.region = region;
236246
this.mapIds = mapIds;
247+
this.nonce = nonce;
237248
this.url = url;
238249
}
239250
/**
@@ -311,9 +322,9 @@ export class Loader {
311322
private setScript(): void {
312323
if (this.id && document.getElementById(this.id)) {
313324
this.callback();
314-
return;
325+
return;
315326
}
316-
327+
317328
const url = this.createUrl();
318329
const script = document.createElement("script");
319330
script.id = this.id;
@@ -322,6 +333,11 @@ export class Loader {
322333
script.onerror = this.loadErrorCallback.bind(this);
323334
script.defer = true;
324335
script.async = true;
336+
337+
if (this.nonce) {
338+
script.nonce = this.nonce;
339+
}
340+
325341
document.head.appendChild(script);
326342
}
327343

0 commit comments

Comments
 (0)