nodejs intro + obfuscation + async

Costas

Administrator
Staff member
ECMAScript modules (in short ES modules [2])

CommonJS is the default Standard for module inclusion. By NodeJS v8.5 provides support for ES Modules.

In order to use ES Modules, you need to add the following to your package.json at the top level:
JavaScript:
//https://stackoverflow.com/a/62488998
{
    "type": "module"
}

Mahdhi Rezvi -Understanding ES Modules in Javascript

CommonJS vs ES Modules in NodeJS

2021 - Reich - From CommonJS to ES Modules
2019 - Arora - Understanding Promises in JavaScript
**2018 - Arora - Understanding Design Patterns in JavaScript
2018 - Arora - Understanding Higher-Order Functions in JavaScript
2018 - Arora - Understanding Asynchronous JavaScript

https://npmjs.com
(lightweight) https://npm.io/

Valley of code - Node.js Handbook (PDF)

NodeJS Fiddle



Jack Halon - Introduction to V8 and JavaScript Internals (mirror)


bytenode
https://www.npmjs.com/package/bytenode
https://github.com/bytenode/bytenode

2021 - Abbas - How to Compile Node.js Code Using Bytenode
2019 - Abbas - How to Compile Node.js Code Using Bytenode

https://github.com/herberttn/bytenode-webpack-plugin

^inspired by
https://gitlab.com/shardus/bytenode-webpack-plugin
https://www.npmjs.com/package/bytenode-webpack-plugin

alternative -nwjs

Obfuscating JavaScript code
https://github.com/javascript-obfuscator/javascript-obfuscator
https://obfuscator.io/

https://stackoverflow.com/a/58360440
https://dev.to/anthonys1760/obfuscating-javascript-code-with-nodejs-233

nexe (package node and your script)
nexe - create a single executable out of your node.js apps
nexe extractor - nexeruncator

Package your NodeJS project into an executable with pkg
 

Costas

Administrator
Staff member
testing nodeJS v19 includes experimental fetch api we using process.removeAllListeners('warning') to suppress the warnings on nodeJS...

on localhost php is running having one file
response2.php = sleep(2); echo 'response with sleep 2 seconds';

on nodeJS package.json enable the ES module by adding
"type": "module"

fetch always returns a Promise

JavaScript:
log('start');

let resp = GetMeSomeData();

log(resp);

log('end');

function GetMeSomeData() {
  return fetch('http://localhost/response2.php').then((response) => {
      if ( !response.ok )
              return null;
          else
              return response.text();
  });
}

function log(message){
  console.log( (new Date()).toISOString().substring(0, 19).replace('T', ' ') + ' >> ' + message);
}

/*
2022-10-30 16:00:43 >> start
2022-10-30 16:00:43 >> [object Promise] Promise { <pending> }
2022-10-30 16:00:43 >> end
*/

adding await on function call, working as expected
JavaScript:
log('start');

let resp = await GetMeSomeData();

log(resp);

log('end');

function GetMeSomeData() {
  return fetch('http://localhost/response2.php').then((response) => {
      if ( !response.ok )
              return null;
          else
              return response.text();
  });
}

function log(message){
  console.log( (new Date()).toISOString().substring(0, 19).replace('T', ' ') + ' >> ' + message);
}

/*
2022-10-30 16:01:08 >> start
2022-10-30 16:01:10 >> response with sleep 2 seconds
2022-10-30 16:01:10 >> end
*/

return from variable
JavaScript:
log('start');

let resp = await GetMeSomeData();

log(resp);

log('end');

function GetMeSomeData() {
  let p = fetch('http://localhost/response2.php').then((response) => {
    if ( !response.ok )
      return null;
    else
      return response.text();
  });

  log('bump');
  return (p);
}
function log(message){
  console.log( (new Date()).toISOString().substring(0, 19).replace('T', ' ') + ' >> ' + message);
}

/*
2022-10-30 16:02:27 >> start
2022-10-30 16:02:27 >> bump
2022-10-30 16:02:29 >> response with sleep 2 seconds
2022-10-30 16:02:29 >> end
*/

adding async & await at fetch, working as expected
JavaScript:
log('start');

let resp = await GetMeSomeData();

log(resp);

log('end');

async function GetMeSomeData() {
  let p = await fetch('http://localhost/response2.php').then((response) => {
    if ( !response.ok )
      return null;
    else
      return response.text();
  });

  log('bump');

  return (p);
}

function log(message){
  console.log( (new Date()).toISOString().substring(0, 19).replace('T', ' ') + ' >> ' + message);
}

/*
2022-10-30 16:03:03 >> start
2022-10-30 16:03:06 >> bump
2022-10-30 16:03:06 >> response with sleep 2 seconds
2022-10-30 16:03:06 >> end
*/

same logic applied to HTML with plain JS, on the following example we can see that JS onclick calls an async function
JavaScript:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>DOMContentLoaded , load</title>
</head>

<body>

    <a href="#" onclick='testMethod();'>TEST</a>
    <div id='someContainer'></div>

    <script>

        async function testMethod() {
            log("TEST started");
            const someContainer = document.getElementById('someContainer');
            let h = await testGetMeSomeData();
            log(h);
            someContainer.innerHTML = h;
            log("TEST completed");
        }

        function testGetMeSomeData() {
            return fetch('http://localhost/response2.php').then((response) => {
                if (!response.ok) //200-299 https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
                    return null;
                else
                    return response.text();
            });
        }

        function getMeSomeData() {
            return fetch('http://localhost/response2.php').then((response) => {
                if (response.status != 200)
                    return null;

                return response.text();
            });
        }

        //fired when the DOM is ready, resources not loaded images/css etc.
        document.addEventListener('DOMContentLoaded', async function () {
            log('DOMContentLoaded OK')

            const someContainer = document.getElementById('someContainer');
            let markup = null;

            try {
                markup = await getMeSomeData();
            } catch (e) {
                log(e);
                markup = 'Something bad happened :(';
            }

            log('bump');
            log(markup);
            someContainer.innerHTML = markup;
        });

        //page fully loaded - ' () => ' is just /anonymous arrow/ function equivalent to ' function() { '

        window.addEventListener('load', () => {
            log('window load OK')
        })

        //which can be written also as
        // window.onload = async function() {
        //     log('window load OK')
        //     await testMethod();
        // };

        function log(message) {
            console.log((new Date()).toISOString().substring(0, 19).replace('T', ' ') + ' >> ' + message);
        }
    </script>

</body></html>
/*
2022-10-30 16:05:18 >> DOMContentLoaded OK
2022-10-30 16:05:18 >> window load OK
2022-10-30 16:05:20 >> bump
2022-10-30 16:05:20 >> response with sleep 2 seconds
2022-10-30 16:05:25 >> [user click the anchor link] TEST started
2022-10-30 16:05:27 >> response with sleep 2 seconds
2022-10-30 16:05:27 >> TEST completed
*/

references :
webrtc-local-ip-leak - https://github.com/niespodd/webrtc-local-ip-leak/blob/master/main.js
await"able DOM event handlers - https://gist.github.com/nickytonline/069fc006d1946279a31fed10a61d08c5
fetch() cheatsheet - https://devhints.io/js-fetch
 
Top