Skip to content

Commit

Permalink
Pull in the latest safety-web development (#4)
Browse files Browse the repository at this point in the history
* Add a base skeleton for the plugin

Change-Id: I7e98fdf3aa147ca8c1e14eb0f2bbf508aa610f60

* Set up Mocha with a placeholder test

Change-Id: I2f31bcf5f868c237417f17a75dc58d0e62438fba

* Remove tests from tsconfig and add yarn clean script

Change-Id: I1455d874fd158a5e915e48c4d1a57de40b37cbf2

* Add Copyright header to js files

Change-Id: Ib3f5a77d4b36e21b40413092dc42ddf135b30378

* Add a notice that safety-web is under development

Change-Id: Idd3d9458d2682560d9b9534a87203aa34ac3ba68

* Sets the rule tester up

Change-Id: I14e9dfd64aea1b8262a762c3689aa07caac34d18

* Add a script to update a vendored version of tsetse and add the current version of tsetse

Change-Id: I542eafad8b6570612592af12f43041c7767fc921

* Track the last run of the tsetse_update.sh script and the latest commit pulled for tsetse

Change-Id: Ice0292972ac65701676e34289688dd03d110cb37

* Add readme instructions for updating tsetse

Change-Id: I541078c4ff8cb51f177f6e73242c0637db47aa2b

* Add dependencies for tsetse

Change-Id: If68828cde13c7a70276115493e6d311cf489aad8

* Wire the tsetse checks, update the tests and test fixtures

This implementation is taken from the tsec eslint plugin. It only works with projects that have a tsconfig setup.

Change-Id: Ia8c000f96e10ec0a91e9c232af47fee72e590b53

* Add a test project as an integration test

Change-Id: I8b39d9537ca903b26f2a2758ac9c50d3054364df

* Add a test helper to check for expected violations

WIP: this helper will be refined to focus on certain fields and make the test less rigid.
Change-Id: I5b0f64c6b52f7b89b7e94bd5c5fbf62af709097b

* Add a JavaScript test project as an integration test

Change-Id: I4031da14bad7d9d4b8999727e81bd0178b33067c

* Set ESLint up for safety-web sources

Change-Id: Ieff5925cfd6ecfbc314dd69ad3d077cab0320ae1

* Fix the lint issues in safety-web

Change-Id: Ic649c4eadd8c036727e7f71af8a1368878d0a4bc

* Fix the main entry point path

Since test/ was added to the tsconfig, lib.index.js moved to lib/src/index.js. This was caught in the integration tests, but I haven't set the CI yet and I forgot to run them before the tsconfig change.

Change-Id: Id9bacc21976090270a008abcfb93c46e3ac01bdb

* Only add compiled JS to the NPM release

Change-Id: Ic96d5a7e791bc0e80ea6b7ba5973a03f3a314659

* Improve the violation expectation helper

- Canonicalize the finding reports to compare them
- Also add the license header
- Also add the javascript test project to the integration tests

Change-Id: I6eded1df866bdb0fe3a364e2834d361c67a36df1

* Add a typescript integration test set up with ESLint8

There are a few breaking changes between ESLint 8 and 9 so it's worth testing that safety-web works with both versions.

Change-Id: Ic97ab5d5d7a958631cb2ef527e1748752ed2528b

* Fix the basic-typescript-eslint9 tests

Change-Id: Icf62c861dc3f95377e10a4474da188214dd01ce9

* Define common script for all packages to be able to use `yarn workspaces run x`

Change-Id: I4aced5d5fbe69aec917dbf52cf14bb81e2822fe4

* Add a test:watch

Change-Id: Iba160f4b696ce2bfc2bdbd5d3b375c46cc5b865d

* Wire tsetse violations to ESLint message ids.

Change-Id: Ic594a1ed16102e987bb2e47b6d30d0f524134d52

* Add commands to update the violation golden files

Also explicitely use the node_module path for running eslint8 as there's a bug in yarn that makes it run the wrong binary yarnpkg/yarn#8590

Change-Id: I0ffb28f7831b8c016d1f6f00b9af9909d78647ed

* Clean the javascript eslint 9 test config up

Change-Id: I17239dc278005c054d83b7e45599bb72205f05d9

* Mark the test helper binary as executable once built

Change-Id: I4b111226d5920c0de3ac9ff5236c68277fa5e184

* Add a integration for javascript running on ESLint8

Change-Id: Ide643796658c061627191d0e020750dd721b3cc0

* Add a build:watch script to auto-rebuild safety-web on changes

Change-Id: I9a8758a69f39569181864851a7f6dff19fde9543

* Check that we're actually using eslint8 in integration test

yarn run eslint doesn't resolve the correct version by default. This was
already working, but was not checked.

Change-Id: I74fd24254d7ce0f17ad984668c78cf3ab869d127

* Specify the yarn version to use with corepack

Change-Id: I55c8548c6ee85d97f7d5d71e08642178d978d704

* Upgrade yarn to the latest version (Berry 4.3.1)

Also upgrade the version of some dependencies, commands and
documentation to match the new Yarn syntax.

Change-Id: I21aaa6ba30185fc7c49b31efbcce31660fff7717

* Fix the project after Yarn was upgraded.

Change-Id: Ibcb3320de668abccb68fece5242c74913d4b36e2
  • Loading branch information
neuracr authored Jul 25, 2024
1 parent 738b696 commit bfa0219
Show file tree
Hide file tree
Showing 94 changed files with 8,252 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
!.yarn/sdks
!.yarn/versions
node_modules
safety-web/lib/*
test-helpers/expect-violations/bin/*
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,43 @@

**This is not an officially supported Google product.**

**This project is under development and is not ready for production yet.**

safety-web is an ESLint plugin that works on TypeScript and JavaScript projects and surfaces security issues like Trusted Types violations statically.

## Development

This project uses yarn "modern" Berry (Yarn 4) with workspaces. To install the dependencies for all [workspaces](https://yarnpkg.com/features/workspaces):

```bash
yarn
```

The commands `clean`, `build`, `lint`, `test` are defined in all workspaces. This makes it possible to run them in all workspaces:

```bash
# Build all workspaces
yarn workspaces foreach --all run build
```

## safety-web unit testing

```bash
yarn workspace eslint-plugin-safety-web run test
```

## unit tests + integrations tests

```bash
yarn run unit_tests
```

## Updating tsetse

The core logic behind this plugin is re-used from [tsec](https://github.com/google/tsec). The [`common`](https://github.com/google/tsec/tree/main/common) directory of tsec is mirrored in `safety-web/src/common`, as vendored dependency.

Run tsetse_update.sh to pull the latest version of tsetse in:

```bash
bash update_tsetse.sh
```
17 changes: 14 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
{
"private": true,
"license": "Apache-2.0",
"author": "Google ISE Web Team",
"workspaces": [
"safety-web"
]
}
"safety-web",
"tests/*",
"test-helpers/*"
],
"scripts": {
"unit_tests": "yarn workspace eslint-plugin-safety-web test",
"integration_tests": "yarn workspace basic-typescript-eslint9 test && yarn workspace basic-typescript-eslint8 test && yarn workspace basic-javascript-eslint9 test && yarn workspace basic-javascript-eslint8 test",
"update_integration_tests": "yarn workspace basic-typescript-eslint9 update && yarn workspace basic-typescript-eslint8 update && yarn workspace basic-javascript-eslint9 update && yarn workspace basic-javascript-eslint8 update",
"test": "yarn workspaces foreach --all run test"
},
"packageManager": "[email protected]"
}
19 changes: 19 additions & 0 deletions safety-web/.mocharc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

module.exports = {
// Use tsx as a TypeScript node loader for Mocha https://stackoverflow.com/a/77609121
"require": "tsx",
"extension": ["ts"],
}
34 changes: 34 additions & 0 deletions safety-web/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: "tsconfig.json", // Indicates to find the closest tsconfig.json for each source file (see https://typescript-eslint.io/packages/parser#project).
tsconfigRootDir: import.meta.dirname,
},
},
files: ["**/*.ts"],
},
{
rules: {
'no-undef': 'off',
'no-dupe-class-members': 'off',
},
files: ['**/*.ts'],
},
{
ignores: [
"**/*.js",
"**/*.mjs",
"test/test_fixtures/",
"lib/",
"node_modules/",
"src/common/", // tsetse folder is linted internally.
]
},
);
35 changes: 33 additions & 2 deletions safety-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
{
"name": "safety-web",
"name": "eslint-plugin-safety-web",
"version": "0.1.0",
"license": "Apache-2.0",
"author": "Google ISE Web Team",
"main": "lib/src/index.js",
"files": [
"lib/src/"
],
"scripts": {
"clean": "tsc --build --clean",
"build": "tsc -b ./tsconfig.json",
"build:watch": "tsc -b ./tsconfig.json --watch",
"lint": "eslint",
"test": "mocha",
"test:watch": "mocha -r ts-node/register --watch --watch-files src/**/*.ts,test/**/*.ts"
},
"dependencies": {
"@typescript-eslint/parser": "^7.17.0",
"@typescript-eslint/utils": "^7.17.0",
"eslint": "^8.56.0 <9.0.0",
"tsutils": "^3.21.0",
"typescript": "^5.4.3 <5.5.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@types/chai": "^4.3.16",
"@types/mocha": "^10.0.7",
"@types/node": "^20.14.9",
"@typescript-eslint/rule-tester": "^7.17.0",
"chai": "^5.1.1",
"mocha": "^10.6.0",
"ts-node": "^10.9.2",
"tsx": "^4.16.2",
"typescript-eslint": "^7.17.0"
}
}
}
71 changes: 71 additions & 0 deletions safety-web/src/common/configured_checker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {ENABLED_RULES} from './rule_groups';
import {Checker} from './third_party/tsetse/checker';
import * as ts from 'typescript';

