GithubHelp home page GithubHelp logo

le-git-imate / le-git-imate Goto Github PK

View Code? Open in Web Editor NEW
2.0 3.0 5.0 1018 KB

Sign commits through the GitHub/GitLab web UI

Home Page: https://le-git-imate.github.io/

License: Other

HTML 0.73% JavaScript 84.28% CSS 14.99%
security commit-signing verifiable-git-repository signed-commits signed-webui-commits gpg-signature le-git-imate

le-git-imate's Introduction

le-git-imate

le-git-imate is a defense mechanism to mitigate attacks against web-based Git hosting services such as GitHub and GitLab. le-git-imate pioneers the ability to sign a web UI commit and to create a true GPG-signed Git commit object in the browser. For more technical details, please refer to our paper le-git-imate: Towards Verifiable Web-based Git Repositories.

Installation

le-git-imate can be installed as an unpacked extension in the Chrome browser as follows:

  1. Download the latest version of the extension at the releases section.

  2. Unzip the extension.

  3. On your Chrome browser, go to chrome://extensions.

  4. Enable the Developer mode.

  5. Click on Load Unpacked and select the Unzip folder.

To the best use of le-git-imate, it is recommended that you take a look at the issue tracker before trying it out.

Security Issues and Bugs

Security issues, bugs and feature requests can be reported through GitHub issue tracker. Ideally, an issue documented as follows:

  • Description of issue or feature request
  • Current behavior
  • Expected behavior

License

Use of this source code is governed by the Licensed under the Apache License, Version 2.0 that can be found in the LICENSE file.

Website

https://le-git-imate.github.io/

About

This project is managed by Prof. Reza Curtmola and other members of the NJIT Cybersecurity Research Center at NJIT and the Secure Systems Lab at NYU.

Contact: [email protected]

le-git-imate's People

Contributors

hmdfsn avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

le-git-imate's Issues

Improve exception handler

Description of issue or feature request
There are many cases like the following ones that the extension can not handle properly.

  • Use a new packline whenever user hits the extension button: If the user hits the extension twice (before finalizing the commit), the packline would be override and thus corrupted.
  • Do not do anything if the user has not made a change in edit page

This issue is related to #1, #22, #23, #29.

Current behavior

  • There are many exceptions without a good handler.

Expected behavior

  • If user does something unexpected, the extension should notify her with a proper message.

Improve the documentation

Description of issue or feature request
Currently, the extension lacks a good documentation to guide users how to install and use le-git-imate on GitHub or GitLab.

Current behavior

  • The extension does not provide a well-written documentation.

Expected behavior

  • The documentation should be revised at least in two ways:
    -- tutorial: Details on how to set up and use the extension
    -- install: A brief description on how to install the extension

Allow users to upload key file in the setup

Description of issue or feature request
le-git-imate allows users to import keys as text. It can add an option to upload the key file.

Current behavior

  • le-git-imate does not allow to add an existing key file into the keyring by uploading the key file.

Expected behavior

  • Allow to import existing keys either as file or as text.
  • Allow the user to upload multiple key files

Display a proper message when key parameters are invalid

Description of issue or feature request
Upon the key evaluation, users must be notified with a proper message if any key parameter (such as wrong userId, expired key, etc.) is wrong. This issue could be fixed along with #1, #14, #22.

Current behavior
The extension does not always display proper messages if a key parameter is not valid. Currently it only checks userid and email for keys generated by the extension.

Expected behavior
All key parameters (e.g., userId, email, expiration date, key size, etc.) should be validated before adding the key into the local keyring.

Support both options of the upload request on GitLab

Description of issue or feature request
One regular commit on GitHub or GiLab is uploading a file. It can be done in two ways: (1) drop the file in the upload page, (2) browse the local system and select the file to be uploaded.
le-git-imate does not support the second option on GitLab.
This issue should be addressed with #7.

Current behavior

  • In case of upload a file on GitLab, le-git-imate does not supports browse and select a file.

Expected behavior

  • Support both options of the upload request on GitLab.

Implement proposed defenses against web UI attacks

Description of issue or feature request
Though the le-git-imate design considers some checks to defend against web UI attacks, the implementation has not considered those checks yet.

