Coder Social home page Coder Social logo

os-scar / overlay Goto Github PK

View Code? Open in Web Editor NEW
218.0 7.0 16.0 805 KB

Overlay is a browser extension helping developers evaluate open source packages before picking them

License: MIT License

JavaScript 81.50% Vue 17.54% HTML 0.44% Shell 0.05% SCSS 0.48%
advisory extension supply-chain

overlay's Introduction

Badge Commits Badge Issues Badge License Badge Version Badge Mozilla Badge Chrome Badge Discord


Overlay

Overlay is a browser extension that helps developers evaluate open source packages before picking them. It gathers data from various sources, such as Snyk Advisor, Debricked, Socket.dev, and Deps.dev, and displays them on the package pages of popular registries like npm, PyPI, and Go.

Get Overlay for Firefox Get Overlay for Chromium

Platinum Sponsors

Gold Sponsors


Overlay Screenshot

With Overlay, you can quickly consider packages based on metrics like popularity, quality, security, maintenance, and compatibility. You can also see detailed information about each package, such as its license, dependencies, vulnerabilities, issues, releases, and more.

Overlay aims to help developers make informed decisions when choosing open source packages for their projects.

Currently supported

Installation

Overlay is available for Chrome and Firefox. You can install it from the following links:

Usage

After installing Overlay, you can use it on any supported page (such as StackOverflow). You will notice indicators on package names and links, showing the number of issues. When you hover over an indicator, you will see more details about the package. You can also click on the indicator to open a modal with even more details.

demo.mp4

You can customize the sources that Overlay uses by clicking on the Overlay logo in the extensions bar.

Feedback

We would love to hear your feedback and suggestions on how to improve Overlay. You can contact us by:

Contribution

We welcome contributions from anyone who wants to help us improve Overlay. If you are interested in contributing, please fork this repository and make your changes. Then submit a pull request with a clear description of your changes and why they are needed. We will review your pull request and merge it if it meets our standards.

Please make sure to follow our code style and conventions.

If you have any questions or suggestions about contributing, please feel free to contact us.

Technical details

Overlay is written in Vue.js and uses a background script to fetch package data from various external sources.
It injects the indicator as a WebComponent into the current web pages and uses a popup menu to control the displayed sources.

Local Development

To start developing the extension locally, follow these steps:

  1. Clone the project from the repository.
  2. Install the dependencies with yarn install.
  3. In one terminal, run yarn build:watch. This will rebuild the extension every time you change a file.
  4. In another terminal, run yarn start:chrome (or yarn start:firefox). This will reload the extension on the development browser every time the extension is built.

You can now test and debug the extension on Chrome or Firefox.

Testing

To run unit tests, use yarn test. We use Jest for testing.

For end-to-end tests, see the e2e/README.md file.

Resources

Contributors

License

Overlay is licensed under the MIT license. See the LICENSE file for more details.

overlay's People

Contributors

aponace avatar aviv1620 avatar baruchiro avatar dipsylala avatar ettestim avatar guynachshon avatar hagarfisher avatar itay-goldraich avatar jossef avatar noamanisfeld avatar oferlis avatar oshriasulin avatar rzarviv avatar uriklar avatar yoavsbg avatar zviki-zaks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

overlay's Issues

add sandworm.dev integration

Sandworm is a new tool for developers to check npm packages.
They are generating a report with list of issues:

image

Even though the webapp looks like it was statically generated, they may have an API to generate json
see https://docs.sandworm.dev/#json-output (or their CLI source code to see how it fetches the data: https://github.com/sandworm-hq/sandworm-audit)

To display it in the UI you will need their logo, please put here a link to download the logo, so @jossef will convert it to the right size.

overlay-indicator custom element breaks the copy option

Without our extension, the user sees a code block with relevant commands and copies this command to use it.

pip install --force-reinstall -v "MySQL_python==1.2.2"

Now, with our extension, if you mark the content, it will copy the "issues number" and some spaces.

