Skip to content

feat: allowOutsideReadDir configuration #8852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/documentation/stories/asset-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,24 @@ to `true` on your asset definition, like so:
```

This needs to be set for every assets you want to write outside of your build output directory.

## Read assets outside of `dist/`

This needs to be set for every assets you want to write outside of your build output directory.

Because reading files in your project isn't an expected effect of `ng build`, it is disabled by
default on every assets. In order to allow this behaviour, you need to set `allowOutsideReadDir`
to `true` on your asset definition, like so:

```json
"assets": [
{
"glob": "**/*",
"input": "../not-dist/some/folder/",
"output": "./assets/",
"allowOutsideReadDir": true
},
]
```

This needs to be set for every assets you want to write outside of your build output directory.
5 changes: 5 additions & 0 deletions packages/@angular/cli/lib/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@
"type": "boolean",
"description": "Allow assets to be copied outside the outDir.",
"default": false
},
"allowOutsideReadDir": {
"type": "boolean",
"description": "Allow assets to be read outside the project dir.",
"default": false
}
},
"additionalProperties": false
Expand Down
21 changes: 16 additions & 5 deletions packages/@angular/cli/models/webpack-configs/common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as path from 'path';
import { HashedModuleIdsPlugin } from 'webpack';
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
import chalk from 'chalk';
import { extraEntryParser, getOutputHashFormat, AssetPattern } from './utils';
import { isDirectory } from '../../utilities/is-directory';
import { requireProjectModule } from '../../utilities/require-project-module';
Expand Down Expand Up @@ -106,19 +107,28 @@ export function getCommonConfig(wco: WebpackConfigOptions) {

if (!asset.allowOutsideOutDir) {
const message = 'An asset cannot be written to a location outside of the output path. '
+ 'You can override this message by setting the `allowOutsideOutDir` '
+ 'property on the asset to true in the CLI configuration.';
+ 'You can override this message by setting the `allowOutsideOutDir` '
+ 'property on the asset to true in the CLI configuration.';
throw new SilentError(message);
}
}

// Prevent asset configurations from reading files outside of the project.
const projectRelativeInput = path.relative(projectRoot, asset.input);
if (projectRelativeInput.startsWith('..') || path.isAbsolute(projectRelativeInput)) {
const message = 'An asset cannot be read from a location outside the project.';
if ((projectRelativeInput.startsWith('..') || path.isAbsolute(projectRelativeInput))
&& !asset.allowOutsideReadDir) {

const message = `${asset.input} cannot be read from a location outside the project.`
+ 'You can override this message by setting the `allowOutsideReadDir` '
+ 'property on the asset to true in the CLI configuration.';
throw new SilentError(message);
}

if (asset.allowOutsideReadDir) {
console.log(chalk.yellow('The allowOutsideReadDir option'
+ ' is on that could be a security risk'));
}

// Ensure trailing slash.
if (isDirectory(path.resolve(asset.input))) {
asset.input += '/';
Expand Down Expand Up @@ -190,7 +200,8 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
: 'rxjs/_esm5/path-mapping';
const rxPaths = requireProjectModule(projectRoot, rxjsPathMappingImport);
alias = rxPaths(nodeModules);
} catch (e) { }
} catch (e) {
}

// Allow loaders to be in a node_modules nested inside the CLI package
const loaderNodeModules = ['node_modules'];
Expand Down
1 change: 1 addition & 0 deletions packages/@angular/cli/models/webpack-configs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ export interface AssetPattern {
input?: string;
output?: string;
allowOutsideOutDir?: boolean;
allowOutsideReadDir?: boolean;
}
8 changes: 8 additions & 0 deletions tests/e2e/tests/basic/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ export default function () {
];
}))
.then(() => expectToFail(() => ng('build')))
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson['apps'][0];
app['assets'] = [
{ 'glob': '**/*', 'input': '/temp-folder/outside-allowed/of/project', 'output': 'temp',
'allowOutsideReadDir': true }
];
}))
.then(() => ng('build'))

// Add asset config in .angular-cli.json.
.then(() => updateJsonFile('.angular-cli.json', configJson => {
Expand Down