Current behavior

  • le-git-imate does not implement necessary checks against web UI attacks

Expected behavior

  • As stated in le-git-imate design, le-git-imate should implement at least two checks:
    -- consistency between data retrieved through the API and what is displayed in the UI
    -- possible hidden HTML tags

Remove an extra click in upload operation

Description of issue or feature request
When the user is ready to push the commit, she uses the le-git-imate extension, doing two clicks: (1) activate the extension, (2) push the commit button.
However, in case of the upload operation, the user should activate the extension before uploading the file which is an extra step.

Current behavior

  • The upload operation is possible only if the user activates the extension before uploading the file.

Expected behavior

  • No need to click the extension button before uploading the file.

Support importing keys from Keybase

Description of issue or feature request
Currently the user can import an existing key or generate a new one. An alternative solution to manage the keys is to allow users to import keys from the Keybase server.
P.S: This is a work in progress by le-git-imate team. There are some security concers that should be addressed in accordance with #13, #28.

Current behavior

  • le-git-imate does not allow to import key from a key directory like Keybase.

Expected behavior

  • Allow users to import key from Keybase.

Improve the merge algorithm

Description of issue or feature request
le-git-imate re-implements the git merge algorithm in JS. We need to revisit the merge component to address all potential issues. A list of things that we should look into is as follows:

Current behavior

  • There might be several merge cases that the current implantation is not able to address.

Expected behavior

  • Make the merge algorithm more reliable and fix potential issues listed above. You can start by looking into there refs: [1, 2, 3].

Swap title and summary fields in the merge commit message - GitHub

Description of issue or feature request

Doing a merge commit through the GitHub UI, le-git-imate does not include the merge title in the commit message.

Expected behavior

Add the merge title to the merge commit message. The title should have the following pattern:

Merge pull request #PR from <USER>/<BRANCH>

Do not store GitHub/GitLab password locally

Description of issue or feature request
The extension uses two types of credentials as follows:

  • password: GitHub/GitLab passowrd
  • token: The personal token allows users to use it in place of a password to perform Git operations over HTTPS with Git on the command line or the API on GitHub or GitLab.

From security point of view, we do not like to store the password locally. However, le-git-imate uses GitHub or GitLab tokens to authorize APIs, and the authorization for git-receive-pack protocol is based on the password. That is why le-git-imate asks the user to import the password for GitHub or GitLab account during the setup step.
This should be addressed in accordance with #13.

Current behavior

  • le-git-imate does not use token for all authorization processes and uses the password to authorize git-pack-protocol.

Expected behavior

  • Remove the need for user's password by using token for any authorization between client and the server.

Give users an option to create GitHub/GitLab token during the installation

Description of issue or feature request
The user should provide the personal token during the installation which may add some complexity for the user. It would be a good idea if the extension gets the token transparently (without involving the user).
This issue can be fixed in accordance with #28.

Current behavior
During the setup, le-git-imate asks the user to provide the personal token and gives no option to generate it on the fly.

Expected behavior
Allow users to generate the token during the installation.

Improve the user interface (UI)

Description of issue or feature request
Using new UI concepts and in accordance with #1 and #14, the extension interface can be improved in different ways.

Expected behavior
Several things can be updated.

  • popup window layout
  • Changed file sections in the window
  • More info about changed files (such as renamed, moved, etc.)
  • Better content and UI for error messages
  • logo
  • icons
  • fonts
  • etc.

Check if the current GitHub/GitLab user is able to perform a commit

Description of issue or feature request
Before performing any commit, the extension checks if an account is set for the server (i.e. GitHub acount, GitLab account). However, it does not check if credentials for the current user (extracted from the URL) are stored locally. This issue can be resolved in accordance with #6.

Current behavior

  • The extension does not check if the account info for the current user is set or not.

Expected behavior

  • Before computing the commit, the extension must make sure that if credentials for the current user are stored locally.

Expected behavior
We may decide to allow performing commits as long as credentials for one authorized account are stored locally. For example, perform the commit in the following scenario:

  • A person has two accounts User1 and User2. Both have access to push commit on a project.
  • le-git-imate has credentials to perform commit on behalf of User2.
  • The current user is User1.
  • The person tries to perform a commit.
    In this case the new commit would be created on behalf of User2.

