lavamoat-core
Advanced tools
Comparing version 15.1.2 to 15.2.0
# Changelog | ||
## [15.2.0](https://github.com/LavaMoat/LavaMoat/compare/lavamoat-core-v15.1.2...lavamoat-core-v15.2.0) (2024-02-29) | ||
### Features | ||
* **core:** ESM support in policy generation ([60dc4fa](https://github.com/LavaMoat/LavaMoat/commit/60dc4fa750ffea336f23baaee7f82ea21d2ca8e3)) | ||
* **core:** return attempted path when parsing JSON of policy fails ([ea7f3d4](https://github.com/LavaMoat/LavaMoat/commit/ea7f3d49c42e57723707eefd3c399943344077cc)) | ||
* **core:** turn off localeTaming in ses lockdown by default ([e37582f](https://github.com/LavaMoat/LavaMoat/commit/e37582f201070bfaa734f378aa6b851892adc684)) | ||
* **webpack:** policy loading, generation and overrides put together ([1bf3702](https://github.com/LavaMoat/LavaMoat/commit/1bf370270c91afafa20b6331b0b478b16cd1b55b)) | ||
### Bug Fixes | ||
* **core/test:** platform-agnostic line separator ([0a898a3](https://github.com/LavaMoat/LavaMoat/commit/0a898a3e231b4281d6bd8e5543e5ead7c8f28511)) | ||
* **core:** detect ESM/CJS imports properly ([c2c37e2](https://github.com/LavaMoat/LavaMoat/commit/c2c37e235d67a8f3ac17fed6f9475481010ef881)) | ||
* **core:** export types from generatePolicy ([b999545](https://github.com/LavaMoat/LavaMoat/commit/b999545567e6673b42ed6b2c34153d84d7a4b283)) | ||
* **webpack:** fix typescript complaints ([fc41eda](https://github.com/LavaMoat/LavaMoat/commit/fc41eda86bfd680fbeadce72954b787864c2884f)) | ||
### Dependencies | ||
* The following workspace dependencies were updated | ||
* dependencies | ||
* lavamoat-tofu bumped from ^7.2.0 to ^7.2.1 | ||
## [15.1.2](https://github.com/LavaMoat/LavaMoat/compare/lavamoat-core-v15.1.1...lavamoat-core-v15.1.2) (2024-02-07) | ||
@@ -4,0 +29,0 @@ |
{ | ||
"name": "lavamoat-core", | ||
"version": "15.1.2", | ||
"version": "15.2.0", | ||
"description": "LavaMoat kernel and utils", | ||
@@ -35,3 +35,3 @@ "repository": { | ||
"test": "ava && npm run test:ses", | ||
"test:ses": "diff -q ../../node_modules/ses/dist/lockdown.umd.js ./lib/lockdown.umd.js" | ||
"test:ses": "diff -wq ../../node_modules/ses/dist/lockdown.umd.js ./lib/lockdown.umd.js" | ||
}, | ||
@@ -41,3 +41,3 @@ "dependencies": { | ||
"json-stable-stringify": "1.1.1", | ||
"lavamoat-tofu": "^7.2.0", | ||
"lavamoat-tofu": "^7.2.1", | ||
"merge-deep": "3.0.3", | ||
@@ -44,0 +44,0 @@ "type-fest": "4.10.2" |
@@ -17,2 +17,3 @@ // @ts-check | ||
}, | ||
inspectEsmImports, | ||
// @ts-expect-error no types yet | ||
@@ -24,2 +25,10 @@ } = require('lavamoat-tofu') | ||
/** | ||
* Symbols that look like globals but aren't; indexed by source type. | ||
*/ | ||
const MODULE_REFS = /** @type {const} */ ({ | ||
module: ['arguments', 'import', 'export'], | ||
script: ['arguments', 'require', 'module', 'exports'], | ||
}) | ||
module.exports = { rootSlug, createModuleInspector, getDefaultPaths } | ||
@@ -43,9 +52,12 @@ | ||
/** @type {ModuleInspector} */ | ||
const inspector = /** @type {any} */ (new EventEmitter()) | ||
inspector.inspectModule = (moduleRecord, opts2 = {}) => { | ||
inspectModule(moduleRecord, { ...opts, ...opts2 }) | ||
} | ||
inspector.generatePolicy = (opts2) => { | ||
return generatePolicy({ ...opts, ...opts2 }) | ||
} | ||
const inspector = Object.assign(new EventEmitter(), { | ||
/** @type {InspectModuleFn} */ | ||
inspectModule: (moduleRecord, opts2) => { | ||
inspectModule(moduleRecord, { ...opts, ...opts2 }) | ||
}, | ||
/** @type {GeneratePolicyFn} */ | ||
generatePolicy: (opts2) => { | ||
return generatePolicy({ ...opts, ...opts2 }) | ||
}, | ||
}) | ||
@@ -168,3 +180,3 @@ return inspector | ||
// esm support | ||
sourceType: 'module', | ||
sourceType: 'unambiguous', | ||
// someone must have been doing this | ||
@@ -258,7 +270,8 @@ allowReturnOutsideFunction: true, | ||
function inspectForGlobals(ast, moduleRecord, packageName, includeDebugInfo) { | ||
const commonJsRefs = ['require', 'module', 'exports', 'arguments'] | ||
const moduleRefs = MODULE_REFS[ast.program.sourceType] | ||
const globalObjPrototypeRefs = Object.getOwnPropertyNames(Object.prototype) | ||
const foundGlobals = inspectGlobals(ast, { | ||
// browserify commonjs scope | ||
ignoredRefs: [...commonJsRefs, ...globalObjPrototypeRefs], | ||
ignoredRefs: [...moduleRefs, ...globalObjPrototypeRefs], | ||
// browser global refs + browserify global | ||
@@ -304,4 +317,8 @@ globalRefs: ['globalThis', 'self', 'window', 'global'], | ||
.map(([requestedName]) => requestedName) | ||
const { cjsImports: moduleBuiltins } = inspectImports(ast, namesForBuiltins) | ||
if (!moduleBuiltins.length) { | ||
const esmModuleBuiltins = inspectEsmImports(ast, namesForBuiltins) | ||
const { cjsImports: cjsModuleBuiltins } = inspectImports( | ||
ast, | ||
namesForBuiltins | ||
) | ||
if (cjsModuleBuiltins.length + esmModuleBuiltins.length === 0) { | ||
return | ||
@@ -312,3 +329,5 @@ } | ||
const moduleDebug = debugInfo[moduleRecord.specifier] | ||
moduleDebug.builtin = moduleBuiltins | ||
moduleDebug.builtin = [ | ||
...new Set([...esmModuleBuiltins, ...cjsModuleBuiltins]), | ||
] | ||
} | ||
@@ -319,4 +338,10 @@ // aggregate package builtins | ||
} | ||
let packageBuiltins = packageToBuiltinImports.get(packageName) | ||
packageBuiltins = [...(packageBuiltins ?? []), ...moduleBuiltins] | ||
let packageBuiltins = packageToBuiltinImports.get(packageName) ?? [] | ||
packageBuiltins = [ | ||
...new Set([ | ||
...packageBuiltins, | ||
...cjsModuleBuiltins, | ||
...esmModuleBuiltins, | ||
]), | ||
] | ||
packageToBuiltinImports.set(packageName, packageBuiltins) | ||
@@ -323,0 +348,0 @@ } |
@@ -5,3 +5,7 @@ const { generateKernel } = require('./generateKernel') | ||
const { LavamoatModuleRecord } = require('./moduleRecord') | ||
const { loadPolicy, loadPolicyAndApplyOverrides } = require('./loadPolicy') | ||
const { | ||
loadPolicy, | ||
loadPolicyAndApplyOverrides, | ||
loadPoliciesSync, | ||
} = require('./loadPolicy') | ||
const { mergePolicy } = require('./mergePolicy') | ||
@@ -20,2 +24,3 @@ const { applySourceTransforms } = require('./sourceTransforms') | ||
loadPolicyAndApplyOverrides, | ||
loadPoliciesSync, | ||
getDefaultPaths, | ||
@@ -22,0 +27,0 @@ applySourceTransforms, |
@@ -65,2 +65,5 @@ // LavaMoat Prelude | ||
overrideTaming: 'severe', | ||
// preserves JS locale methods, to avoid confusing users | ||
// prevents aliasing: toLocaleString() to toString(), etc | ||
localeTaming: 'unsafe', | ||
} | ||
@@ -67,0 +70,0 @@ |
// @ts-check | ||
const fs = require('node:fs/promises') | ||
const { readFileSync } = require('node:fs') | ||
const { mergePolicy } = require('./mergePolicy') | ||
const jsonStringify = require('json-stable-stringify') | ||
module.exports = { loadPolicy, loadPolicyAndApplyOverrides } | ||
module.exports = { loadPolicy, loadPolicyAndApplyOverrides, loadPoliciesSync } | ||
@@ -13,11 +14,12 @@ /** | ||
* @param {PolicyOpts} opts | ||
* @returns {Promise<import('./schema').LavaMoatPolicy | undefined>} | ||
* @returns {import('./schema').LavaMoatPolicy | undefined} | ||
*/ | ||
async function readPolicyFile({ debugMode, policyPath }) { | ||
function readPolicyFileSync({ debugMode, policyPath }) { | ||
if (debugMode) { | ||
console.warn(`Lavamoat looking for policy at '${policyPath}'`) | ||
} | ||
/** @type string */ | ||
let rawPolicy | ||
try { | ||
const rawPolicy = await fs.readFile(policyPath, 'utf8') | ||
return JSON.parse(rawPolicy) | ||
rawPolicy = readFileSync(policyPath, 'utf8') | ||
} catch (err) { | ||
@@ -29,3 +31,18 @@ if (/** @type {NodeJS.ErrnoException} */ (err).code !== 'ENOENT') { | ||
} | ||
return | ||
} | ||
try { | ||
return JSON.parse(rawPolicy) | ||
} catch (/** @type any */ error) { | ||
if (debugMode) { | ||
console.warn({ | ||
error: error?.message || error, | ||
policyPath, | ||
rawPolicy, | ||
}) | ||
} | ||
throw new Error( | ||
`Lavamoat could not parse policy at '${policyPath}': ${/** @type {NodeJS.ErrnoException} */ (error).message}` | ||
) | ||
} | ||
} | ||
@@ -47,3 +64,3 @@ | ||
try { | ||
const rawPolicy = await readPolicyFile({ debugMode, policyPath }) | ||
const rawPolicy = readPolicyFileSync({ debugMode, policyPath }) | ||
policy = rawPolicy ?? policy | ||
@@ -77,3 +94,3 @@ } catch (err) { | ||
/** @type {import('./schema').LavaMoatPolicyOverrides | undefined} */ ( | ||
await readPolicyFile({ debugMode, policyPath: policyOverridePath }) | ||
readPolicyFileSync({ debugMode, policyPath: policyOverridePath }) | ||
) | ||
@@ -100,2 +117,36 @@ | ||
/** | ||
* Loads policy and policy overrides from disk and merges them. | ||
* | ||
* Doesn't write anything back to disk. | ||
* | ||
* @param {PolicyOpts & { policyOverridePath: string }} opts | ||
* @returns {{ | ||
* policy: import('./schema').LavaMoatPolicy | undefined | ||
* applyOverride: ( | ||
* main: import('./schema').LavaMoatPolicy | ||
* ) => import('./schema').LavaMoatPolicy | ||
* }} | ||
*/ | ||
function loadPoliciesSync({ debugMode, policyPath, policyOverridePath }) { | ||
const policy = readPolicyFileSync({ debugMode, policyPath }) | ||
const policyOverride = readPolicyFileSync({ | ||
debugMode, | ||
policyPath: policyOverridePath, | ||
}) | ||
return { | ||
policy, | ||
applyOverride: (main) => { | ||
if (!policyOverride) { | ||
return main | ||
} | ||
if (debugMode) { | ||
console.warn('Merging policy-override.json into policy.json') | ||
} | ||
return mergePolicy(main, policyOverride) | ||
}, | ||
} | ||
} | ||
/** | ||
* @typedef PolicyOpts | ||
@@ -102,0 +153,0 @@ * @property {boolean} debugMode |
@@ -57,3 +57,3 @@ // @ts-check | ||
* @param {string} parentAddress | ||
* @returns {string | undefined} | ||
* @returns {string | null} | ||
*/ | ||
@@ -60,0 +60,0 @@ |
@@ -5,1 +5,2 @@ export * from './index' | ||
export type * from './schema' | ||
export type * from './generatePolicy' |
@@ -7,2 +7,3 @@ import { generateKernel } from "./generateKernel"; | ||
import { loadPolicyAndApplyOverrides } from "./loadPolicy"; | ||
import { loadPoliciesSync } from "./loadPolicy"; | ||
import { getDefaultPaths } from "./generatePolicy"; | ||
@@ -12,3 +13,3 @@ import { applySourceTransforms } from "./sourceTransforms"; | ||
import { makeInitStatsHook } from "./makeInitStatsHook"; | ||
export { generateKernel, createModuleInspector, parseForPolicy, loadPolicy, mergePolicy, loadPolicyAndApplyOverrides, getDefaultPaths, applySourceTransforms, LavamoatModuleRecord, makeInitStatsHook }; | ||
export { generateKernel, createModuleInspector, parseForPolicy, loadPolicy, mergePolicy, loadPolicyAndApplyOverrides, loadPoliciesSync, getDefaultPaths, applySourceTransforms, LavamoatModuleRecord, makeInitStatsHook }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -27,2 +27,21 @@ export type PolicyOpts = { | ||
}): Promise<import('./schema').LavaMoatPolicy>; | ||
/** | ||
* Loads policy and policy overrides from disk and merges them. | ||
* | ||
* Doesn't write anything back to disk. | ||
* | ||
* @param {PolicyOpts & { policyOverridePath: string }} opts | ||
* @returns {{ | ||
* policy: import('./schema').LavaMoatPolicy | undefined | ||
* applyOverride: ( | ||
* main: import('./schema').LavaMoatPolicy | ||
* ) => import('./schema').LavaMoatPolicy | ||
* }} | ||
*/ | ||
export function loadPoliciesSync({ debugMode, policyPath, policyOverridePath }: PolicyOpts & { | ||
policyOverridePath: string; | ||
}): { | ||
policy: import('./schema').LavaMoatPolicy | undefined; | ||
applyOverride: (main: import('./schema').LavaMoatPolicy) => import('./schema').LavaMoatPolicy; | ||
}; | ||
//# sourceMappingURL=loadPolicy.d.ts.map |
export type ImportHookFn = (address: string) => Promise<import('./moduleRecord').LavamoatModuleRecord>; | ||
export type IsBuiltinFn = (specifier: string) => boolean; | ||
export type ShouldImportFn = (childSpecifier: string, moduleSpecifier: string) => boolean; | ||
export type ResolveFn = (requestedName: string, parentAddress: string) => string | undefined; | ||
export type ResolveFn = (requestedName: string, parentAddress: string) => string | null; | ||
export type ParseForPolicyOpts = { | ||
@@ -6,0 +6,0 @@ moduleSpecifier: string; |
@@ -5,2 +5,3 @@ export * from './index'; | ||
export type * from './schema'; | ||
export type * from './generatePolicy'; | ||
//# sourceMappingURL=types.d.ts.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
549505
13540
Updatedlavamoat-tofu@^7.2.1