• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4if (!common.hasCrypto) common.skip('missing crypto');
5common.requireNoPackageJSONAbove();
6
7const tmpdir = require('../common/tmpdir');
8const assert = require('assert');
9const { spawnSync } = require('child_process');
10const crypto = require('crypto');
11const fs = require('fs');
12const path = require('path');
13const { pathToFileURL } = require('url');
14
15tmpdir.refresh();
16
17function hash(algo, body) {
18  const h = crypto.createHash(algo);
19  h.update(body);
20  return h.digest('base64');
21}
22
23const tmpdirPath = path.join(tmpdir.path, 'test-policy-parse-integrity');
24fs.rmSync(tmpdirPath, { maxRetries: 3, recursive: true, force: true });
25fs.mkdirSync(tmpdirPath, { recursive: true });
26
27const policyFilepath = path.join(tmpdirPath, 'policy');
28
29const parentFilepath = path.join(tmpdirPath, 'parent.js');
30const parentBody = "require('./dep.js')";
31
32const depFilepath = path.join(tmpdirPath, 'dep.js');
33const depURL = pathToFileURL(depFilepath);
34const depBody = '';
35
36fs.writeFileSync(parentFilepath, parentBody);
37fs.writeFileSync(depFilepath, depBody);
38
39const tmpdirURL = pathToFileURL(tmpdirPath);
40if (!tmpdirURL.pathname.endsWith('/')) {
41  tmpdirURL.pathname += '/';
42}
43
44const packageFilepath = path.join(tmpdirPath, 'package.json');
45const packageURL = pathToFileURL(packageFilepath);
46const packageBody = '{"main": "dep.js"}';
47
48function test({ shouldFail, integrity, manifest = {} }) {
49  manifest.resources = {};
50  const resources = {
51    [packageURL]: {
52      body: packageBody,
53      integrity: `sha256-${hash('sha256', packageBody)}`
54    },
55    [depURL]: {
56      body: depBody,
57      integrity
58    }
59  };
60  for (const [url, { body, integrity }] of Object.entries(resources)) {
61    manifest.resources[url] = {
62      integrity,
63    };
64    fs.writeFileSync(new URL(url, tmpdirURL.href), body);
65  }
66  fs.writeFileSync(policyFilepath, JSON.stringify(manifest, null, 2));
67  const { status } = spawnSync(process.execPath, [
68    '--experimental-policy',
69    policyFilepath,
70    depFilepath,
71  ]);
72  if (shouldFail) {
73    assert.notStrictEqual(status, 0);
74  } else {
75    assert.strictEqual(status, 0);
76  }
77}
78
79test({
80  shouldFail: false,
81  integrity: `sha256-${hash('sha256', depBody)}`,
82});
83test({
84  shouldFail: true,
85  integrity: `1sha256-${hash('sha256', depBody)}`,
86});
87test({
88  shouldFail: true,
89  integrity: 'hoge',
90});
91test({
92  shouldFail: true,
93  integrity: `sha256-${hash('sha256', depBody)}sha256-${hash(
94    'sha256',
95    depBody
96  )}`,
97});
98test({
99  shouldFail: true,
100  integrity: `sha256-${hash('sha256', 'file:///')}`,
101  manifest: {
102    onerror: 'exit'
103  }
104});
105test({
106  shouldFail: false,
107  integrity: `sha256-${hash('sha256', 'file:///')}`,
108  manifest: {
109    onerror: 'log'
110  }
111});
112