Support merging branches with a large number of commits

Description of issue or feature request
One of the very first step in a merge commit is to compare the PR and master branch to determine the changes (i.e., added/deleted/modified files). le-git-imate uses different APIs to make the comparison on GitHub and GitLab.
However, those API may fail to function correctly if the number of commits in the PR exceeds a limit. On GitHub you can use the CompareBranch API to compare up to 250 commits. And if the number of changed files in a PR goes over 300, we can't simply use one API to list the files.
On GitLab, a diff API between two branches/commits may completely collapse if:

  • 50,000 lines have already been rendered.
  • 1000 files have already been rendered.

This issue could be address with #11.

Current behavior

  • le-git-imate does not support merging large PRs

Expected behavior

  • Support large merge commits which needs to
    -- first know all limitations we have when we use GitHub API to compare branches.
    -- second use alternative solutions like what is suggested by GitHub.

Validate account info before storing in the local system

Description of issue or feature request
The account info (GitHub/GitLab credentials) can be validated at the very beginning along with the key setting. Currently, le-git-imate stores account info without any check. This issue could be addressed in accordance with #1.

Current behavior

  • Account info (i.e., username, password, token) is not validated at the setup step.
  • The extension checks the account info as part the commit creation.

Expected behavior

  • Validate GitHub/GitLab account info. It should be done for username, password and token.
  • If the account is not set, the initial window should display a proper message asking user to import the credentials.
  • That's should be fixed for both GitHub and GitLab.

Alternative solution

Support multiple file uploads on GitHub

Description of issue or feature request
Unlike GitLab, GitHub allows to upload multiple files through one commit. le-git-imate does not support it yet.

Current behavior

  • If the user upload multiple files on GitHub, the extension takes only the first one and ignore the others.

Expected behavior

Create an informative response when the 'push commit' fails

Description of issue or feature request
If for any reason the commit is not be pushed successfully, the user should now be notified with a meaningful message. This can be addressed in accordance with #1, #14, #22.

Current behavior

  • le-git-imate does not let the user know what was the reason behind a failed push commit

Expected behavior

  • Provide a meaningful message if push commit failed.

Address security concerns on storing credentials locally

Description of issue or feature request
The extensions could be exploited by web applications from their privileged capabilities. And malicious scripts on the page may be able to access the local storage and retrieve sensitive info stored by our extension. Read more about the issue on chrome dev page and academic papers like this. Also take a look at threatpost, infosecbuzz.

le-git-imate stores some sensitive info (token, password) locally. As mentioned in #28, we should first remove the need of password and then protect the token.

Current behavior

  • The extension does not properly take care of the security of stored credentials.

