Giter VIP home page Giter VIP logo

auth0-authorization-extension's Introduction

Auth0 Authorization Extension

This extension provides authorization features for Auth0 focused on RBAC and user group management.

Status Update

The Authorization Extension is in maintenance mode. We do not plan on adding new features to the extension as we are working to bring features of the extension into the core Auth0 platform. Bug fixes and security patches will still be made.

Documentation

We provide documentation on how to install and use the Authorization Extension on the Auth0 docs website.

How does this compare to the core Authorization features in Auth0?

We have RBAC available in Auth0 as a core feature of the platform, rather than requiring the use of this extension.

For a detailed summary of the differences between this extension and the core features of the platform, check this document.

We advise using the core capabilities rather than the extension as they are built to meet the high scalability needs of the Auth0 platform.

Why do we rely on a fork of hapi?

Due to the SameSite cookie changes in browsers, we needed a version of Hapi that supported the changes. The easiest path forward was to fork Hapi and port the changes needed over, as we are relying on an older version of Hapi that is not receiving the updates required to respect SameSite cookies.

Development Setup

Requires Node 12 - higher versions not yet supported. If you are using nvm, simply run nvm use inside the directory to switch to the correct version.

  1. Clone this repo.
  2. Run npm ci.
  3. Get Argo Tunnel: brew install cloudflare/cloudflare/cloudflared

Create a local config

To run the extension, you'll need a file in server/config.json that specifies how the extension interacts with Auth0. Here is a sample for running the extension with a production tenant:

{
	"AUTH0_DOMAIN": "mytenant.auth0.com",
	"AUTH0_CLIENT_ID": "qwerty123",
	"AUTH0_CLIENT_SECRET": "longer-secret-value",
	"EXTENSION_CLIENT_ID": "abcd123",
	"EXTENSION_SECRET": "longer-secret-value",
	"WT_URL": "http://localhost:3000",
	"PUBLIC_WT_URL": "http://localhost:3000",
	"AUTH0_RTA": "https://auth0.auth0.com"
}

Copy this config into the file created at server/config.json and modify the following values:

  1. Set your tenant name in the AUTH0_DOMAIN option.
  2. Create a client in that tenant. This client should be an SPA (Single Page App).
  3. Enter the client ID and client secret as both the AUTH0_CLIENT_ID/_SECRET as well as the EXTENSION_CLIENT_ID/_SECRET.

Running in production mode

  1. Build the client: npm run build.
  2. Start an Argo proxy via: cloudflared --url http://localhost:3000
  3. Open server/config.json and enter the URL provided by Argo Tunnel into the WT_URL and PUBLIC_WT_URL options.
  4. In another terminal, start the server in production mode with npm run serve:prod.

You can then open the URL provided by Argo Tunnel to use the extension.

Running in development mode

  1. Start an Argo proxy via: cloudflared --url http://localhost:3001
  2. In another terminal, run WT_URL=https://<PROVIDED_BY_CLOUDFLARE>.trycloudflare.com npm run serve:dev. Replace the URL with the one provided in the previous step. Please note that the development mode works only in Chrome.

Running tests

Run tests with npm test.

auth0-authorization-extension's People

Contributors

6footgeek avatar aarongodin avatar bazarov1988 avatar crew-security avatar crigot avatar csakshaug avatar dependabot[bot] avatar dmeechan avatar fadymak avatar francocorreasosa avatar fyockm avatar ittus avatar ivesprime avatar jcenturion avatar jhiner avatar kusold avatar lbalmaceda avatar mattstewart avatar mcastany avatar mostekcm avatar nicosabena avatar sandrinodimattia avatar santiagoaguiar avatar sericaia avatar sgmeyer avatar shawnmclean avatar sre-57-opslevel[bot] avatar twistedstream avatar ubenzer avatar zxan1285 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

Watchers

 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

auth0-authorization-extension's Issues

