Giter VIP home page Giter VIP logo

bell's People

Contributors

aboutvale avatar adrivanhoudt avatar arb avatar bbatliner avatar brand7n avatar cjihrig avatar dapus avatar devinivy avatar dpmott avatar edimoldovan avatar eiriksm avatar geek avatar hofan41 avatar hueniverse avatar jarrodyellets avatar jsatk avatar ksck23 avatar ldesplat avatar lloydbenson avatar marsup avatar nargonath avatar pankajpatel avatar paulmougel avatar phitran avatar robertd avatar satnam-sandhu avatar sholladay avatar slaawwa avatar tameraydin avatar tanepiper 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bell's Issues

Fix POST payload format and location

The client resource() method puts POST payloads in the query. Also, some providers (I'm looking at your stupid face Twitter) require the form-encoded payload to be OAuth compliant which means strings with '!' will not get encoded using normal encoding and break. This fixes it in a way that will work under all versions of node.

If you didn't use the Bell.oauth.Client API, you are not affected by this change. If you did, you need to replace calls to client.request() with the new client.resource().

Passwordless login support

It seems that this project lacks support for a passwordless login scheme. T would be helpful to know if a passwordless login scheme is within the scope of this project, and whether any considerations have been made to support this feature in the near future.

Wreck

Replace nipple with wreck

redirected url querystring in protected routes

After successfull authentication, querystring are not retained for protected routes.

Ex. For route /auth/login/twitter protected with twitter auth strategy in required mode
URL /auth/login/twitter?next=%2F/home redirects to /auth/login/twitter after authenticated successfully. Should it retain query params in redirected url after authenticated?
Is this valid behavior? If not, how we achieve it by using temporary state between the authorization flow?

How to implement redirectUrl after authentication?

I'm actually using Bell and hapi-auth-cookie and I'm not sure which (or both) plugins would need to be involved since I don't quite understand yet how they interact, but I need to be able to send someone to a route to initiate auth and after they're successfully authenticated, redirect them to that URL.

It seems like this is a standard part of the OAUTH process, or at least once was, but I'm wondering if these plugins use that functionality and thus need to provide it themselves to effectively bring it back.

I'm trying to build a plugin to ease the use of bell and hapi-auth-cookie hapi-bell-cookie-auth-plugin, but just today I found another doing something similar https://github.com/hofan41/clapper and even more nicely written (though mine is very fresh in my defense).

I'm going to post this in hapi-auth-cookie also and will close on either side if/when it's clear that it's a one-sided issue.

For additional clarification, the key point there was, "I need to be able to send someone to a route to initiate auth and after they're successfully authenticated, redirect them to that URL."

  • User navigates to /auth/twitter?ReturnUrl=/foobar (no session yet exists so I can't persist the ReturnUrl value for the final redirect).
  • User is sent to twitter auth and redirected to my app
  • My app confirms and sets up a session then redirects the user (here I'd like to redirect using ReturnUrl)

Right now, I can control the final redirect, but if I put an auth strategy (using Bell) on a route, I cannot find any way to capture the ReturnUrl, then persist it in a way that can be retrieved (unique that that logical session) later.

Get session_handle from Yahoo

After logging in with Yahoo, bell exposes the access token and token secret passed from Yahoo. This access token expires after 60 min. In order to easily refresh this token, a session_handle is needed, which Yahoo provides upon original login. Without this session_handle a user is required to re-login every 60 min in order to get a new access token.

It would be great it bell could retrieve the session_handle upon login, as it does the access token and token secret.

Yahoo documentation here: https://developer.yahoo.com/oauth/guide/oauth-refreshaccesstoken.html

Modularize this

Feels that providers should be separate modules. What do you think?

5.0.0 google.js example fails

With the following error -

"Authentication failed due to: Failed obtaining google user profile"

Can anyone verify the google.js example is working ? Am I doing something wrong ?

-Drew

Allow environment variables to configure scheme options

Currently, it is not possible to configure some of the options in this plugin using environment variables, since some of the options are assumed to be boolean/number types, while environment variables are strings.

I would like to request that this be made possible by using Joi's nifty validation() function which will accept a boolean/number string and return a transformed object with the appropriate types.

Pull request incoming.

Cannot use bell with Facebook

Hi all,

I cannot find a way to make bell usable with Facebook. Here is my server config:

server.register(Bell, function (err) {
   server.auth.strategy('facebook', 'bell', {
        provider: 'facebook',
        password: 'password',
        isSecure: false,
        // Make sure to set a "Callback URL" and
        // check the "Allow this application to be used to Sign in with Twitter"
        // on the "Settings" tab in your Twitter application
        clientId: 'myClientID',                                 // Set client id
        clientSecret: 'myClientSecret'            // Set client secret
    });
    server.route({
        method: '*',
        path: '/bell/facebook',
        config: {
            auth: {
                strategy: 'facebook',
                mode: 'try'
            },
            handler: function (request, reply) {
                if (!request.auth.isAuthenticated) {
                    return reply('Authentication failed due to: ' + request.auth.error.message);
                } else {
                reply('<pre>' + JSON.stringify(request.auth.credentials, null, 4) + '</pre>');
               }
            }
        }
    });
});

However i obtain always an Authentication failed due to: Failed obtaining facebook access token

I double checked my Facebook app developer page and on the basic settings I've configured a WebSite that point to http://thalion.local:3000/bell/facebook/ that's my server route for bell authenticatin

Also, on Advanced Settings I've included Valid OAuth Redirect URI to point to http://thalion.local:3000/bell/facebook/

I'm stucked without any idea. Any hints can be much appreciated!

Oauth with Google returns "Failed obtaining google access token"

Hi,

When the callback is called the authentication fails because the application can't obtain the google access token. I already double checked my configurations and everything seem ok.

Anyone could have some guess why this error is happening?

{
  isAuthenticated: false,
  credentials: undefined,
  artifacts: undefined,
  session: {
    set: [
      Function
    ],
    clear: [
      Function
    ]
  },
  mode: 'try',
  strategy: 'google',
  error: {
    [
      Error: Failedobtaininggoogleaccesstoken
    ]data: '{\n  "error" : "invalid_grant",\n  "error_description" : "Invalid code."\n}',
    isBoom: true,
    output: {
      statusCode: 500,
      payload: [
        Object
      ],
      headers: {
        
      }
    },
    reformat: [
      Function
    ]
  }
}

LDAP support

Once the Travelogue project was discontinued, it would be good to see the LDAP support in Bell.

LinkedIn profile fields

Hi,

Is there a way to set the fields to return from the LinkedIn API?
e.g.: https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address)

facebook expiration won't be mapped properly

Hi,

actually the expiration date of facebook access token won't be mapped properly.

You implemented a default mapping:
oauth.js - line 229: expiresIn: payload.expires_in

but the facebook payload attribute is called 'expires' only.

Cheers
Stephan

oauth with Azure

Hello,

My project is using Microsoft Azure with Active Directory.
Do you have some information about the integration of this feature with Bell Module ?

Thank you

No 'access-control-allow-origin' header is present on the requested resource.

I'm using bell at the server side while at the client side I'm using Angular. I call the /auth/facebook entrypoint at the server side by using $http but I get the error

No 'access-control-allow-origin' header is present on the requested resource.

Have you any suggestions how to use bell with angularjs frontend?

Test Cleanup

Clean up test to be in line with new standards.

bell with another strategy

I'm looking for a way to layer authentication strategies. For example I'd like someone who's authenticated with hapi-auth-basic to also connect a twitter account using bell.

Any ideas are much appreciated.

How to test

I have bell setup with hapi-auth-cookie following the structure of postmile but I don't have any idea on how to test my server. could you please write an example test here or at postmile repo.

4.0.0 Release Notes

A new OAuth 2.0 property (useParamsAuth) has been added to indicate if the client ID and client secret are sent in the Authorization header or as query parameters. The default is to use the Authorization header. The existing OAuth 2.0 providers have been updated to follow the specification.

Don't send client credentials as parameters and basic auth while retrieving token

I am using WSO2 and bell. I see that in bell in https://github.com/hapijs/bell/blob/master/lib/oauth.js#L191-L203

We send both the client_id and client_secret in the query and in the Authorization header. Looking at the source code of WSO2 it says that the standard does not allow both ways to be sent at the same time. I looked over the standard. rfc6749 especially section 2.3.1 and section 5.2 invalid_client . I do not see that listed.

WSO2 does not allow that behavior.

Either way, I think this could be exposed in another option when defining the provider (credTransport: ['basic', 'query']) with both as default to be backwards compatible? Better name? Better place to put it?

Thank You.

Auth cookies aren't being set

What's the trick to getting auth cookies to be set?

plugin.register(require('bell'), function(err) {
  plugin.auth.strategy('facebook', 'bell', {
    provider: 'facebook',
    password: '12345',
    cookie: 'auth',
    clientId: settings.get('facebook.appId'),
    clientSecret: settings.get('facebook.appSecret'),
    isSecure: false,
    isHttpOnly: true
  });
  plugin.route({
    method: ['GET', 'POST'],
    path: '/facebook',
    config: {
      auth: 'facebook',
      handler: function(request, reply) {
        var profile, provider, _ref;
        _ref = request.auth.credentials, provider = _ref.provider, profile = _ref.profile;
        return serializeUser(provider, profile).then(function(user) {
          request.user = user;
          return reply.redirect('/');
        });
      }
    }
  });
  plugin.ext('onPreAuth', function(request, next) {
    console.log('>>>>> pre', request.auth);
    return next();
  });
  return plugin.ext('onPostAuth', function(request, next) {
    console.log('>>>>> post', request.auth);
    return next();
  });
});

After initial redirect my request.auth is always at authenticated state and cookie is never set. A test reply.state('foo', 'bar') works fine and the cookie is preserved.

What am I doing wrong? I think I tried nearly everything.

facebook login internal server error

When I try to use the facebook strategy, I get the following error:

Debug: auth, unauthenticated, error, facebook
    Error: Missing facebook request token cookie
    at Object.exports.create (D:\Info\coven-sso\node_modules\bell\node_modules\b
oom\lib\index.js:21:17)
    at Object.exports.internal (D:\Info\coven-sso\node_modules\bell\node_modules
\boom\lib\index.js:262:99)
    at Object.authenticate (D:\Info\coven-sso\node_modules\bell\lib\oauth.js:177
:31)
    at D:\Info\coven-sso\node_modules\hapi\lib\auth.js:227:30
    at internals.Protect.run (D:\Info\coven-sso\node_modules\hapi\lib\protect.js
:56:5)
    at authenticate (D:\Info\coven-sso\node_modules\hapi\lib\auth.js:218:26)
    at internals.Auth._authenticate (D:\Info\coven-sso\node_modules\hapi\lib\aut
h.js:348:5)
    at internals.Auth.authenticate (D:\Info\coven-sso\node_modules\hapi\lib\auth
.js:177:17)
    at D:\Info\coven-sso\node_modules\hapi\lib\request.js:370:13
    at iterate (D:\Info\coven-sso\node_modules\hapi\node_modules\items\lib\index
.js:35:13)
Debug: internal, error
    Error: Missing facebook request token cookie
    at Object.exports.create (D:\Info\coven-sso\node_modules\bell\node_modules\b
oom\lib\index.js:21:17)
    at Object.exports.internal (D:\Info\coven-sso\node_modules\bell\node_modules
\boom\lib\index.js:262:99)
    at Object.authenticate (D:\Info\coven-sso\node_modules\bell\lib\oauth.js:177
:31)
    at D:\Info\coven-sso\node_modules\hapi\lib\auth.js:227:30
    at internals.Protect.run (D:\Info\coven-sso\node_modules\hapi\lib\protect.js
:56:5)
    at authenticate (D:\Info\coven-sso\node_modules\hapi\lib\auth.js:218:26)
    at internals.Auth._authenticate (D:\Info\coven-sso\node_modules\hapi\lib\aut
h.js:348:5)
    at internals.Auth.authenticate (D:\Info\coven-sso\node_modules\hapi\lib\auth
.js:177:17)
    at D:\Info\coven-sso\node_modules\hapi\lib\request.js:370:13
    at iterate (D:\Info\coven-sso\node_modules\hapi\node_modules\items\lib\index
.js:35:13)

Here's my code (basicly your twitter example)

var Hapi = require('hapi');

var server = new Hapi.Server({ debug: { request: ['error'] } });
server.connection({ port: 3000 });

server.register(require('bell'), function (err) {

    server.auth.strategy('facebook', 'bell', {
        provider: 'facebook',
        password: 'test',
        clientId: '',
        clientSecret: '',
        isSecure: false
    });

    server.route({
        method: ['GET', 'POST'],
        path: '/login',
        config: {
            auth: 'facebook',
            handler: function (request, reply) {

                if (!request.auth.isAuthenticated) {
                    return reply('Authentication failed due to: ' + request.auth.error.message);
                }

                return reply.redirect('/home');
            }
        }
    });

    server.route({
        method: ['GET'],
        path: '/home',
        config: {
            handler: function (request, reply) {
                console.log(request.auth.credentials);
                return reply(JSON.stringify(request.auth.credentials));
            }
        }
    });

    server.start(function () {
        console.log('Server running at:', server.info.uri);
    });
});

client_secret and clientSecret

So, it looks like clientSecret was changed to client_secret here:

96ef98c#diff-84fad1d3b3913ec86805e857580c5d54R199

and that breaks my code since when I try to set client_secret I get:

child "clientSecret" fails because ["clientSecret" is required] {"name":"ValidationError","details":[{"message":"\"clientSecret\" is required","path":"clientSecret","type":"any.required","context":{"key":"clientSecret"}}],"_object":{"ttl":31536000000,"domain":".gethuman.com","isSecure":false,"password":"MIICXgIBAAKBgQC4xBeP3h36ikta","cookie":"bell-facebook","clientId":"523625311006913","client_secret":"e8f655bd2b7ebecf977c274cd0c915dc","provider":{"useParamsAuth":true,"protocol":"oauth2","auth":"https://www.facebook.com/v2.3/dialog/oauth","token":"https://graph.facebook.com/v2.3/oauth/access_token","scope":["email"]},"name":"custom"}}

but then if I set clientSecret as I have been doing, I get:

Error validating client secret.

In debugging my Bell I can see that this is because client_secret is null here:

https://github.com/hapijs/bell/blob/master/lib/oauth.js#L199

I don't mind submitting a pull request to fix this but I noticed that clientSecret is actually used in other places of the code so perhaps there is something I am missing. If it is OK with you I would very simply submit a pull request to do:

query.client_secret = settings.client_secret || settings.clientSecret;

Api Authentication with Bell

Hi,

I am not sure if this is either totally obvious or not supported, but I want to use bell with a frontend and as an API authentication method.

The procedure would look like that the user is signed in at the frontend and then only sends his own access_token to the backend (e.g. from facebook). The backend then authenticates (with Bell) that access token and would then return its own token from its own authentication strategy.

So I only need bell as a authentication strategy that is taking an access_token from the request and authenticates it against my third party provider (facebook) and also gives me the user information and then I can do in my actual route handler whatever I want.

This seems to be the main purpose, but I could not find documentation about the configuration for this approach. Since most of the use cases seem to be browser based and work with redirect urls.

I have also tried to send send the authentication data to my endpoint via:

        server.inject({
            method: 'POST',
            url: '/auth/facebook',
            payload: {
                access_token: 'MY_TOKEN'
            }

But then I only get a 302 response.

So how would I approach just authenticating a provided access_token with the third party?

How to handle the authorize rejection from Twitter?

I asked this at Stackoverflow

I access the /login route and I get redirected to Twitter, I authorize the app and then I'm redirected back to /login?oauth_token=xxxxxxx&oauth_verifier=xxxxxxx where I can have access to the user profile in the request.auth.credentials.

The problem came when I tried to reject the app. At Twitter, Instead of clicking the "Sign In" button, I clicked the "Cancel" button and then the "Return to site name" button. This last button redirects me to /login?denied=xxxxxx and then I'm redirected (again) to Twitter to approve the app.

I tried to handle this scenario using the example given in https://github.com/hapijs/bell#handling-errors but can't get it to work.

server.route({
    method: ['GET', 'POST'],
    path: '/login',
    config: {
        auth: {
            strategy: 'twitter',
            mode: 'try'
        },
        handler: function (request, reply) {

            if (!request.auth.isAuthenticated) {
                return reply('Authentication failed due to: ' + request.auth.error.message);
            }

            return reply.redirect('/home');
        }
    }
});

It seems that before checking the request.auth it interprets the /login route and redirects to Twitter. I still don't understand very well the Bell module but it might be that the Twitter strategy is expecting the oauth_token and oauth_verifier in the request.params, but the denied param is not interpreted by the strategy and that's why the redirect happens.

How to handle this scenario?

Forcing redirect_uri to be https

Just wondering if it's possible to force to redirect_uri to be https. We're deploying hapi on Heroku and heroku does SSL termination at the edge of their network. This means we run hapi as http. Bell seems to take the protocol the site is running as and make that the protocol for the redirect_uri - this causes an issue when the provider (e.g. facebook) redirect back to our site as it comes back as http instead of https.

I couldn't see in the options a way to tell bell to use https for the redirect_uri protocol. Just wondering if there is a work around for the moment.

Provider wiki

It would be useful if there were a wiki that provided reference material associated with the various providers. It can be somewhat difficult to track down the documentation about endpoints, scopes, response bodies, etc.. This information has to be researched when creating a provider for the first time, so it couldn't hurt if it was recorded at that time. This should help in the long run in maintaining the code when the provider updates there service. Here is a sample associated with the Google provider:

Endpoints:
Goggle discovery doc for the plus service:
https://www.googleapis.com/discovery/v1/apis/plus/v1/rest

Auth and Token Details:
Auth and Token based on values found in the OpenIDConnect discovery document:
https://accounts.google.com/.well-known/openid-configuration

Scopes:
Scope discussion can be found here:
https://developers.google.com/+/web/api/rest/oauth#plus.login

Response body:
Documentation of response body:
https://developers.google.com/+/web/api/rest/latest/people#resource

Bell setup question

Is it possible to load Bell plugin this way?

server.register([
    {
      register: require('bell'),
      options: {
        provider: 'google',
        password: 'password',
        isSecure: false,
        // You'll need to go to https://console.developers.google.com and set up an application to get started
        // Once you create your app, fill out "APIs & auth >> Consent screen" and make sure to set the email field
        // Next, go to "APIs & auth >> Credentials and Create new Client ID
        // Select "web application" and set "AUTHORIZED JAVASCRIPT ORIGINS" and "AUTHORIZED REDIRECT URIS"
        // This will net you the clientId and the clientSecret needed.
        // Also be sure to pass the redirect_uri as well. It must be in the list of "AUTHORIZED REDIRECT URIS"
        clientId: '',
        clientSecret: '',
        providerParams: {
          redirect_uri: server.info.uri + '/auth'
        }
      }
    },
    {
      register: require("hapi-route-auto-reg"),
      options: {
        directory:  __dirname + '/routes'
      }
    }
  ], function (err) {
    if (err) throw err;

    server.route({
      method: '*',
      path: '/auth',
      config: {
        auth: 'google',
        handler: function (request, reply) {
          reply('<pre>' + JSON.stringify(request.auth, null, 4) + '</pre>');
        }
      }
    });
  }
);

Facebook provider is throwing an error

I'm getting this

{"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"}

when being redirected from facebook back to http://localhost:8080/auth/facebook?code=AQBfow3ErUA7-TB7N...

no stack trace in the console :( will try to investigate tomorrow...

here's my setup

register = (plugin, options, next) ->
  plugin.register require('bell'), (err) ->
    plugin.auth.strategy 'facebook', 'bell',
      provider: 'facebook'
      password: '12345'
      clientId: settings.get 'facebook.appId'
      clientSecret: settings.get 'facebook.appSecret'

    plugin.route
      method: ['GET', 'POST']
      path: '/facebook'
      config:
        auth: 'facebook'
        handler: (request, reply) ->
          console.log request
          # // Perform any account lookup or registration, setup local session,
          # // and redirect to the application. The third-party credentials are
          # // stored in request.auth.credentials. Any query parameters from
          # // the initial request are passed back via request.auth.credentials.query.
          reply.redirect '/admin'

    next()

Multiple auth strategies not possible?

I am using hapijs 7.5.3 with bell 1.3.1.

I'd like to register multiple auth strategies with one provider (i.e. facebook) like this:

    plugin.auth.strategy('facebookHost', 'bell', 'try', {
      provider: 'facebook',
      clientId: options.facebook.clientId,
      clientSecret: options.facebook.clientSecret,
      password: options.cookie.password,
      isSecure: options.cookie.isSecure,
      scope: ['email', 'manage_pages', 'create_event', 'publish_stream', 'user_likes', 'user_events', 'rsvp_event', 'user_friends'],
      providerParams: {
        display: 'touch'
      }
    });

    plugin.auth.strategy('facebookLogin', 'bell', 'try', {
      provider: 'facebook',
      clientId: options.facebook.clientId,
      clientSecret: options.facebook.clientSecret,
      password: options.cookie.password,
      isSecure: options.cookie.isSecure,
      scope: ['email', 'user_likes', 'user_events', 'rsvp_event', 'user_friends'],
      providerParams: {
        display: 'popup'
      }
    });

I get the error Error: State already defined: bell-facebook.

Are multiple auth strategies not possible or am I doing something stupid?

Question about reply.redirect call at oauth.js

Hi!

I would like to question about this redirection here

When this redirection is done, the client gets notified of two parameters: code and state. However, these parameters should concern just the server, right? Does the client need to know any of these information?

Do my questions make any sense? Could it be a vulnerability?

For example, according to the facebook documentation, I can exchange code for an access token.

First. I would like know if I really should worry about the fact of the client knowing about the code and state parameters.

Second. How could we avoid this redirection in order not to get the user notified about information that should concern just the server?

Finally. Thank you so much for building hapi.js and bell :)

5.0.0 Release Notes

Google Auth Changes

Google now uses the Google Plus services. More information on the service is located here: https://www.googleapis.com/discovery/v1/apis/plus/v1/rest You will need to update the

The profile object has changed in the following ways:

  • email is now emails and is an array of objects with the following keys: type and value
  • name renamed first and last to givenName and familyName respectively

Linkedin Auth Changes

The scope changed so that r_fullprofile and r_contactinfo are removed and r_basicprofile is added instead. This fixes a bug where the contact information wasn't being retrieved. This should only impact your service if you depended on one of the other scopes.

SAML with Shibboleth support

It seems this was supported in travelogue with passport. I still don't know why travelogue was abandoned in favor of bell but it kind of leaves new projects in no mans land that that need SAML support.

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.