Skip to content

Commit 5c7e048

Browse files
committed
feat(compartment-mapper): expect independent names for globals and module attenuator
1 parent 55a3991 commit 5c7e048

File tree

7 files changed

+37
-19
lines changed

7 files changed

+37
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
console.log('Attenuator imported');
2-
export const attenuate = (params, originalObject) => {
2+
const attenuate = (params, originalObject) => {
33
console.log('Attenuator called', params);
44
const ns = params.reduce((acc, k) => {
55
acc[k] = originalObject[k];
66
return acc;
77
}, {});
88
return ns;
99
};
10+
11+
export const attenuateGlobals = attenuate;
12+
export const attenuateModule = attenuate;

packages/compartment-mapper/demo/policy/att2/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const { create, assign, fromEntries, entries, defineProperties } = Object;
44

55
// minimal implementation of LavaMoat-style globals attenuator with write propagation
66
let globalOverrides = create(null);
7-
export const attenuate = (params, originalObject, globalThis) => {
7+
export const attenuateGlobals = (params, originalObject, globalThis) => {
88
const policy = params[0];
99
console.log('Attenuator2 called', params);
1010
if (policy === 'root') {

packages/compartment-mapper/src/policy-format.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ const POLICY_FIELDS_LOOKUP = ['builtins', 'globals', 'packages'];
1414

1515
/**
1616
*
17-
* @param {Object} packagePolicy
17+
* @param {object} packagePolicy
1818
* @param {string} field
1919
* @param {string} itemName
20-
* @returns {boolean|Object}
20+
* @returns {boolean | object}
2121
*/
2222
export const policyLookupHelper = (packagePolicy, field, itemName) => {
2323
if (!POLICY_FIELDS_LOOKUP.includes(field)) {

packages/compartment-mapper/src/policy.js

+21-10
Original file line numberDiff line numberDiff line change
@@ -173,25 +173,34 @@ const getGlobalsList = packagePolicy => {
173173
.map(([key, _vvalue]) => key);
174174
};
175175

176+
const GLOBAL_ATTENUATOR = 'attenuateGlobals';
177+
const MODULE_ATTENUATOR = 'attenuateModule';
176178
/**
177179
*
178180
* @param {AttenuationDefinition} attenuationDefinition
179181
* @param {DeferredAttenuatorsProvider} attenuatorsProvider
182+
* @param {string} attenuatorExportName
180183
* @returns {Promise<Function>}
181184
*/
182185
const importAttenuatorForDefinition = async (
183186
attenuationDefinition,
184187
attenuatorsProvider,
188+
attenuatorExportName,
185189
) => {
186190
if (!attenuatorsProvider) {
187191
throw Error(`attenuatorsProvider is required to import attenuators`);
188192
}
189-
const { specifier, params } = getAttenuatorFromDefinition(
193+
const { specifier, params, displayName } = getAttenuatorFromDefinition(
190194
attenuationDefinition,
191195
);
192196
const attenuator = await attenuatorsProvider.import(specifier);
197+
if (!attenuator[attenuatorExportName]) {
198+
throw Error(
199+
`Attenuator ${q(displayName)} does not export ${q(attenuatorExportName)}`,
200+
);
201+
}
193202
// TODO: uncurry bind for security?
194-
const attenuate = attenuator.attenuate.bind(attenuator, params);
203+
const attenuate = attenuator[attenuatorExportName].bind(attenuator, params);
195204
return attenuate;
196205
};
197206

@@ -235,7 +244,7 @@ export const makeDeferredAttenuatorsProvider = (
235244
const { namespace } = await compartments[ATTENUATORS_COMPARTMENT].import(
236245
attenuatorSpecifier,
237246
);
238-
return { attenuate: namespace.attenuate };
247+
return namespace;
239248
};
240249
}
241250

@@ -246,11 +255,11 @@ export const makeDeferredAttenuatorsProvider = (
246255

247256
/**
248257
*
249-
* @param {Object} options
258+
* @param {object} options
250259
* @param {DeferredAttenuatorsProvider} options.attenuators
251260
* @param {AttenuationDefinition} options.attenuationDefinition
252-
* @param {Object} options.globalThis
253-
* @param {Object} options.globals
261+
* @param {object} options.globalThis
262+
* @param {object} options.globals
254263
*/
255264
async function attenuateGlobalThis({
256265
attenuators,
@@ -261,6 +270,7 @@ async function attenuateGlobalThis({
261270
const attenuate = await importAttenuatorForDefinition(
262271
attenuationDefinition,
263272
attenuators,
273+
GLOBAL_ATTENUATOR,
264274
);
265275

266276
// attenuate can either define properties on globalThis on its own,
@@ -277,9 +287,9 @@ async function attenuateGlobalThis({
277287
/**
278288
* Filters available globals and returns a copy according to the policy
279289
*
280-
* @param {Object} globalThis
281-
* @param {Object} globals
282-
* @param {Object} packagePolicy
290+
* @param {object} globalThis
291+
* @param {object} globals
292+
* @param {object} packagePolicy
283293
* @param {DeferredAttenuatorsProvider} attenuators
284294
* @param {Array<Promise>} pendingJobs
285295
* @param {string} name
@@ -368,7 +378,7 @@ export const enforceModulePolicy = (specifier, compartmentDescriptor, info) => {
368378

369379
/**
370380
*
371-
* @param {Object} options
381+
* @param {object} options
372382
* @param {DeferredAttenuatorsProvider} options.attenuators
373383
* @param {AttenuationDefinition} options.attenuationDefinition
374384
* @param {ModuleExportsNamespace} options.originalModule
@@ -388,6 +398,7 @@ function attenuateModule({
388398
const attenuate = await importAttenuatorForDefinition(
389399
attenuationDefinition,
390400
attenuators,
401+
MODULE_ATTENUATOR,
391402
);
392403
const ns = await attenuate(originalModule);
393404
const staticModuleRecord = freeze({

packages/compartment-mapper/src/types.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -347,15 +347,16 @@ export {};
347347
* @typedef {object} UnifiedAttenuationDefinition
348348
* @property {string} displayName
349349
* @property {string | null} specifier
350-
* @property {Array<any> | undefined} params
350+
* @property {Array<any>} [params]
351351
*/
352352

353353
/**
354354
* @typedef {object} Attenuator
355-
* @property {Function} attenuate
355+
* @property {Function} [attenuateGlobals]
356+
* @property {Function} [attenuateModule]
356357
*/
357358

358359
/**
359-
* @typedef {Object} DeferredAttenuatorsProvider
360+
* @typedef {object} DeferredAttenuatorsProvider
360361
* @property {(attenuatorSpecifier: string|null) => Promise<Attenuator>} import
361362
*/

packages/compartment-mapper/test/fixtures-policy/node_modules/myattenuator/index.js

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/compartment-mapper/test/test-policy.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const assertNoPolicyBypassImport = async (t, { compartments }) => {
119119
await t.throwsAsync(
120120
() => compartments.find(c => c.name.includes('alice')).import('hackity'),
121121
{ message: /Failed to load module "hackity" in package .*alice/ },
122-
'Attempting to import a package into a compartment despite polict should fail.',
122+
'Attempting to import a package into a compartment despite policy should fail.',
123123
);
124124
};
125125

0 commit comments

Comments
 (0)