Giter Club home page Giter Club logo

adyen-cse-web's People

Stargazers

 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

adyen-cse-web's Issues

cvcIgnoreBins doesn't remove disabled unless you fire the CVC eventHandler

Hey,

I want to use options.cvcIgnoreBins = '6703'; to Ignore CVC for BCMC but this options won't remove the disabled state form the submit button unless you click on the cvc field to fire the event handler.

Do you know why here we only update the validity of field who fired the event handler?

We could update cse.validity with the result of validate(), like this ignored fields would also get updated.

cse.validity = cse.encryption.validate(validationData);

if ( validationResult[field] ) {
    removeClass( node, 'invalid-' + field );
    addClass( node, 'valid-' + field );
} else {
    if (!isInitializing || val !== '') {
        addClass( node, 'invalid-' + field );
    }
    removeClass( node, 'valid-' + field );
}

What do you think? Should I create a PR with this change ?
Alex

Add possibility to invalidate form in `onvalidate` hook

We have an adyen form that contains a confirmation checkbox (Terms) at the end and I want to be able to enable submit button only when this checkbox is checked.
If I could invalidate form in onvalidate hook that would be great.
I suggest that in the callback it could be done by simply returning false if one wants the form to be invalidated.

Typo causing google closure compiler to fail

The following line in adyen.encrypt.js seems to contain a typo. It (probably unintentionally) uses the bitwise OR operator here on line 1131:

handlers.cvcHandler({target:elementsByName.cvc, originalEvent: ev, type : (ev|{}).type, isInitializing : (ev||{}).isInitializing})

(ev|{}).type should be (ev||{}).type - just like the other occurrence a couple characters to the right.

It doesn't produce errors during runtime, but the result of (ev|{}).type will always be undefined, not matter the value of ev.

Passing 2 digits year should be valid

Hello

Most of the credit card in France displays 2 digits for the expiration year. (18 for 2018)

That's why my form allows to enter 2-digits year instead of 4-digits.

However, passing 2 digits year to the validate function seems to be invalid.

I expect a 2 digits year to passed as well as a 4 digits year.

What's your thoughts ?

Best regards

adyen.cardtype.determine returns "mc" when card number is undefined or ""

Hello

In the file addOns.adyen.cardType.js line 61

Cards.determine("") and Cards.determine(undefined) returns "mc".

I think this is not the expected behavior, right ?

If I'm wrong, please explain me why ?

I use this method to detect the cardType and show an icon in the input field depending on the credit card number

capture d ecran 2017-12-11 a 10 29 46

Best regards

Confirm support for browser, add it to documentation.

I'd like to get a confirmation of supported browsers. IE10 gives an error.

There was an error collecting entropy from the browser: 
Error: secure random number generation not supported by this browser
use chrome, FireFox or Internet Explorer 11 

So, it's official that Adyen CSE won't work in IE10 and below?
We could maybe add this info to the docs maybe?

window is not defined (adyen.encrypt.nodom.js:130)

Node.js / NPM error

npm i git://github.com:Adyen/adyen-cse-web.git --save

All I'm doing here is requiring the package, and it throws.

/Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:130
    (function(){try{var b=[new Uint8Array(1),new Uint32Array(1),new Int32Array(1)];return}catch(g){}function f(e,a){return this.slice(e,a)}function c(j,e){if(arguments.length<2){e=0}for(var a=0,h=j.length;a<h;++a,++e){this[e]=j[a]&255}}function d(e){var a;if(typeof e==="number"){a=new Array(e);for(var h=0;h<e;++h){a[h]=0}}else{a=e.slice(0)}a.subarray=f;a.buffer=a;a.byteLength=a.length;a.set=c;if(typeof e==="object"&&e.buffer){a.buffer=e.buffer}return a}try{window.Uint8Array=d}catch(g){}try{window.Uint32Array=d}catch(g){}try{window.Int32Array=d}catch(g){}})();(function(){if("btoa" in window){return}var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";window.btoa=function(g){var e="";var f,d;for(f=0,d=g.length;f<d;f+=3){var k=g.charCodeAt(f)&255;var j=g.charCodeAt(f+1)&255;var h=g.charCodeAt(f+2)&255;var c=k>>2,b=((k&3)<<4)|(j>>4);var m=f+1<d?((j&15)<<2)|(h>>6):64;var l=f+2<d?(h&6

ReferenceError: window is not defined
    at /Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:130:591
    at /Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:130:981
    at Object.<anonymous> (/Users/thomasreggi/Desktop/project/node_modules/adyen-cse-web/js/adyen.encrypt.nodom.js:568:4)
    at Module._compile (module.js:541:32)
    at Module._extensions..js (module.js:550:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/thomasreggi/.nvm/versions/node/v6.2.2/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:166:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)

Why i get 'false' used in React Native?

source code:
import adyenEncrypt from 'adyen-cse-web';
......
const cseInstance = adyenEncrypt.createEncryption(PUBLIC_KEY_DEV, options);
postData['adyen-encrypted-data'] = cseInstance.encrypt(cardData);

result:
Object {adyen-encrypted-data: false}

Webpack loading & roboto font

Hello,

Can I require adyen-cse-js and take only the javascript sdk ? Currently, I do something like that :

const adyen = require('adyen-cse-js');
const encryptor = adyen.createEncryption(publicEncryptionKey);
const cseToken = encryptor.encrypt(Object.assign({ generationtime }, card));

Then, my website is loading Roboto font, from your javascript :(
I'm using VueJs with Nuxt, in the same way, when server side rendering append, adyen try to find navigator var, but it's not available. Why this variable is needed ? Maybe the same reason than css is loading :/

Thanks,
Gaël

Why RSA+AES

Sorry for my ignorance, but is there any reason for doing RSA+AES here, instead of pure RSA, given the message size will usually be much smaller than 245 chars? Is this for future proofing, or is it in any way more secure than just doing RSA?
Thanks!

Validation hooks / events

We'd like to enable / disable some buttons right after the CSE library validated the creditcard is correct.

Can you provide some documentation about how to do this? Are there any hooks or events we are able to capture? Can we add a closure to the options array for this?

ES6 modules + Babel

Do you guys have a plan to create an ES6 module of this library?.
In our case, we use Webpack + Babel for compile those modules to ES5.

Unable to get property 'x' of undefined or null reference

In our frontend error tracking tool, we see the following error

Unable to get property 'x' of undefined or null reference

with the minimal stacktrace of

at ? line 14, column 29192 (https://checkout.spreadshirt.fr/Public/Checkout2/build/2.38.7/checkout/lib/adyen.encrypt.nodom.min.js:14)

which drills down to the code block

t.accelerationIncludingGravity.x

Additional data:

  • IE: 89% effected
  • Edge: 11% effeced

Unable to validate when "generationtime" given

In adyen.encrypt.nodom.js#L517 you should also allow to pass "generationtime" element. Now if you pass all the arguments to validate function before encrypt function call you will get valid == false.

cseInstance.encrypt() returns false

I'm not sure why this method returns false instead of returning the encrypted data.
I checked every input field and everything seems in order but I have no clue what I'm missing.

Compiler error with .replace method

I have been trying to use this, but am getting a javascript compiler error. I am using the adyen.encrypt.nodom.js file, and am having a problem with the ".replace" on line 400 (line number includes the current comments). I get the error "val.replace is not a function".

I tried replacing val = val.replace( /\D/g, '' ); with val = ("" + val).replace( /\D/g, '' ); and doing this in one other spot, but then the end result of the encrypted data always seems to be "false". Where am I going wrong?

Fail to validate

Hi all!

I'm having this issue but no ideia why.

let cardData = {
  cvc:"737",
  expiryMonth:"08",
  expiryYear:"2018",
  generationtime:"2016-10-10T17:01:16.748Z",
  holderName:"John Smith",
  number:"5555444433331111"
};

let encryptData = cseInstance.encrypt(cardData);
console.log(cseInstance.validate());

The console log returns false but there's no clue why the validation is failing.
Is there any way to enable a verbose mode for the validator?

Thank you,
Hugo

Suggestion: Send encrypted card data requests only through CSE library

To prevent accidentally sending unencrypted card data over an insecure connection.

To verify if the card data was successfully encrypted.
And if the current page protocol is https:

if (location.protocol === 'https:') {
    // page is secure
}

A developer would provide the url of their request handler and their own additional data to the Adyen cse library, which sends the request to the merchant server.

The Adyen cse library would verify the cardData encryption and the location protocol, before sending the request to the merchant server.

var encrypted_card_data = cseInstance.encrypt(cardData);

var request = {};
// Object with data set by merchant about price, product, session etc:
request.merchantData = custom_merchant_shopper_data; 
request.encrypted_card_data = encrypted_card_data;

var server_url = '/shopperhandler';

/* location protocol ( https ) and 
card data encryption verified by Adyen before sending request.
 */
cseInstance.send_request(request,server_url);

holder name is not validated

There seems to be a bug concerning the validation of the card holder name.

In Encryption.prototype.encrypt the validationObject does not contain the holderName key.

Is that correct?

Thanks for your feedback.

Could you help me : {err: "Unknown server Error"}

I'm working with angularJS and I get an error response, can you try to help me ?

First
The form (an object vm.ayden is created then submitted to my client side controller with vm.adyenSub() ) :

            <form ng-submit="vm.adyenSub()" id="adyen-encrypted-form">
                <div class="form-group">
                    <label for="adyen-encrypted-form-number">Card Number</label>
                    <input type="text" ng-model="vm.adyen.number" class="form-control" id="adyen-encrypted-form-number" value="5555444433331111" size="20" autocomplete="off" data-encrypted-name="number">
                </div>
                <div class="form-group">
                    <label for="adyen-encrypted-form-holder-name">Card Holder Name</label>
                    <input type="text" ng-model="vm.adyen.holderName" class="form-control" id="adyen-encrypted-form-holder-name" value="John Doe" size="20" autocomplete="off" data-encrypted-name="holderName">
                </div>
                <div class="form-group">
                    <label for="adyen-encrypted-form-cvc">CVC</label>
                    <input type="text" ng-model="vm.adyen.cvc" class="form-control" id="adyen-encrypted-form-cvc" value="737" size="4" autocomplete="off" data-encrypted-name="cvc">
                </div>
                <div class="form-group col-xs-6">
                    <label for="adyen-encrypted-form-expiry-month">Expiration Month (MM)</label>
                    <input type="text" ng-model="vm.adyen.expiryMonth" class="form-control" value="06" id="adyen-encrypted-form-expiry-month" size="2"  autocomplete="off" data-encrypted-name="expiryMonth">
                </div>
                <div class="form-group col-xs-6">
                    <label for="adyen-encrypted-form-expiry-year">Expiration Year (YYYY)</label>
                    <input type="text" ng-model="vm.adyen.expiryYear" class="form-control" value="2016" id="adyen-encrypted-form-expiry-year"  size="4"  autocomplete="off" data-encrypted-name="expiryYear">
                </div>

                <input type="hidden" ng-model="vm.adyen.crypted" id="adyen-encrypted-form-expiry-generationtime" data-encrypted-name="generationtime" />
                <button type="submit" class="btn btn-default">Create payment</button>
            </form>

Second
My controller handle the data and make a POST to NodeJS, (no unencrypted data travelling to the server )

    vm.adyenSub=function(){
        var key     =   "10001|THE KEY PROVIDED BY ADYEN";
        var options = {}; // See adyen.encrypt.nodom.html for details
        var cseInstance = adyen.encrypt.createEncryption(key, options);
        function encryptMyData() {
            var postData = {};
            var cardData = {
                number :            vm.adyen.number,
                cvc :               vm.adyen.cvc,
                holderName :        vm.adyen.holderName,
                expiryMonth :       vm.adyen.expiryMonth,
                expiryYear :        vm.adyen.expiryYear,
                generationtime :    vm.dateAdyen
            };
            postData['adyen-encrypted-data'] = cseInstance.encrypt(cardData);
        return postData
        }


//Here I make the POST to nodeJS with the result of encryptMyData()

        $http.post('/companyAPI/checkout/adyen', encryptMyData(), {headers: {Authorization: 'Bearer ' + authentificationService.getToken()}}).success(function (data) {
            console.log(data);
        }).error(function (data) {
            console.log(data)
        });
    }

THIRD
I successfully send to nodeJS this payload

{ action: 'Payment.authorise',
  'paymentRequest.merchantAccount': 'Hic2hMerchant',
  'paymentRequest.amount.currency': 'EUR',
  'paymentRequest.amount.value': '199',
  'paymentRequest.reference': 'TEST-PAYMENT-2016-03-03T13:53:29+01:00',
  'paymentRequest.shopperIP': '11.111.111.111',
  'paymentRequest.shopperEmail': '[email protected]',
  'paymentRequest.shopperReference': 'test-hic2h',
  'paymentRequest.fraudOffset': '0',
  'paymentRequest.additionalData.card.encrypted.json': 'adyenjs_0_1_16$hUD6rjw3MMVpWmYs+5OQhrBIFnzaF49HKNTUxap0Q/Ita2JbfZi6tTUydP94KDhlT6hFT0Wo5DMZXbrf/eI/H79/E3ARY+vB90pSmWjjrhEDdweFWr7FS+5veBTX/XEE8FyMOBT+g7jsgCn8p+1ZUthbWsgSgH1iOWKqFs5agvkzM1HYlg9T2jV77BWB8PvMD+kLFS3iFay9UBRogaUdFFbvqJqDpbHsJRzqfyL4VGlcbNQGuoXyyPJO+wq3crRBtfnHREMzK9DhMhu7akQcPOPR41nPOAljKd9GkBafEplfH63aYPXJ31A6cOYXYBk0eyczEa/MOYBjXdUozQwJaoGA==$hR9nGIoQbm8eSQNgzPZTU15rbYgvYlkxnjVygu6WJyF7wgwvegGIqdy3/hnP03gYTOp8+NK3MfSI6fHSDDuUDGsF3HMByNXoYwpNyXcp/0yIvF/9iqGnsWZ2JfujHkvsf+NAbsxNDZyTqYVknPLomD0Lg+WkIEKkaiBYb6fzBEy8MZbCVGT4SixltwR/aZgTlBJIThIHal3HuoIiik7gBakZG5PqdVYjucuGzXht8wrz/7hEKmP4jrMR/jPahzxn0R5P0ZBvS+wD5082s5GED23TQ5cttUxW4NxnKSZB5d6EYJgbcSLBKHGPv6gFsfwvvanfFNBzTUXeY1qLXyGiJhQ8WRMReQgAYTjjlQe29cdY6P6gFt0hzfTRfDkAWXY22J5/YNQCSw==' }


then I do :

adyen.test("[email protected]", "myPassword", adyenRequestBody, function(err, response){
        res.json({err: err, response: response});
    });



And i receive this response :
{err: "Unknown server Error"}

Validation for year field

The library provides validation for year field, but it just checks that input is digits. It would be great if you add the ability to check that the card expiration year is greater than or equal to current one (e.g. now 2016 - ... are valid, but 2015 isn't).

This PR (#20) should resolve this issue.

adyen.encrypt_0_1_16.js causing forced reflows when using CreditCard input field.

As described on the original ticket in the adyen-magento github:

Magento version: 1.9.2.4
Plugin version: 2.9.0
Description
The adyen.encrypt_0_1_16.js and adyen.encrypt_0_1_18.js is causing a lot of forced reflows in our checkout. This has apparently been a issue for a long time but just recently got some attention.

The problem occurs when filling in a credit card number, after one or two digits the input field stops responding to any input for about 3 seconds. When recording the issue in the observer I see a function call in the adyen.encrypt_0_1_16.js:204 that eventually calls the getJsFonts a lot. Chrome indicates this as the most likely cause for performance issues during the recording.

Tried to update to module to 2.9.6 and switching the encrypt js file to 1.18 without any luck. Also removed our theme rewrites on the cc.phtml with still the same problem.
screen shot 2018-01-26 at 14 22 23

react implementation?

Hi,im trying to create working prototype in React however there are some issues im unable to solve. I've created java script page with HTML form and it works fine.Any help would be appreciated.

Not sure if im on the right track but I'm trying to apply encryption to the form and then execute form submit.

My form is
<form id="adyen-encrypted-form" action="https://requestb.in/1mrymb71" method="POST" ref="AdyenForm">

The onClick button event for the submit button is:

let options = {};
        // Bind encryption options to the form.
        let encrypted = window.adyen.createEncryptedForm(this.refs.AdyenForm, options);
        this.refs.AdyenForm.submit();

Im not getting any errors and im able to inspect window.adyen therefore it has been loaded successfully.

Line: his.refs.AdyenForm.submit(); submits the form as it should.Problem is that for some reason form is not bound and encrypted as it should. Inspecting object: window.adyen.encrypt.errors i can see there is a UNABLETOBIND:"CSEB01".

Wrong validation rules

Every card parameter except holder name validated with parameter allowEmpty = true passed to validations.createChangeHandler.

Previously all fields were required.

Tag v0.1.18 fails to install properly using README

Using the instructions in the README we ran into several issues getting the package to install using NPM for the v0.1.18 tag.

We eventually resolved this by using
"adyen-cse-js": "git+https://github.com/Adyen/CSE-JS.git#v0.1.18"

[Question] _csrf in form body and Adyen

Hey guys

I have an eCommerce built with NodeJS using adyen library in the client side and
after add csurf library to protect the forms
the last step in checkout(payment step) could not be completed.

my form has an input hidden like this one:

<form method="POST">
    <input type="hidden" id="_csrf" name="_csrf" value="8cvViCIw-yTDZXYgPjA11VOaFCJG6W6Z7Sjk">
....adyen stuff
</form>

i have to setup something in adyen for this form work passing _csrf in the body?

Thanks!

Node module returns sjcl lib instead of adyen

When I try to use no-dom version as a node module, I get the wrong object.

// package.json
"dependencies": {
  "adyen-cse-js": "git+https://github.com/Adyen/CSE-JS.git#v0.1.17"
}

// app.js
import adyenEncrypt from 'adyen-cse-js'
console.log(adyenEncrypt)
// → Object { cipher, hash, keyexchange, mode, misc, codec, exception, bitArray, prng, random, json, encrypt, decrypt }

Why

Every node module has a module variable as a reference to the object representing the current module.

And I figured out that this variable is used in sjcl library, and you include this library into your module without any encapsulation.

As a result, when I import your library I get sjcl library instead.

How to fix

You may want to wrap this code into closure, and pass an empty object as module variable:

(function (module) {
  // ... current sjcl code on L149
})({});

Also after defining AMD module it would be great to make it obvious what exactly do we want to export:

// L172
if (module && module.exports) {
  module.exports = encrypt;
}

require("crypto") in sjcl.js

Due to require("crypto") in sjcl.js which is included in adyen.encrypt.js files when building a bundle with webpack a whole lot of dependencies are pulled in as a result. Unknowingly people who are using webpack or a similar bundling solution might be getting a bigger bundle as a result. This is unnecessary as the code which is responsible for the require fails silently in the browser.
The relevant line in the sjcl.js repo is here https://github.com/bitwiseshiftleft/sjcl/blob/00bd42dae9ebc3a28708db2053ffa2e88f99ad1e/core/random.js#L485
screen shot 2016-12-02 at 17 03 19
Adyen is 40KB~ in size parsed which leaves around 50KB~ of unwanted dependencies that start to get bundled with require("crypto").
My short term suggestion would be to remove the require("crypto") line in the adyen.encrypt.js files.

Please rename this dependency to match its repo name?

We include this repo as a dependency in our package.json like so:

"adyen-cse-js": "git+https://github.com/Adyen/adyen-cse-web.git#v0.1.20.1",

We are on NPM 5. Very routinely, in Jenkins CI we get this error:

npm WARN checkPermissions Missing write access to 
/some/path/to/node_modules/adyen-cse-js

We have hundreds of dependencies in our package.json and we never get this error on any others. When we re-run CI, the problem usually goes away.

I'm not sure if adyen-cse-web actually has permission problems with contents. I suspect it's rather something to do with the fact that this repo's dependency name does not match is repo name. Would love to get these two consistent. Whether you choose to rename the repo or the dependency name doesn't matter to me; which ever one is easiest and most friction-free.

Thanks!

Cross Origin requests or JSONP

I've been searching the documentation but I couldn't find any information about CORS or JSONP.

Do I need to send any specific headers in my request?

The goal is to send the encrypted card details and payment from the user's browser directly to Adyen servers.

Thank you

edit : typo

card number is incorrectly valid

Hi,
validate() method is returning valid true for credit card number: 23422343423443223432 which is really not valid as it doesn't start with numbers of any provider

Method for detecting credit card type on adyen object

There is no method on the adyen object for detecting credit card type, which are needed for custom payment form integration with modern frameworks. The method that is currently present requires a DOM form which is not desirable.
Is this planned in any future release?

Wrong CVC validation for AmEx

Invalid CVC input has 'valid' class until onblur event fired on them.

Steps to reproduce:

  1. Fill 3 digits to CVC
  2. Fill valid AmEx card number (example: 3700 0000 0000 002)
    Actual result: CVC input has valid class but form can't be submited.
    Expecting result: CVC input has error class.

It would be understandable for user to see that CVC is invalid for AmEx card.
Note: fourDigitCvcForBins has default value - '34,37'

About adyen.enrypt.nodom and window object

Hello,

I'm a developer, which integrating you library with angular app.
I need to implement lazy loading of you library. As always I wrap code into anonymous function and add definition of empty object with name window, then eval this code after ajax load. But I got exception on line 153. Because of this
function a(c, d, e, b) {
// c is a window (replaced by my fake) object
// because of addEventListener is not defined it is not a function
if (typeof c.addEventListener === "function") {
c.addEventListener(d, e, b)
} else {
// also attachEvent is not defined
if (c.attachEvent) {
c.attachEvent("on" + d, e)
} else {
// there is throw exception, but encrypt is not defined yet, because it defined on line 162
throw new Error(encrypt.errors.UNABLETOBIND + ": Unable to bind " + d + "-event")
}
}
}
I don't understand, why you need to use window object in "nodom" library. May be it is not bug, but looks like. May be you have version of you library which fully nodom?

Package name

You guys have renamed your package.json name property in 5d253b7. Are you in the process of updating the github repo name also? It should match. Are you planning on publishing the library as a package on npm?

Support for device fingerprinting in JavaScript-only solution

When using adyen.nodom.js it's currently not possible to add a device fingerprint to the encrypted data object.

adyen.nodom.js doesn't include adyen-hpp.df.js, so the dfValue attribute is always set to an empty string here: https://github.com/Adyen/adyen-cse-web/blob/master/js/adyen.encrypt.nodom.js#L471 .

try {
  data.dfValue = df();
} catch (e) {          
}

Note: df() is a function returning an empty string)

It would be very useful to be able to get the fingerprint separately and pass is to the encrypt method (without it being reset to an empty string).

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.