import {
ExemptionList,
parseExemptionConfig,
resolveExemptionConfigPath,
} from './exemption_config';

/**
* Create a new cheker with all enabled rules registered and the exemption list
* configured.
*/
export function getConfiguredChecker(
program: ts.Program,
host: ts.ModuleResolutionHost,
): {checker: Checker; errors: ts.Diagnostic[]} {
let exemptionList: ExemptionList | undefined = undefined;

const exemptionConfigPath = resolveExemptionConfigPath(
program.getCompilerOptions()['configFilePath'] as string,
);

const errors = [];

if (exemptionConfigPath) {
const projExemptionConfigOrErr = parseExemptionConfig(exemptionConfigPath);
if (projExemptionConfigOrErr instanceof ExemptionList) {
exemptionList = projExemptionConfigOrErr;
} else {
errors.push(...projExemptionConfigOrErr);
}
}

// Create all enabled rules with corresponding exemption list entries.
const checker = new Checker(program, host);
const wildcardAllowListEntry = exemptionList?.get('*');
const rules = ENABLED_RULES.map((ruleCtr) => {
const allowlistEntries = [];
const allowlistEntry = exemptionList?.get(ruleCtr.RULE_NAME);
if (allowlistEntry) {
allowlistEntries.push(allowlistEntry);
}
if (wildcardAllowListEntry) {
allowlistEntries.push(wildcardAllowListEntry);
}
return new ruleCtr({allowlistEntries});
});

// Register all rules.
for (const rule of rules) {
rule.register(checker);
}

return {checker, errors};
}
Loading

0 comments on commit bfa0219

Please sign in to comment.