pip install --force-reinstall -v "
2
MySQL_python==1.2.2
"

Publish requirements

To make this project officially ready for users and contributions, I think we need to complete these:

  • Logo. Is this the final logo?
    icon_96
  • README.md file, include screenshots
  • Publish to Firefox and Chrome we stores (even manually)
  • Complete the UI #29
  • Remove not-ready features from production (#52 for example)
  • Badges (scorecard?)
  • Link to report issues.
  • Discord channel (the SCAR one?)? Or the Github Discussion is enough?

Support `go get` commands to install from Github repo

Go packages

Examples:

case Package name StackOverflow Advisories comments
Standard library/tool golang.org/x/tools/cmd/godoc macos - Install go with brew, and running the gotour no
link github.com/google/uuid Is there a method to generate a UUID with Go language? Snyk, Debricked, openbase, deps.dev
command github.com/nu7hatch/gouuid Is there a method to generate a UUID with Go language? Snyk, Debricked*, openbase, deps.dev** No versions in Github
command with version github.com/gorilla/[email protected] How do I import a specific version of a package using go get? Snyk, Debricked, openbase, deps.dev
go install github.com/mailgun/godebug debugging - Does any golang interactive debugger exist? Snyk, Debricked***, openbase, deps.dev**
Not-exists package github.com/username/hello go - How to place Golang project (a set of packages) to Github? No of course
From code.google code.google.com/p/goauth2/oauth Google service account authorization with JWT in Go I can't find working example

Way to support:

  • Support the go get and go install.
  • Support command arguments
  • Support get specific version
  • The Github repo should be searched in the advisories.
  • Need to search for an example of go get github.com/user/repo/subfolder

Originally posted by @baruchiro in #45 (comment)


When you add a new language/registry, you need to cover these use cases:

  • Link to the package in the registry, and check if there are other official websites (for example: pypi.python.org, pythonhosted.org)
  • Link with added parts, like version and anchor
  • CLI install commands with:
    • flags and arguments (for example: pip install --global-option build_ext -t ../ pandas)
    • Special characters (depends on registry options, for example: p, P_ck-ag.E)
    • package with a specific or range of versions
    • multiple packages in one command
    • other install commands (go install, npx)
    • install from git repo instead of registry (example: npm install git://github.com/user-c/dep-2#node0.8.0)
  • multiple commands in multiline element

See the tests of each language to see what else you need to test (and add to here).

Originally posted by @baruchiro in #47

cache with ttl - add in background service

The current implementation of the cache is very simple:

const _cache = {};
const buildNewKeys = (keys) =>
keys.reduce((acc, currentKey) => {
if (!acc[currentKey]) {
acc[currentKey] = {};
}
return acc[currentKey];
}, _cache);
export default (keys, action) => {
const lastKey = typeof keys === 'string' ? keys : keys.pop();
const objectForKey = typeof keys === 'string' ? _cache : buildNewKeys(keys);
if (!objectForKey[lastKey]) objectForKey[lastKey] = action();
return objectForKey[lastKey];
};

In the background service, we are wrapping the HTTP requests with the cache method, so that if we requested that request once, it will return its Promise every time.

There can be multiple issues with this simple implementation.

  • TTL: Since it is running on the Background Service, the cache will become bigger and bigger if the user keeps its browser open for a long time.
    We need to improve the process by cleanup old records from the cache object.

add pypi packages support

Similar to current coverage for npm packages, add support for PyPI packages:

  • Links- (I found in SO links in this format: pypi.python.org/pypi, but it redirects to pypi.org/project)
  • pip install commands
  • Package name with _ will be replaced to -, for example: pip install MySQL_python will install MySQL-python.
  • Python package name is case-insensitive.
  • Example of a package name with a dot: kreagroup.jsi18n
  • Package with version will be pip install package=version
  • package can be wrapped with quotes: pip install "package=version"

This page in StackOverflow seems to contain various cases for pip install.

TODO:

  • Test all the cases above on finder.
  • Test the variants of the package names against each advisory.

reduce fetching the same package multiple times

The flow today is finding packages on the page:

flowchart
	807640["find packages in webpage"] --> 822924["request info from background"]
	884778["send info to webapp"] --> 106849["update the store"]
	822924 --> 620428["receive info from background"]
	620428 --> 884778
Loading

Now, this flow can happen multiple times for each package, since in pages like StackOverflow, one package may appear multiple times.

We need to reduce the occurrences of the flow.

Nuget Support

Is there any plan to support Nuget in the registries?

provide package data from background service

Either placed transparently on the global store or provided on demand, this is the expected data structure to display both the tooltip, general metadata, and modal.

For example, data structure expected for node-ipc package:

{
    name: 'node-ipc',
    loading: true, // indicating the package info is loading
    type: 'npm',
    license: 'MIT',
    latest: '1.2.3',
    created: 1677996776, // epoch utc
    stars: 50000,
    sources: [{
            type: 'checkmarx',
            error: true, // indicating error occured
        },
        {
            type: 'snyk_advisor',
            loading: true, // indicating data is still loading
        },
        {
            type: 'socket',
            issues: 3,
            supplyChainScore: 100,
            qualityScore: 74,
            maintenanceScore: 78,
            vulnerabilitiesScore: 100,
            licenseScore: 88,
        },
        {
            type: 'openbase',
            userRatingScore: 4.8,
            userFeedback: [{
                    name: 'Easy to use',
                    positive: true
                },
                {
                    name: 'Great Documentation',
                    positive: true
                },
                {
                    name: 'Performant',
                    positive: true
                },
                {
                    name: 'Bleeding Edge',
                    positive: false // will be displayed as bad
                },
                {
                    name: 'Highly Customizable',
                    positive: false  // will be displayed as bad
                },
                {
                    name: 'Responsive Maintainers',
                    positive: false  // will be displayed as bad
                },
            ],
        },
        {
            type: 'scorecards',
            score: 7.5,
            checks: [{
                    description: 'Using protected branches',
                    score: 3.2
                },
                {
                    description: 'signed commits',
                    score: 5.2
                },
                // more scorecards items...
            ],
        },
        {
            type: 'debricked',
            contributorsScore: 77,
            popularityScore: 82,
            securityScore: 59,
        },
    ],
}

get package info - from single response to async responses (event based)

Today, when we request information from the background service, it returns one response aggregated with all the advisories:

const getPackageInfo = async (packageID) => {
const packageInfo = await advisory(packageID);
const { latestVersion, license, stars } = packageInfo.depsDev.data;
return {
...packageID,
latest: latestVersion,
license,
stars,
sources: packageInfo,
};
};

We want to not wait for all the advisories, but respond when each advisory is ready.

It will require changing the communication between the content script and the background service, because we are changing from Request-Response to Request-Multi Responses.

Support multiple commands in the same line

From StackOverflow:

npm uninstall -g create-react-app && npm i -g npm@latest && npm cache clean -f && npx create-react-app@latest my-app --use-npm

There are only two packages here:

  1. npm from npm i -g npm@latest
  2. create-react-app from npx create-react-app@latest my-app --use-npm (will be supported by #37)

Currently, it takes more than that:
image

I created a branch with tests to cover this case. Of course, those tests are now failing.

Overlay preventing copying full line

When double-clicking a line to highlight it, if overlay exists it prevents you from copying the entire line on double click.

Example

Possible solutions:

  • add copy icon at the end of the line
  • using the pseudo-selector ::select
  • javascript solution - though it is messy and not intuitive to support:
const parentElement = document.getElementById('parentElement'); 
parentElement.addEventListener('dblclick', function(event) {event.stopPropagation();});

add overlay in https://readthedocs.io/

There are two types of adding Overlay to ReadTheDocs:

  1. Identifying the current page and adding the Overlay details as we do in npm.org and PyPI.
  2. Find links to ReadTheDocs on other websites and add the indicator to them.

For those two options, we need first to collect examples of both, then do some research to understand what you said about different package ecosystems, different URLs, different page structures, and so on.

Write advisories tests

Since our interface with the advisories is not guaranteed, I think we need to write tests that accessed the real advisory endpoint and test it is not changed or broken.

We are doing something similar with finding in StackOverflow- every day we are running the "real-examples" test again on a real StackOverflow website.

Playwright test failing

the java script playwright web test e2e\npm.spec.js
us failing.
when we run it using:
the run from cursor in vs code
we get an error:

Error: locator.scrollIntoViewIfNeeded: Target closed
at e2e\npm.spec.js:9:26

Execution log

waiting for locator('overlay-indicator[package-name="module_name"]')

image

apply indicator element on multiple websites

Support the registry websites such as npmjs and pypi.org. These sites need a custom UI component because we want to add this component as a static part of the page.

generic code to modify the content of selected websites (not *) to load and add the indicator element tag
e.g.

  • npmjs.com (#74)
  • pypi.org (#75)
  • reddit
  • github issues comments
  • twitter
  • #86

How to hold the advisories data returned from the background service?

  • Should be cross-browser (Firefox, Chrome)

Approach 1: Using a store

The "finder" code (scraping the page and finding all the packages) will take two actions once it finds a package:

  1. Wrap the found package with our custom-element component.
  2. Fetch the advisories info from the background service and update the store.

image

Pros

  • Save on calling the background service for duplicates on the same page.

Cons

  • Another "moving part", compared to the Comopnent's state approach, and we manage and access another building block here.

Challenges

  • The Content Script runs in isolated mode, and the custom-element is injected into the page as a script tag and runs in the page context.
    Generally, we can't share an object reference between the content script and the page.
    (there are workarounds, see Firefox, Chrome (also read this in Chrome docs))
    Optional solution is to inject also the "finder" code into the page, but then you have a problem with communication with the background service, see the challenge in approach 2.

Approach 2: Component's state

Each component will own its own state, which means that once the component is loaded, it will fetch the advisory info for its package from the background service.

image

Pros

  • Each component is a closed box with all its implementation inside.

Cons

  • We expect one package to appear multiple times on a page, and each component for each package will send a request to the background service to fetch the same data (remember that the background service manages a cache so outside requests to the advisories will not be duplicated).

Challenges

  • Calling the background service from the component, who is injected as a script into the page (custom-elements.js), requires an extension id (and manifest configuration).
    However, using extension API from a webpage seems to not be supported in Firefox, the chrome or browser objects are undefined. (And see here and here)

Summary

We need to consider two points:

  1. We can't share a reactive object between the content script and the webpage (reference).
  2. In Firefox, we can't send a message from a webpage to our background service (reference).

@baruchiro think we should ask ourselves why we inject the custom-element.js as a script tag (it seems to be right, but it is better to document the decision and validate it).

Conclusion

Calculating all these challenges, we will have to create a connection between the webpage and the content script (Chrome and Firefox seems to work the same in this approach).

Desired behavior of Overlay extension when using the search bar in npmjs.com

Discussed in #104

Originally posted by rzarviv June 8, 2023
I noticed that when I'm using the search bar in npmjs.com to search for a package, the search result shown in Overlay does not update. For example, when I visit react's page on npm and then I search for @angular/cli using the search bar, Overlay will still show its search result for react.

I guess that since overlay does not have the activeTab permission, it's unable to recognize the URL modification caused by using the search bar, and I wonder whether it needs to be implemented.

Steps to reproduce

  1. Open react's page on npm.
  2. Wait for Overlay to be completely loaded.
  3. Search for another package in the search box.
  4. Select that package.

Expected

The Overlay detailed component must show the current package info/

Actual

The Overlay didn't refresh and shows the previous package (react).

Error handling - what if one or more advisories didn't return?

Today we have three states for the indicator: Loading, Good, and Bad.

What should we display if one of the advisories returns an error (for example, the API is broken)?
What if all except one return an error?
What if all?

Is it a Good state (because there are no bad scores)? Is it Bad?

Refactor: Change finding result structure

The current structure of finding results is:

{
  type: 'go',
  name: packageMatch.groups.name,
  startIndex: counterIndex,
  endIndex: counterIndex + packageMatch[0].length,
}

We always need to calculate the startIndex + length. Instead, it will be simpler to just keep an index and a length, and add them in one place when needed (in the getRangeOfPositions function).

export const getRangeOfPositions = (element, textStart, textEnd) => {
const start = findPositionInsideTree(element, textStart);
const end = findPositionInsideTree(element, textEnd);
const range = new Range();
range.setStart(start.node, start.position);
range.setEnd(end.node, end.position);
return range;
};

Support GitHub packages urls (golang, swift, ...)

There are some use cases to support Github repo analysis (by connecting it to its package, or by itself).

  • Install NPM package from Github: npm install git://github.com/user-c/dep-2#node0.8.0
  • Go packages
  • Swift
  • Enhance package insights with repo insights.

Way to support:

  • Support the go get command, the Github repo there is for sure a Go package.
  • Identify if a repo is a Go package
  • Find links to Go packages
  • Identify if a repo is a package in which language.

Create an infrastructure for E2E tests

We want to run End to End tests by running a browser instance, installing the extension, and clicking on the page to see the extension in action.

The requirements:

  • Run a real browser
  • Install the extension
  • Run on headless mode
  • Run with a real URL (or do you have another suggestion?)

Cypress

Currently can't visit StackOverflow.

Selenium

Headless Chrome can't load extensions.

Playwright

Managed to run Chrome with an extension, but the solution for headless didn't work.
Firefox extension is not supported.

Send a message to Discord when a new release is created

I want to add a Github Action to the end of release.yml, to send a message to our SCAR discord channel when a new release is created.

To implement it, please open a new Discord server and try to publish it. Once it will be ready, I will use the token from the real Discord channel.

Support npm-init and npx commands

npm-init

npm init <initializer> can be used to set up a new or existing npm package.
initializer in this case is an npm package named create-<initializer>, which will be installed by npx, and then have its main bin executed -- presumably creating or updating package.json and running any other initialization-related operations.
(from npm documentation)

npx

Executes <command> either from a local node_modules/.bin, or from a central cache, installing any packages needed in order for <command> to run.

npx will install a package, if needed, then will run its CLI.

We should support npx commands, such as here: https://stackoverflow.com/a/59189242/839513.

Note that in contrast to the regular npm command, in npx will be just one package. The other arguments will be the package's CLI arguments.

Link of a scoped package not opened correctly

Clicking on a OpenSSF scorecard (a.k.a deps-dev) link of a scoped npm package (for example: @angular/cli) leads o a "package not found" page.

Steps to reproduce:

  1. Visit StackOverflow and find a page that contains a code section with a scoped package (for example: this link)
  2. Open the extension and click on the "open link" icon in OpenSSF Scorecard section. A new tab should be opened stating that the package could not be found.

solution
The following background/advisory/deps-dev.js causes the problem:
image

replacing name with encodeURIComponent(name) should solve the problem.

Support link to package website

You can see answers with a suggestion to a package, but instead of a link to the package in the registry, there will be a link to the package website. (#40 is an example of links to both Github and the package website)

We can create a map from websites to their package name/registry link, and give insights also for those links.

Tooltip - bypass <Pre> overflow

We need to find a solution to bypass overflow hidden on elements styled by StackOverflow.

Possible solutions:

  • use position: fixed; over the entire component if it has <pre> as a parent. then find <pre>s parent and add to it transform: translate(0, 0)
  • change the current flow and use absolute positioning

support pip3 install command

We are not supporting install commands with pip3. Example:

image

Please add the pip3 install command to the unit tests, and the link above to the real-examples.yaml.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.