ASP.NET 4.5 MVC OWIN

Can anyone point me in the direction of how to use this with ASP.NET 4.5 / MVC / OWIN?

API Access swagger.json issue on private instance.

Environment
One node installation of private instance with version 10258, enabled all the required features to run this extension.

Issue

On the API page following error is shown. The full stack trace can be found by visiting the page https://demo-toon-webtask.XXX.com/api/run/demo-toon-teneant/adf6e2f2...9201/swagger.json

Oh snap! You got an error!

An error occured while loading the api explorer configuration: { "schemes": [ "https,http" �[31m[1]�[0m ], "basePath": "/", "swagger": "2.0", "host": "demo-toon-webtask.XXX.com" } �[31m [1] "0" must be one of [http, https, ws, wss]�[0m

Rule overwrites roles and permissions in app_metadata each time the user login with a different application

The current rule template fails to correctly merge roles and permissions to app_metadata.

Given that roles and permission are now per-application, each time the user login in application, the roles and permissions saved in user.app_metadata.authorization gets overwritten with the roles and permission for that application.

The expected behaviour is that the app_metadata.authorization roles and permissions would be grouped per clientId, or an equivalent solution.

Support S3 as a storage provider

We currently use webtask storage to persist groups, roles and permissions. Support these additional providers to go beyond the storage limit.

Error in Authorization Extension if Group Mappings exist

I have a group in the authorization extension with just one group mappings- i.e. A windows azure AD connection and a group.

The authorization extension errors out with the following error on every execution. A customer has also raised this issue and is a priority now. Please let me know if you need more information on steps to repo.

2016-07-31T00:27:43.039Z - error: TypeError: Cannot read property 'members' of undefined
at /data/auth0-authz-1.4.js:1:16552
at arrayEach (/data/node_modules/lodash/index.js:1289:13)
at Function. (/data/node_modules/lodash/index.js:3345:13)
at /data/auth0-authz-1.4.js:1:16447
at arrayEach (/data/node_modules/lodash/index.js:1289:13)
at Function. (/data/node_modules/lodash/index.js:3345:13)
at /data/auth0-authz-1.4.js:1:16374
at tryCatcher (/data/_verquire/mongoose/4.1.6/node_modules/mongoose/node_modules/mquery/node_modules/bluebird/js/main/util.js:24:31)
at Promise._settlePromiseFromHandler (/data/_verquire/mongoose/4.1.6/node_modules/mongoose/node_modules/mquery/node_modules/bluebird/js/main/promise.js:454:31)
at Promise._settlePromiseAt (/data/_verquire/mongoose/4.1.6/node_modules/mongoose/node_modules/mquery/node_modules/bluebird/js/main/promise.js:530:18)
at Promise._settlePromiseAtPostResolution (/data/_verquire/mongoose/4.1.6/node_modules/mongoose/node_modules/mquery/node_modules/bluebird/js/main/promise.js:224:10)
at bound (domain.js:287:14)
at Promise.runBound (domain.js:300:12)
at Async._drainQueue (/data/_verquire/mongoose/4.1.6/node_modules/mongoose/node_modules/mquery/node_modules/bluebird/js/main/async.js:182:12)
at Async._drainQueues (/data/_verquire/mongoose/4.1.6/node_modules/mongoose/node_modules/mquery/node_modules/bluebird/js/main/async.js:187:10)
at Immediate.Async.drainQueues as _onImmediate
at processImmediate as _immediateCallback
[00:28:51.463Z] INFO wt: finished webtask request 1469924861447.804533 with HTTP 500 in 1596ms
[00:28:51.465Z] INFO wt: 2016-07-31T00:27:43.045Z - info: POST /api/run/pushp/adf6e2f2b84784b57522e3b19dfc9201/api/authorize/waad%7Cwt6mnFMVA264M7RvrmXH4L95GGkJCJBjawRlTufFjlU 500 112.585 ms - 57
[00:28:51.481Z] INFO wt: Access Denied: { message: 'Cannot read property 'members' of undefined' }

Updating from v1

We should:

  • Show a warning about breaking change (applications)
  • Test the update from v1 to v2 and make sure the new non-interactive client is created correctly

Upgrade Node.js for security fixes #security-nodejs-20160209

Please upgrade Node.js to v0.12.10, v4.3.0, v5.6.0, or newer, to address the security issues listed here:
https://groups.google.com/forum/#!topic/nodejs-sec/G8IA0G4uA88.

Due date for this request is 2016-02-26.

This update addresses the following issues:

Please acknowledge that you've received this request and that it makes sense.
If it's not applicable to your repo, let me know so I can fix my list.

Thank you!

Is there API support for this extension?

It looks like users could be added to groups programmatically by adding the group to the user profile in the app_metadata section. Is it also possible to create groups via an API?

Ability to preload social users into groups

First, if this functionality exists already and I just haven't figured out how to do it, apologies and if you can point me to the docs on this and close this issue, I'd appreciate it.

I have an existing user base with Google accounts. I want to add those users into an authorization group so I can grant them access to things. Currently, I have to ask them to login to a special Client I've setup that doesn't do anything which gets them into that Auth0 system after which point I go and add them to a group in authorization. I do this every few weeks, email users asking them to go do an auth0 google auth, then I go back and see who did it and add them into a group. It's very tedious and there's a long tail I'll never be able to add.

How can I take my list of existing Google account email addresses and add those to an authorization group despite the fact that they haven't yet tried to log in?

Support federated users

For enterprise connections, you'll only be able to see users that have logged in at least once. If we think about user provisioning, it could be that a new employee is starting next week and that we want to already assign them to groups/roles.

In that case, we need a way to assign these "unknown" users to groups and roles.

Extension not playing nicely with Extensions in the Auth0 dashboard

Just experimenting with Auth0.

Looks pretty awesome and I'm interested in how it can be extended to manage more granular permissions.

This extension looks cool but I can't find it in the Extensions via the dashboard...

screen shot 2016-05-09 at 17 47 47

...and when I try to add it I get an Error message telling me it's already there...

screen shot 2016-05-09 at 17 45 53

I'm currently on the trial plan. I realise this may be an Auth0 user support thing rather than an issue but thought it was worth raising here.

Thanks :)

Open link in new tab gives blank page

When using the Authorization Extension in the auth0 public cloud, when either control clicking on any of the 3 tabs (Applications, Groups or Users) in the extension, or when right clicking to open that link in a new tab, the resulting new tab comes up blank.

Steps to reproduce

  • Open the authorization extension
  • Right click Users and select Open Link in a new Tab

Expected results

To see a new tab with the authorization extension showing users

Actual results

A new tab with the following content


  <!DOCTYPE html>
  <html lang="en">
  <head>
    <title>Auth0 - Authorization</title>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="shortcut icon" href="https://cdn.auth0.com/styleguide/2.0.1/lib/logos/img/favicon.png">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="https://cdn.auth0.com/styles/zocial.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.auth0.com/manage/v0.3.973/css/index.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.auth0.com/styleguide/3.8.4/index.css">
    
    <link rel="stylesheet" type="text/css" href="//cdn.auth0.com/extensions/auth0-authz/assets/auth0-authz.ui.1.4.5.css">
  </head>
  <body>
    <div id="app"></div>
    <script type="text/javascript" src="//cdn.auth0.com/js/lock-9.0.min.js"></script>
    <script type="text/javascript" src="//cdn.auth0.com/manage/v0.3.973/components/ZeroClipboard/ZeroClipboard.js"></script>
    <script type="text/javascript" src="//cdn.auth0.com/manage/v0.3.973/js/bundle.js"></script>
    <script type="text/javascript">window.config = {"AUTH0_DOMAIN":"iocoop.auth0.com","IS_ADMIN":false,"BASE_URL":"https://sandbox.it.auth0.com/api/run/iocoop/adf6e2f2b84784b57522e3b19dfc9201","BASE_PATH":"/api/run/iocoop/adf6e2f2b84784b57522e3b19dfc9201"};</script>
    
    
    
    <script type="text/javascript" src="//cdn.auth0.com/extensions/auth0-authz/assets/auth0-authz.ui.vendors.1.4.5.js"></script>
    <script type="text/javascript" src="//cdn.auth0.com/extensions/auth0-authz/assets/auth0-authz.ui.1.4.5.js"></script>
    
  </body>
  </html>

Send all issues to Sentry.io

It's hard to get information about customer issues for extensions that have been deployed in their account. Using Sentry.io we can have all unhandled exceptions sent to a single location.

Storage concurrency not implemented, writes silently failing

I have an array of permissions that I am creating programatically through the API. I use a Promise.map to loop over each permission and send a request to the API. Each request returns me the permission object and status 200, implying that the operation was successful. However, when I looked at the dashboard it consistently only actually created a subset of the ones it said it did. For example, for an array of six permissions, it would only create between 2 and 5 of them, on at least five different tries (I repeatedly went to the dashboard and deleted all of the permissions and tried again).

I solved this by adding the concurrency: 1 option to the Promise.map, so that only one request is out at a time. This fixed the issue by leaving more time between the requests (I likely could have put a delay instead), and it now actually creates all the permissions it says it did. Even with concurrency 2 however, it would return success and a permission object, only for it to not actually exist.

Here is part of the code:

return Promise.map(permissions, function(permission) {
    
    // if permission exists do nothing
    if (permission exists) {
       return;
    }
    
    return request(permissionOptions)
       .then(function(resp) {
          console.log(resp);
       }
}, {concurrency: 1}) // concurrency must be limited to 1 or only some permissions are created

Without concurrency set to 1, for all of my permissions it will log successful creation in the console.log, but not all would exist.

Configuration not being saved

When I go to configuration and add for example "groups" to the Token Contents, the values are not saved after clicking on "publish rule". The switch remains green, but when I reload the page it is inactive / grey again. Something I am doing wrong?

Also in the "id_token" that I get when loggin in with the node-auth library, I do not see any roles, groups or permissions. Is it the "id_token" that these values will be added to, or is it another token? How would I get it for a user in the "username-password-database" with the node-auth library?

Using the Dashboard connection Try button doesn't produce tokens with roles or permissions

Because the Try button using the global Auth0 client, the token that results from an auth flow will never contain roles or permissions. This is because roles and permissions are tied to a specific application (client_id) but that is never the global client.

You can see this in the auth0-authorization-extension rule that the extension generates when it makes it's call to the policy endpoint:

  function getPolicy(user, context, cb) {
    request.post({
      url: EXTENSION_URL + "/api/users/" + user.user_id + "/policy/" + context.clientID,
      headers: {
        "x-api-key": "a82e327704511ce8732f38a176d4ad00d813b70c86add5e696567ff4df914472"
      },
      json: {
        connectionName: context.connection,
        groups: user.groups
      },
      timeout: 5000
    }, cb);
  }

I got tripped up on this until I realized what was going on. Perhaps we should add something to docs that explains that if you want to try an authentication flow, you'll need to do it with a client that you've secured with the extension. It might be cool to actually have a Try tool build right into the extension so people can see that the resulting token appears as they expected.

Extension rule uses root-level non-namespaced claims

Specifically, these lines:

      // Update the outgoing token.
      user.groups = data.groups;
      user.roles = data.roles;
      user.permissions = data.permissions;

This has no effect when used with an OIDC-conformant login flow.

Duplicate roles show up in the token/metadata

When I'm a direct member of a role, but at the same time I get this role through a group, it shows up twice:

"roles": [
   "Submitter",
   "Submitter"
 ],

We need to make sure all permissions, groups and roles are unique.

The user picker should show the connection name

There are cases where a user with the same email address and name might exist in multiple connections (eg: DB + AD). This is why we should have the following:

  • Show the connection name next to each user (both in the picker and in the overview)
  • The filtering in the picker should be done based on the user_id and not on the email address

Support pipeline v2 (API Authorization)

In pipeline v2 the context exposes the idToken and accessToken. Our configuration should list options to store groups/roles/permissions in one of these tokens AND also allow you to define a custom attribute name (namespaced) for each property, like:

https://schemas.mycompany.com/groups

Invalid Token when accessing anything

I have just set up this extension and when I try to access any users I get the following error:
error

When I stream the log output to my local console I get the following output:

data: Response: {
      "data": null,
      "isBoom": true,
      "isServer": false,
      "output": {
        "statusCode": 401,
        "payload": {
          "statusCode": 401,
          "error": "Unauthorized",
          "message": "Invalid token"
        },
        "headers": {
          "WWW-Authenticate": "Token error=\"Invalid token\""
        }
      }
    }

It occurs repeatedly for (what seems like) any call to the Manangment API. I have admin rights (I created our Auth0 account), so I'm not sure why this is happening.

Group / Members tab has error if you delete a user in the Dashboard that's been assigned to the group

Steps to reproduce:

  1. Create a new user in the Auth0 Dashboard
  2. Assign that user to a group in the extension
  3. Delete the user in the Dashboard
  4. Navigate to the group's Members tab and you'll see an error like this:

image

Obviously the extension doesn't know when a user it's managing has been deleted from Auth0. It needs to be able to tolerate this and perhaps remove the user from its store when this is detected, although I don't like changing state (eg. remove a user) as the result of a query.

Support roles and permissions passthrough

We already support groups passthrough, but in addition to that should also support roles and permissions passthrough:

  • Add 2 more switches on the configuration page
  • In the rule also support merging of existing roles and permissions

Styles changes.

General:

  • Check modal styles (buttons etc)
  • Change loading blur styles.
  • Add sidebar icons
  • Show empty states at the proper time.

Users:

  • Add user empty state.
  • Filter between users and federated users (pending login). Make two separate sections with a search bar for each one (you can search by different properties of the users). (Check with @sandrinodimattia )
  • User section copy (Have to check with Julieta/Victor)
  • Users and federated users sub-section copy. (Have to check with Julieta/Victor)

User detail:

  • User detail view, missing content for Roles section. (Check with @sandrinodimattia )
  • Add user to groups modal -> Change modal adding selects so you can add an user to multiple groups at the same time (match design).
  • Change 'Add user to group' modal styles (buttons)
  • Change groups table remove button styles to match design.

Group:

  • Add new group modal copy.
  • Add new group modal Members autocomplete search.
  • Add "Add user" button to groups table.
  • Implement modal screen of group created / code 👇
    image

Group detail:

  • Change section header to match user detail style.
  • Remove 'Back to groups' button
  • Can't add users to a group, check all the screens of this flow (Modal ui to add users is different)
  • There is no roles tab, ask Sandrino.

Roles:

  • Change roles table icons.

Meetup with Sandrino

  • Create user button in Users Federated section -> Show modal to create
  • Check flow ux for empty state of sections.
  • User header change loading state. (make loading all the panel)
  • Change loading state blur
  • Make two sections inside User Groups and Group members that show (Explicit Group Memberships and All Group Memberships) Like the actual extension
  • Multiselect list table component
  • Change typeahead template (try with react-typeahead or change component)
  • If it is the first time you create a group show the Tutorial code modal.
  • Add "Add user to group" button to the groups section table.
  • Add "Create group" copy for modal.
  • Delete "Refresh" button from groups section table.
  • Remove member edit in "Edit group" modal.
  • Group detail: show edit group modal when clicking header edit button.
  • Group detail: change delete group icon and show modal.
  • Group detail: Roles tab with UI mockup.
  • Group detail: Add member button show modal (only show typeahead)
  • Configuration: Groups Passthrough box borders
  • Configuration: show warning modal ui when clicking on Publishing rule.
  1. Permissions
  2. Roles
  3. Groups
  4. Users

Later:

  • Create search component

Deleting this extension fails on private instance

Environment
One node installation of private instance with version 10258, enabled all the required features to run this extension.

When deleting this extension via the dashboard following error occures.

Request URL:https://demo-toon-webtask.XXX.com/api/run/demo-toon-teneant/adf6...c9201/.extensions/on-uninstall
Request Method:DELETE
Status Code:500 Internal Server Error
{"error":"Error: socket hang up\n    at createHangUpError (_http_client.js:211:15)\n    at Socket.socketOnEnd (_http_client.js:303:23)\n    at emitNone (events.js:72:20)\n    at Socket.emit (events.js:166:7)\n    at endReadableNT (_stream_readable.js:913:12)\n    at nextTickCallbackWith2Args (node.js:442:9)\n    at process._tickDomainCallback (node.js:397:17)"}

Webtask log show warn entry

[2017-02-06T12:32:09.647Z]  WARN: webtask-master/1 on a0-1: failure during request proxying (req_id=1486384294527.772649, deployment_key=local, tenant=demo-toon-teneant, container_id=1824e79f-3a73-4a57-8882-XXX, attempt=1, last_attempt=true, code=ECONNRESET, error="socket hang up")

Documentation for v2

The documentation should cover:

  • The fact that we dropped support for applications
  • What are groups + group mappings
  • What are roles
  • What are permissions
  • The configuration section (storing in token or metadata)
  • API access

Trying to determine api-key (for use in rules configuration settings)

hi,

when installing the extension and it's rule script the following lines are generated (a snippet from the complete function/script):

  // Get the policy for the user.
  function getPolicy(user, context, cb) {
    request.post({
      url: EXTENSION_URL + "/api/users/" + user.user_id + "/policy/" + context.clientID,
      headers: {
        "x-api-key": "4d38c7e0ba5f9844092cd589d22e2cc10d341226dd5d8fb1b6692531110aad61"
      },
      json: {
        connectionName: context.connection || user.identities[0].connection,
        groups: user.groups
      },
      timeout: 5000
    }, cb);
  }

I am trying to figure out a way to determine/retrieve the 'x-api-key' value for a given installation of without having to publish the generated rule (I have a custom variant of the script which I am trying to make "configuration based" so I can deploy the same script to different account") so that I can add a [global] rules-configuration setting.

is it possible to determine the correct api-key value without publishing the rule (and copy/pasting the relevant value from the generated script code)?

Deleting Group does not update app_metadata

I have created 2 groups to play with, called "Group 1" and "Group 2" and assigned users to them. Later on I deleted the groups but noticed that the app_metadata of the users were not updated:

image

Should the group membership not be removed from the user app_metadata when a group is deleted?

Add a detail page for Roles

We can currently assign users to roles directly, but you are not able to get an overview of all users that are assigned to a role.

We should create a detail page for roles, where you can see all of the permissions, but also all of the users assigned to that role.

Creating a Role/Permission in v2 requires an Application

Great work on v2, but to create a Role or Permission, it is necessary to specify an Application.

However, applications were removed in v2, and it's no longer possible to create on so the dropdown remains empty...?

Forgive me if I'm overlooking something, but as far as I can see there is no way to create a Role or Permission right now?

Installing the extension with the rule enabled breaks "Try" button for all logins

By default all users are allowed to access all applications, except for the global client (ironically named "All Applications" by default) which is used by the "Try" button from the management dashboard.

The extension should either make an exception for the global client or show it under the list of applications inside the extension.

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.