Expected behavior

  • Do not use passwords (#28).
  • Protect the personal token.

Add unit tests and test coverage

Description of issue or feature request
The current version (v0.1) has no test component. We would like to add:

  • unit tests
  • test coverage

Support all merge options on GitHub

Description of issue or feature request
GitHub allows the user to do a merge in three ways:

  • Create a merge commit: All commits from the pull request (PR) branch will be added into the master branch
  • Squash and merge: All commits from the PR branch will be squashed into a single commit and that commit goes to the master branch.
  • Rebase and merge: All commits from the PR branch will be added onto the base branch individually without a merge commit.

Current behavior

  • le-git-imate does not support all merge options on GitHub and only allows one option: Create a merge commit

Expected behavior

  • Support all three options to merge a PR on GitHub

Check if the commit signature extraction is always reliable

Description of issue or feature request
To create a signed commit, the signature is computed over the commit fields. Then it is extracted from the commit by using a specific string pattern. Next the commit and its signature form a signed Git commit which will be used to create a signed Git commit object.
We need to make sure that the signature extraction always works.
This issue could be resolved in accordance with #3.

Current behavior

  • le-git-imate uses a very basic approach to extract the commit signature which may fail in some corner cases (if there is any!).

Expected behavior

  • Add unit tests to make sure commit signature extraction function works correctly.

Improve the popup window

Description of issue or feature request
The popup window can be improved by adding more options and by making it more user-friendly. This should be addressed In accordance with #22.

Current behavior

  • The initial window has a config button with no other options. The layout is very basic.
  • The main window (which displays commit info) has a basic layout with a fixed size.

Expected behavior

  • Options could be added to the initial window and its layout could be improved.
  • The main window may have a dynamic size regarding the commit type and commit info. Also it could have a better layout.

Replace the username whit the author/committer name in the commit object

Description of issue or feature request

le-git-imate forms the author/committer name using the GitHub/GitLab username. While it should be the name assigned to the GitHub/GitLab account.
This issue could be addressed in accordance with #41.

Current behavior

Each commit object has an author/committer name. le-git-imate forms this field using the username taken from the URL.

Expected behavior

Instead of using username as the committer/author name, le-git-imate should use the name associated with the GitHub/GitLab account.

Remove 'Read your browsing history' from the popup that appears while installing le-git-imate from Web Store

Description of issue or feature request
While installing le-git-imate from the chrome web store, a popup appears requesting permission to read the user's browsing history. Since le-git-imate does not read the user's browsing history', that is not required.

Current behavior
While installing le-git-imate from the chrome web store, upon clicking 'the Add to Chrome' button, a popup appears. The popup contains the following message:

Add le-git-imate?
It can:
Read and change your data on github.com and gitlab.com
Read your browsing history

However, le-git-imate does not read the user's browsing history.

Expected behavior

The 'Read your browsing history' part needs to be removed from the installation-time popup message.

Display proper messages if user credentials are not authorized

Description of issue or feature request
le-git-imate assumes that imported account info is correct. Talking to the server, the user is authorized using the stored data (i.e., token or password). However, the authorization may fail. In this case, le-git-imate should notify the user about the issue. Depending on how we address #4, the message may be displayed in different steps.
This issue may be addressed in accordance with #14, #26.

Current behavior

Expected behavior

  • Display a message when user is not authorized to call and API or preform the git-pack protocol.

Remove any recursive option in tree retrieval from GitHub

Description of issue or feature request
Trees that need to be fetched to perform a regular commit on GitHub are not retrieved in a smart way. Actually, le-git-imate gets all trees at once using the recursive option. That is not a good option when working with large repos as it can cause a timeout.

Current behavior

  • The regular commit on GitHub does not use non-recursive approach when it comes to tree retrieval.

Expected behavior

  • Replace the recursive approach with the non-recursive one to retrieve trees on GitHub.
    P.S: The non-recursive approach is developed but not ready to be integrated yet.

Validate the file path when it is needed in a regular commit

Description of issue or feature request
As a regular commit, the user can add a new file or rename a file. In both cases, the new file path should be validated. It should be address in accordance with #10, #16.

Current behavior

  • le-git-imate does not validate the file path.

Expected behavior

  • Validate the file path when a new blob is added or an existing one is updated.
  • Some example checks:
    -- If the file already exists
    -- If the file name is valid
    -- If new directory name is valid

Support 2FA authentication

Description of issue or feature request

le-git-imate can not perform a webui commit is the user enables two-factor authentication (2FA) .
This could be addressed in accordance with #13 and #28 .

Current behavior

Once a user enables 2FA, they can not use password for the authentication and instead they must create a personal token to use as a password when authenticating to GitHub.

However, the current version of le-git-imate uses the token only to authenticate GitHub/GitLab APIs and the authentication for git-receive-pack protocol is done by password. As a result, if a user enables 2FA, they can not use the le-git-imate extension to sign the webui commits.

Expected behavior

le-git-imate must use the personal token for any authentication which means the basicAuth should be replaced with a token-based approach.

Check if the action is commitable before performing the commit

Description of issue or feature request
In the current version, the extension performs a commit if two requirements are passed:

  1. Run the extension on GitHub or GitLab
  2. Run the extension on a commit page

Trying to use the extension when above requirements are not passed, the user would be informed about the requirements. However, there are situations in which both checks are passed and still the extension should not be executed:

  • Delete a file on GitLab without user confirmation: Though GitLab performs the delete operation by asking for a user confirmation, the le-git-imate extension can delete a file without such a confirmation.
  • Perform a closed merge: The extension raises an error if the user tries to commit a closed merge.
  • Perform a merge conflict: The extension raises an error if the user tries to perform a merge before addressing the conflicts.

Current behavior

  • Delete a file on GitLab: Though GitLab performs the delete operation after a confirmation, the le-git-imate extension can delete a file without performing a two-step confirmation confirm the delete. That behavior is not consistent with GitLab.
  • Try a closed merge: The extension does not show a proper message if the user tries to commit a closed merge.
  • Try a merge conflict: The extension does not show a proper message if the user tries to perform a merge before addressing the conflicts.

Expected behavior
We can add a few checks before performing the commit to make sure above issues are addressed.

  • Delete a file on GitLab: Check if the commit message text area exists, then perform the delete. That is enough to make sure that the second step of delete operation is already taken place.
  • Try a closed merge: Check if the green merge button is available.
  • Try a merge conflict: Check if the green merge button is available.

Allow user to store multiple keys for commit signing

Description of issue or feature request
The initial setup allows the user to store only one key pair in the local system and add new key, the previous one is replaced with new one. It should be addressed in accordance with #19.

Current behavior

  • User store only one key to sign commits

Expected behavior

  • Display stored keys in a new page
  • Allow the user to set the default signing key in the config page

Allow the user to store multiple accounts per server

Description of issue or feature request
Currently, le-git-imate does not allow to store multiple accounts per server (GitHub or GitLab).

Current behavior
le-git-imate stores only one account for GitHub and one account for GitLab. In case the user adds a new account, the previous one is replaced with the new one.

Expected behavior
Allow to user to store different GitHub or GitLab accounts. So they can benefit from le-git-imate on different accounts.

Allow users to config the GitLab server

Description of issue or feature request
Currently, le-git-imate supports only commits on GitHub and GitLab though it is compatible with any GitLab hosting service. Since users can set up their own GitLab server, it would be a good idea to allow them config the GitLab server address.

Current behavior

Expected behavior

  • Allow users to config their own GitLab server.
  • Different parts of the code must be updated including the the setup UI and configs.

Fix issues with merge algorithm

Description of issue or feature request
The merge algorithm can not support some merge requests due to issues in two functions:(1) xmerge/xdl_refine_conflicts, (2) xdiffi/xdl_split.

You can replicate the issue in the xdl_refine_conflicts function, if, for example, you perform the following PRs by the le-git-imate extension:
golang/go#33882
github/gitignore#3121

You can replicate the issue in xdl_split function, if, for example, you perform the following PRs by the le-git-imate extension:
vuejs/vue#10167
golang/go#33870
facebook/react#16591
ytdl-org/youtube-dl#22063

Current behavior

  • le-git-imate does not perform merge requests if xmerge/xdl_refine_conflicts and xdiffi/xdl_split functions get involved.

Expected behavior

  • Fix issues with xdl_refine_conflicts and xdl_split functions. This can be done as part of #32.

Make sure if regular expressions work for corner cases

Description of issue or feature request
le-git-imate uses different regular expressions to validate username, email, key userId, etc.
It should be fixed in accordance with #4.

Current behavior

  • Acceptable reference is not provided for all used regex.

Expected behavior

  • Add a valid reference for all regex
  • Add more regular expressions to handle corner cases.

Use a GitHub verified email in the committer field

Description of issue or feature request

le-git-imate does not assign a proper email to the committer. Thus, GitHub is not able to verify the signature created in the browser.

Current behavior

The user's GPG key must be associated with a GitHub verified email that matches the committer identity. Otherwise GitHub is not able to verify the webui commit signature (created by le-git-imate). Currently, le-git-imate creates the committer email as follows: <username>@users.noreply.github.com which causes the issue.

Expected behavior

Instead of using <username>@users.noreply.github.com as the committer email, le-git-imate should use an email that is associated with the GPG key.

Take care of corner cases in URL parser

Description of issue or feature request
URL parser uses some keywords to detect the commit type, file path, ect.
However, if the file path contains one of le-git-imate's keywords, then performing the commit may fail as le-git-imate cannot parse the URL correctly.
In the following example while parent directory is "dnew", le-git-imate takes it as "d" and then it can not perform the commit.

https://gitlab.com/<user>/<repo>/dnew/master/new

This issue should be fixed in accordance with #14.

Current behavior

  • There are some corner cases in which extension is not able to parse the URL correctly.

Expected behavior

  • Make sure that all corner case are handled by URL parser.

Display the content of new file in the changed section of popup window

Description of issue or feature request
The changed section in the popup window only shows changed content of an existing file (as a result of edit operation). We should display the content of new file in the window to make sure a malicious scripts have not changed the content. This should be addressed in accordance with #22.

Current behavior

  • Changed section of pop window display only changes of an edited file.

Expected behavior

  • Display the content of added and uploaded files as well by updating this part of the code.

Support merge commits with more than one common ancestor (CA)

Description of issue or feature request
le-git-imate assumes that each merge commit has only one CA. However, this assumption could be violated in creation cases.

Current behavior

  • A merge commit with more than one CA is not possible.

Expected behavior

  • Allow the user to perform a merge commit with more than one CA. To do so, we should look into examples on GitHub/GitLab in which a merge commit has more than one CA and see how those cases are handled.

Support the UI actions for updating the file path

Description of issue or feature request
GitHub and GitLab allows to change the directory path through the web UI. For example moving a file as follows:

  dir1/dir2/dir3/file1 --> dir1/dir6/file2

The extension, however, does not support commit creation for such an operation.

Current behavior

  • If a commit involves move operation, le-git-imate neither performs the commit correctly nor notifies the user properly.

Expected behavior

  • Support move operation as a possible web UI action on GitHub and GitLab.

Make commit type detection algorithm more reliable

Description of issue or feature request
Looking into the URL, le-git-imate can detect the commit type since the URL corresponding to each commit has a unique pattern. More details is described here. However, the upload operation on GitLab is an exception as the URL does not have a specific pattern. We should make sure that the current approach to detect upload operation on GitHub is fully reliable.
This issue may be resolved along with #8.

Current behavior

  • The current approach to detect upload operation on GitHub is not fully reliable.

Expected behavior

  • Make sure that le-git-imate detects commit types correctly (in particular the upload operation on GitLab).
  • Add unit tests.

Make the key generation parameters optional

Description of issue or feature request
The key generation function does not get all parameters from the user. Instead it uses predefined values as follows:

   key expiration: 0
   key size: 2048
   passphrase: ""

Current behavior

  • The key generation process allows the user to neither set a key expiration nor to pick the key size nor to set a key passphrase.

Expected behavior

  • Update the setup UI to get new key parameters.
  • Use the parameters during the key generation process
  • Update the key retrieval process

Make le-git-imate function properly on Manjaro Linux

Description of issue or feature request
On Manjaro Linux, le-git-imate works fine upon installation. However, upon restarting the system, the extension persists with the 'Configure le-git-imate to get started' popup even after the extension has been configured.

Current behavior
After installing le-git-imate on Manjaro Linux, if the user restarts the system, configures the extension and then clicks on the le-git-imate icon, the popup still contains the 'Configure le-git-imate to get started' message along with the 'Settings' button. Upon clicking the 'Settings' button, the configuration page appears with all the fields blank.

Expected behavior
Le-git-imate must function normally like it does on other operating systems.

Generate a personal token on behalf of the user

Description of issue or feature request
Users have to provide their personal tokens as part of the setup. To do so, they must generate a new token as follows (if not have already of if can't remember the existing one):

Github -> Settings -> Developer settings -> Personal access tokens -> Generate new tokens

Would be great if the extension does that on behalf of the user. This way the user herself does not have to take care of this procedure.
This issue might be addressed in accordance with #40.

Current behavior
The extension does not allow the user to generate the personal token on the fly.

Expected behavior
Allow the user generate the token during the installation rather than providing an existing one.
One possible solution is to obtain the username and password from the user, generate an access token on her behalf, store the access token and discard the password.

Related resources: [1], [2], [3].

Support a special regular commit on GitLab: create a new directory

Description of issue or feature request
GiLab allows users to create a new directory as a regular commit. This operation is not supported by le-git-imate. The issue can be addressed in accordance with #10.

Current behavior

  • le-git-imate does not support creating a new directory as a regular commit.

Expected behavior

  • Support create new directory through GitLab web UI.

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.