#StackBounty: #node.js #webpack #vue.js #vuejs2 #webpack-2 how to uglify a file and save to another location (vue.js)

Bounty: 100

I am unsure on how to uglify my server.js file and save it into the dist folder under a server folder. Right now I’m just using the CopyWebpackPlugin

new CopyWebpackPlugin([
  {
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
  },
  {
    from: path.resolve(__dirname, '../src/server'),
    to: config.build.assetsServerDirectory,
    ignore: ['*.sql']
  }
]),

This works, but is just a simple copy and paste.


Get this bounty!!!

#StackBounty: #node.js #express #dynamics-crm #azure-active-directory #microsoft-dynamics Authenticating with CRM, Dynamics, Azure in E…

Bounty: 200

Been banging my head against a few walls with this so hoping some CRM/Dynamics experts can give me a hand!

I’m trying to programatically login to Dynamics CRM, using a single set of admin credentials within a Node powered Express app. The app will then serve requested CRM data back to any logged in user who has access (controlled by roles/permissions within the App), meaning an end user only has to login into the Express app.

We have an internet facing Dynamics instance, with a particular endpoint, let’s say https://my.crm.endpoint as an example. I have also registered an App in the Azure Portal and called it CRM App.

Question This registered app’s homepage is set to https://my.crm.endpoint, but is that enough to link the CRM App to our Dynamics instance?

I’ve written a script (crm.js) that successfully requests an access token for my CRM App registered in Azure Portal, using it’s App ID.

Example Token

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyIsImtpZCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyJ9.eyJhdWQiOiJkNmJmNjhhNi01ZDMwLTRjMWItYWIwYS1hMTLJHO*SUDHJSYDOUISMYDUYNSGnhjdjlkshdlnsudsmmjsdjsdksdWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzE5ZTk1OTZlLTA2ZjgtNGVkNy1hZmU3LTExYTZmMmMzMDQwYi8iLCJvaWQiOiI4Zjg5MTY0MS1lMDE0LTRkMTUtODMzYS1mMTdiNzNhOWY4N2YiLCJzdWIiOiI4Zjg5MTY0MS1lMDE0LTRkMTUtODMzYS1mMTdiNzNhOWY4N2YiLCJ0aWQiOiIxOWU5NTk2ZS0wNmY4LTRlZDctYWZlNy0xMWE2ZjJjMzA0MGIiLCJ1dGkiOiJIRkV3Z3N0ZW1VNmRSSVV0b21RbUFBIiwidmVyIjoiMS4wIn0.iQCH4SA8ZZ7uYCV7dG8xR5wK_AMk8h2uOkghr0B2k3To4ArP5R-M9KpgoL0O13IuGg6m2Yjo6vRVQJGeA2FeI4ixlkP5FStThKmCmO5CKIpm1c2CRMbMWt8dt8JRaGlZIRuARTsENWyoDE5ASrirhMTJGi1oY5Ud2ZwdtA_sdu7UTBcSoMhCrBiEi0NNRGNqGMplGvRZ6wwwISbppODbbs5Z92uvLfjyYAh-vmiNbGkiyQDJ5SpKwh3pl3Sx3L8sUVnld5CGWUtnbn4PMagkdMTxkHhBterYxSpGzYx3cj7_-UsddejsSCrYJtllyLjL6m_oeZjmHFqe_5Dzt57H1Q

Using the bearer token, I then attempt to get some contacts out of Dynamics via the the usual endpoint: https://my.crm.endpoint/api/data/v8.2/contacts?$select=fullname,contactid

This fails and I get a 401 Unauthorised error message.

Question Can anyone suggest what the problem could be? I’ve included some potentially crucial information at the bottom 🙂

NB: If I am logged in to O365 in my browser and then visit the CRM endpoint above, I see the contacts I requested so the endpoint itself does work.

crm.js

let util = require('util');
let request = require("request");

let test = {
    username: '<my.email@address.com>',
    password: '<my_password>',
    app_id: '<app_id>',
    secret: '<secret>',
    authenticate_url: 'https://login.microsoftonline.com/<tenant_id>/oauth2/token',
    crm_url: 'https://<my.crm.endpoint>'
};
function CRM() { }

CRM.prototype.authenticate = function () {
    return new Promise((resolve, reject) => {
        let options = {
            method: 'POST',
            url: test.authenticate_url,
            formData: {
                grant_type: 'client_credentials',
                client_id: test.app_id,         // application id
                client_secret: test.secret,     // secret
                username: test.username,        // on premise windows login (admin)
                password: test.password,        // password
                resource: test.app_id           // application id
            }
        };

        // ALWAYS RETURNS AN ACCESS_TOKEN
        request(options, function (error, response, body) {
            console.log('AUTHENTICATE RESPONSE', body);
            resolve(body);
        });
    })
};

CRM.prototype.getContacts = function (token) {
    return new Promise((resolve, reject) => {

        let options = {
            method: 'GET',
            url: `${test.crm_url}/api/data/v8.2/contacts?$select=fullname,contactid`,
            headers: {
                'Authorization': `Bearer ${token}`,
                'Accept': 'application/json',
                'OData-MaxVersion': 4.0,
                'OData-Version': 4.0,
                'Content-Type': 'application/json; charset=utf-8'
            }
        };

        request(options, (error, response, body) => {
            console.log('getContacts', util.inspect(error), util.inspect(body));
            resolve(body);
        });

    });
};

let API = new CRM();    // instantiate the CRM object

API.authenticate()      // call authenticate function
    .then(response => {
        if (response) {

            let json = JSON.parse(response);
            let token = json.access_token;

            console.log('TOKEN', token);

            API.getContacts('token')
            .then(contacts => {
                // DO SOMETHING WITH THE CONTACTS
                console.log('CONTACTS', contacts);
            })
        }
    });


module.exports = CRM;

Error Response

HTTP Error 401 - Unauthorized: Access is denied

ADDITIONAL INFO

Our CRM set up is an on premise server configured to be internet facing (IFD). This uses Active Directory Federation services. So we have Web Application Proxy Servers running federation services on the perimeter of the network that communicate with ADFS servers on the internal network. ADFS authenticates users connecting from outside the network (from internet) against the on prem AD. Once authenticated the proxy allows users to connect through to CRM.

Our on prem active directory is synced with Azure AD as we have a hybrid deployment. Any O365 service (exchange online, sharepoint etc) uses Azure AD in the background this is a basic requirement of O365. We synchronise the Active directory so we only have to manage users in one place. We do adds/moves/changes in the on prem AD and they automatically get synced to the Azure AD.

UPDATE

I’ve just noticed that the expires_on timestamp (returned in the response containing the token) is in UTC and our servers are on BST, leaving me to believe that maybe the token is expiring before the proceeding function can even use it.

Question Does anybody know how I would go about increasing the expiration length for testing purposes?

{“token_type”:”Bearer”,“expires_in”:”3600″,”ext_expires_in”:”0″,“expires_on”:”1523484710“,”not_before”:”1523480810″,”resource”:”resource_id”,”access_token”:”eyJ0e…”}


Get this bounty!!!

#StackBounty: #node.js #firebase #google-cloud-storage #firebase-admin Can't upload to google cloud or firebase storage bucket from…

Bounty: 100

I have been trying to upload some images to my firebase storage bucket .
I have followed this official docs :-

https://firebase.google.com/docs/storage/admin/start

and https://googlecloudplatform.github.io/google-cloud-node/#/docs/storage/latest/storage/bucket

I am able to see the files which are already present in the bucket (these files were stored there using an android app)

But I’m not able to upload local files from nodejs’s admin.storage module .

Here is the code :

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://myprojectid.firebaseio.com/" , 
  storageBucket : "myprojectid.appspot.com/"
});

bucket = admin.storage().bucket() ; 
bucket.upload('./mylocalfile.jpg' , (err , file , response)=>{
console.log(err) ; //always gives me err
console.log(file) ; //gives undefined
}) ; 

But bucket.getFiles().then(objects=>console.log(objects)) ; works perfectly and prints the files present in the root .

How to fix this ?

Here is the error it prints when console logging err :

{ ApiError: Not Found
    at Object.parseHttpRespMessage (C:UsersNateshDesktopAttentionPlease_backendfunctionsnode_modulesfirebase-adminnode_modules@google-cloudcommonsrcutil.js:156:33)
    at Object.handleResp (C:UsersNateshDesktopAttentionPlease_backendfunctionsnode_modulesfirebase-adminnode_modules@google-cloudcommonsrcutil.js:131:18)
    at C:UsersNateshDesktopAttentionPlease_backendfunctionsnode_modulesfirebase-adminnode_modules@google-cloudcommonsrcutil.js:465:12
    at Request.onResponse [as _callback] (C:UsersNateshDesktopAttentionPlease_backendfunctionsnode_modulesfirebase-adminnode_modulesretry-requestindex.js:179:7)
    at Request.self.callback (C:UsersNateshDesktopAttentionPlease_backendfunctionsnode_modulesfirebase-adminnode_modulesrequestrequest.js:186:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:191:7)
    at Request.<anonymous> (C:UsersNateshDesktopAttentionPlease_backendfunctionsnode_modulesfirebase-adminnode_modulesrequestrequest.js:1163:10)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:188:7)
  code: 404,
  errors: [],
  response:
   IncomingMessage {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: true,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        defaultEncoding: 'utf8',
        ranOut: false,
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     domain:
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        members: [] },
     _events:
      { end: [Object],
        close: [Object],
        data: [Function],
        error: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: null,
        npnProtocol: false,
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 9,
        connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'www.googleapis.com',
        _readableState: [Object],
        readable: true,
        domain: [Object],
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        destroyed: false,
        _bytesDispatched: 4047,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [Object],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: null,
        read: [Function],
        _consuming: true,
        _idleTimeout: -1,
        _idleNext: null,
        _idlePrev: null,
        _idleStart: 1307656 },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: null,
        npnProtocol: false,
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 9,
        connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'www.googleapis.com',
        _readableState: [Object],
        readable: true,
        domain: [Object],
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        destroyed: false,
        _bytesDispatched: 4047,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [Object],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: null,
        read: [Function],
        _consuming: true,
        _idleTimeout: -1,
        _idleNext: null,
        _idlePrev: null,
        _idleStart: 1307656 },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers:
      { 'x-guploader-uploadid': 'AEnB2UqADzuHb4O7UjdBAui1cDWeLNO4s0YuT2krCPoYIHaUrYPjXRH8rBU0mcSi9n7sie11PhALTN2vOKkhykW0apqTbrNB9Q',
        vary: 'Origin, X-Origin',
        'content-type': 'text/html; charset=UTF-8',
        'content-length': '9',
        date: 'Sat, 17 Mar 2018 13:24:19 GMT',
        server: 'UploadServer',
        'alt-svc': 'hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="41,39,35"' },
     rawHeaders:
      [ 'X-GUploader-UploadID',
        'AEnB2UqADzuHb4O7UjdBAui1cDWeLNO4s0YuT2krCPoYIHaUrYPjXRH8rBU0mcSi9n7sie11PhALTN2vOKkhykW0apqTbrNB9Q',
        'Vary',
        'Origin',
        'Vary',
        'X-Origin',
        'Content-Type',
        'text/html; charset=UTF-8',
        'Content-Length',
        '9',
        'Date',
        'Sat, 17 Mar 2018 13:24:19 GMT',
        'Server',
        'UploadServer',
        'Alt-Svc',
        'hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="41,39,35"' ],
     trailers: {},
     rawTrailers: [],
     upgrade: false,
     url: '',
     method: null,
     statusCode: 404,
     statusMessage: 'Not Found',
     client:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: null,
        npnProtocol: false,
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 9,
        connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'www.googleapis.com',
        _readableState: [Object],
        readable: true,
        domain: [Object],
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        destroyed: false,
        _bytesDispatched: 4047,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [Object],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: null,
        read: [Function],
        _consuming: true,
        _idleTimeout: -1,
        _idleNext: null,
        _idlePrev: null,
        _idleStart: 1307656 },
     _consuming: true,
     _dumped: false,
     req:
      ClientRequest {
        domain: [Object],
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: false,
        upgrading: false,
        chunkedEncoding: true,
        shouldKeepAlive: true,
        useChunkedEncodingByDefault: true,
        sendDate: false,
        _removedHeader: [Object],
        _contentLength: null,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Object],
        connection: [Object],
        _header: 'POST /upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile HTTP/1.1rnUser-Agent: gcloud-node-storage/1.4.0rnx-goog-api-client: gl-node/6.11.5 gccl/1.4.0rnAuthorization: Bearer ya29.c.<PLACEHOLDER_FOR_SOME_LONG_AUTH_ID>rnhost: www.googleapis.comrnaccept-encoding: gzip, deflaterntransfer-encoding: chunkedrncontent-type: multipart/related; boundary=6e012a90-2cb1-4c46-9de5-bb75cb5949earnConnection: keep-alivernrn',
        _headers: [Object],
        _headerNames: [Object],
        _onPendingData: null,
        agent: [Object],
        socketPath: undefined,
        timeout: undefined,
        method: 'POST',
        path: '/upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile',
        _ended: true,
        parser: null,
        timeoutCb: null,
        res: [Circular] },
     request:
      Request {
        domain: [Object],
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        timeout: 60000,
        gzip: true,
        forever: true,
        pool: [Object],
        method: 'POST',
        uri: [Object],
        headers: [Object],
        callback: [Function],
        readable: true,
        writable: true,
        explicitMethod: true,
        _qs: [Object],
        _auth: [Object],
        _oauth: [Object],
        _multipart: [Object],
        _redirect: [Object],
        _tunnel: [Object],
        setHeader: [Function],
        hasHeader: [Function],
        getHeader: [Function],
        removeHeader: [Function],
        localAddress: undefined,
        dests: [],
        __isRequestRequest: true,
        _callback: [Function: onResponse],
        proxy: null,
        tunnel: true,
        setHost: true,
        originalCookieHeader: undefined,
        _disableCookies: true,
        _jar: undefined,
        port: 443,
        host: 'www.googleapis.com',
        url: [Object],
        path: '/upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile',
        httpModule: [Object],
        agentClass: [Object],
        agentOptions: [Object],
        agent: [Object],
        src: [Object],
        _started: true,
        href: 'https://www.googleapis.com/upload/storage/v1/b/myprojectid.appspot.com//o?uploadType=multipart&name=profile',
        req: [Object],
        ntick: true,
        response: [Circular],
        originalHost: 'www.googleapis.com',
        originalHostHeaderName: 'host',
        responseContent: [Circular],
        _destdata: true,
        _ended: true,
        _callbackCalled: true },
     toJSON: [Function: responseToJSON],
     caseless: Caseless { dict: [Object] },
     read: [Function],
     body: 'Not Found' },
  message: 'Not Found' }


Get this bounty!!!

#StackBounty: #javascript #node.js #selenium How can I build simple UI screen for end user for automation in Node Js

Bounty: 100

I am using Selenium webdriver, Javascript and Node JS to automate test cases. I have just wrote basic test case like :

var webdriver = require('selenium-webdriver');

var driver = new webdriver.Builder().
   withCapabilities(webdriver.Capabilities.chrome()).
   build();

driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('simple programmer');
driver.findElement(webdriver.By.name('btnK')).click();
driver.quit();

I can easily run above test case using command line node mytestcase.js

Now what I want it Give simple UI screen to end user where I want to put button foe ex: Automate Google search and as soon as user click on this button, test case will run automatically.

Is there any chance I can do above? I just need hint about how can I given simple UI screen to user to automate test cases by just clicking on button.


Get this bounty!!!

#StackBounty: #node.js #nginx #https #websocket Secure WebSocket Connection through nginx 1.10.3 and LetsEncrypt

Bounty: 500

Been ripping hair out because I cannot find out why I cannot connect to my WebSocket server through HTTPS.

So, I have an Express 4 server running a vue app. It uses the ws library from npm to connect to the WebSocket server. The nginx is 1.10.3. I use LetsEncrypt to secure it.

When I go online, I get (in the console):

main.js:12 WebSocket connection to ‘wss://play.mysite.com:8443/’ failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

Line 12:

window.ws = new WebSocket(${tls}://${window.location.hostname}:${port});`

That is wss://play.mysite.com:8443. It is indeed on a subdomain.

Here is my nginx block:

server {

    root /var/www/play.mysite.com/;
    index index.html;

    access_log /var/log/wss-access-ssl.log;
    error_log /var/log/wss-error-ssl.log;

    server_name play.mysite.com www.play.mysite.com;

    location / {

        proxy_pass http://localhost:4000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    listen [::]:443 ssl ipv6only=on default_server; # managed by Certbot
    listen 443 ssl default_server; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/play.mysite.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/play.mysite.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {

    if ($host = www.play.mysite.com) {
        return 301 https://$host$request_uri;
    }


    if ($host = play.mysite.com) {
        return 301 https://$host$request_uri;
    }


    listen 80;
    listen [::]:80;

    server_name play.mysite.com www.play.mysite.com;
    return 404;
}

As you see, we have the subdomain on https://play.mysite.com. My Express server always listen on port 4000 and my WebSocket server listens to wss / port 8443 on production.

When I view the /var/log/wss-error-ssl.log, I get:

2018/02/26 00:01:36 [error] 22894#22894: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 61.217.22.198, server: play.mysite.com, request: “GET /static/css/app.67b8cb3fda61e1e2deaa067e29b52040.css HTTP/1.1”, upstream: “http://[::1]:4000/static/css/app.67b8cb3fda61e1e2deaa067e29b52040.css“, host: “play.mysite.com”, referrer: “https://play.mysite.com/

So, what exactly am I doing wrong?

The proxy_pass was set right. Listening to port 8443 for WebSocket on both client/server. What is the meaning? Thank you.

edit: and yes, I know the port 8443 is running:

root@MySITE:/var/www/play.mysite.com# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 *:https                 *:*                     LISTEN
tcp        0      0 localhost:4000          *:*                     LISTEN
tcp        0      0 localhost:mysql         *:*                     LISTEN
tcp        0      0 *:http                  *:*                     LISTEN
tcp        0      0 *:ssh                   *:*                     LISTEN
tcp6       0      0 [::]:8443               [::]:*                  LISTEN
tcp6       0      0 [::]:https              [::]:*                  LISTEN
tcp6       0      0 [::]:http               [::]:*                  LISTEN
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN
udp        0      0 *:bootpc                *:*
udp        0      0 45.76.1.234.vultr.c:ntp *:*
udp        0      0 localhost:ntp           *:*
udp        0      0 *:ntp                   *:*
udp6       0      0 2001:19f0:5:2b9c:54:ntp [::]:*
udp6       0      0 fe80::5400:1ff:fe61:ntp [::]:*
udp6       0      0 localhost:ntp           [::]:*
udp6       0      0 [::]:ntp                [::]:*


Get this bounty!!!

#StackBounty: #javascript #node.js #asynchronous Reducing Repetitive Handlers in an Asynchronous Environment

Bounty: 50

I am currently working on a Node.js Socket Server for my messaging service and have been thinking about a way to re-organize my code to make it more understable, flow better, and most importantly—be manageable. In order to give an idea about what I think is wrong with the structure, I will present a trimmed version:

'use strict';

let SocketServer = require('./InitializeServer.js'); // server initialization
const MessageSender = require('./Messaging.class.js'); // import the Messanger Class
const Database = require('./SQL.js');

const conn = Database.Connection;
const SQL = Database.SQL;

/** This method is in another file and establishes a secure websocket server
 *
 *  @param {ClientObject} An object that describes everything about the client
 *  @param {ConnectionObject} An object that describes everything about the currection connection of a user, note ConnectionObject depends on ClientObject
 *  @param {req} Connection request param
 */
SocketServer.runWebSocketServer(function (ClientObject, ConnectionObject, req) {
    let poll = null;
    let _self = ClientObject.get();

    const Messanger = new MessageSender(ClientObject);
    const Chat = new SocketServer.EventDispatcher(ClientObject, ConnectionObject, {
        // these events require a "verify" key
        verify: ['status', 'actions']
    });

    // all of my handlers go here

    Chat.on('message', function (data) {
        // send out messages
    }, true);

    Chat.on('status', function (data, subtype, applyToAll) {
        // send out status messages
    }, false);

    Chat.on('typing', function (data) { 
        // "is typing" mechanism
    }, true);

    Chat.on('actions', function (action, type) {
        // set actions
    }, true);

    Chat.on('loadMore', function (start) {
        // do something here
    }, true);

    Chat.on('close', function close() {
        console.log("CLOSE CONNECTION");
    });

    // do a few more general operations below
});

Being that I am quite new to the Node.js environment, the repetitive section of the code throws up some flags. Extendability is typically hindered by such repetitive behavior. As a consideration, I could change the lines that repeat to follow a more object oriented approach*:

    Chat.on(new MessageEvent());
    Chat.on(new StatusEvent());
    Chat.on(new TypingEvent());
    Chat.on(new Actions());
    Chat.on(new LoadingEvent());
    Chat.on(new CloseEvent());

I am unsure if this would be the correct or best practice. What do you think?

*Note that the .on method does not come from any native implementation so I am very flexible


Get this bounty!!!

#StackBounty: #node.js #angular Using nbind with Angular 5 and TypeScript

Bounty: 50

I am trying to use nbind to easily create a C++ NodeJS module in an Angular website. I created a new Angular CLI project in Webstorm and followed the tutorial at https://github.com/charto/nbind. Everything builds and my lib-types.d.t file is being generated:

import { Buffer } from "nbind/dist/shim";

export class NBindBase { free?(): void }

export class Greeter extends NBindBase {
    /** static void sayHello(std::string); */
    static sayHello(p0: string): void;
}

I import the library in my AppComponent like this:

import { Component } from '@angular/core';
import * as nbind from 'nbind';
import * as LibTypes from './../lib-types';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  sayHello() {
    const lib = nbind.init<typeof LibTypes>().lib;
    lib.Greeter.sayHello('aaaaaaaaaaaaaah');
  }
}

I added a button with (click)=>”sayHello()” which should call the library. When running the application I get multiple warnings (the request of a dependency is an expression):

WARNING in ./node_modules/nbind/dist/nbind.js
128:4-32 Critical dependency: the request of a dependency is an expression
    at CommonJsRequireContextDependency.getWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibdependenciesContextDependency.js:39:18)
    at Compilation.reportDependencyErrorsAndWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:703:24)
    at Compilation.finish (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:561:9)
    at applyPluginsParallel.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompiler.js:502:17)
    at E:Projectsstreamingasdfstreamppnode_modulestapablelibTapable.js:289:11
    at _addModuleChain (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:507:11)
    at processModuleDependencies.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:477:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
 @ ./node_modules/nbind/dist/nbind.js
 @ ./src/app/app.component.ts
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://0.0.0.0:0 ./src/main.ts

WARNING in ./node_modules/nbind/dist/nbind.js
141:14-42 Critical dependency: the request of a dependency is an expression
    at CommonJsRequireContextDependency.getWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibdependenciesContextDependency.js:39:18)
    at Compilation.reportDependencyErrorsAndWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:703:24)
    at Compilation.finish (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:561:9)
    at applyPluginsParallel.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompiler.js:502:17)
    at E:Projectsstreamingasdfstreamppnode_modulestapablelibTapable.js:289:11
    at _addModuleChain (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:507:11)
    at processModuleDependencies.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:477:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
 @ ./node_modules/nbind/dist/nbind.js
 @ ./src/app/app.component.ts
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://0.0.0.0:0 ./src/main.ts

WARNING in ./node_modules/nbind/dist/nbind.js
53:28-53 Critical dependency: the request of a dependency is an expression
    at RequireResolveContextDependency.getWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibdependenciesContextDependency.js:39:18)
    at Compilation.reportDependencyErrorsAndWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:703:24)
    at Compilation.finish (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:561:9)
    at applyPluginsParallel.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompiler.js:502:17)
    at E:Projectsstreamingasdfstreamppnode_modulestapablelibTapable.js:289:11
    at _addModuleChain (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:507:11)
    at processModuleDependencies.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:477:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
 @ ./node_modules/nbind/dist/nbind.js
 @ ./src/app/app.component.ts
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://0.0.0.0:0 ./src/main.ts

WARNING in ./node_modules/nbind/dist/nbind.js
72:28-57 Critical dependency: the request of a dependency is an expression
    at RequireResolveContextDependency.getWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibdependenciesContextDependency.js:39:18)
    at Compilation.reportDependencyErrorsAndWarnings (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:703:24)
    at Compilation.finish (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:561:9)
    at applyPluginsParallel.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompiler.js:502:17)
    at E:Projectsstreamingasdfstreamppnode_modulestapablelibTapable.js:289:11
    at _addModuleChain (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:507:11)
    at processModuleDependencies.err (E:Projectsstreamingasdfstreamppnode_moduleswebpacklibCompilation.js:477:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
 @ ./node_modules/nbind/dist/nbind.js
 @ ./src/app/app.component.ts
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://0.0.0.0:0 ./src/main.ts

Also when I click the button I get the following error:

ERROR TypeError: Arguments to path.resolve must be strings
    at Object.exports.resolve (index.js:71)
    at findCompiledModule (nbind.js:70)
    at find (nbind.js:93)
    at Object.init (nbind.js:104)
    at AppComponent.sayHello (app.component.ts:14)
    at Object.eval [as handleEvent] (AppComponent.html:1)
    at handleEvent (core.js:13530)
    at callWithDebugContext (core.js:15039)
    at Object.debugHandleEvent [as handleEvent] (core.js:14626)
    at dispatchEvent (core.js:9945)

Is this a bug in nbind, or am I importing my library in the wrong way?

The current code can be found at https://github.com/kayvanbree/angular-nbind-boilerplate.


Get this bounty!!!

#StackBounty: #node.js #file-system #promise #typescript #generator Generator function to enumerate files

Bounty: 50

I want to implement a function that enumerates all files in directory. I think the function should

  • Return a Promise, because underlying readdir call is prefered over readdirSync.
  • Be a generator function, because checking statSync(...).isFile() might take some time and maybe, I will need only first few files…

So my attempt

import * as fs from 'fs';
import * as path from 'path';

function enumerateFiles(dir: string): Promise<IterableIterator<string>> {
    let result = function* (files: string[]): IterableIterator<string> {
        for (let enty of files) {
            let fullpath = path.join(dir, enty);

            if (fs.statSync(fullpath).isFile())
                yield fullpath;
        }
    };

    return new Promise<IterableIterator<string>>((resolve, reject) => {
        fs.readdir(dir, (err, files) => {
            if (err)
                reject(err);
            else
                resolve(result(files));
        });
    });
}

And usage

for (let file of await enumerateFiles(String.raw`C:WindowsWebScreen`))
    console.log(file);

// C:WindowsWebScreenimg100.jpg
// C:WindowsWebScreenimg101.jpg
// ...

What do you think? I’m really not sure about combining Promises with generator functions. Especially in this order…


Get this bounty!!!

#StackBounty: #node.js #bash #heroku #imagemagick #tmp FFMPEG cannot read files in /tmp/ on Heroku

Bounty: 50

I created a nodejs application hosted on heroku which uses imagemagick. I am doing this operation:

require('child_process').exec(`convert -quiet -delay 1 output.avi ${gif}`);

This should convert output.avi (which is present) to a gif file. In this case, gif is "/app/temp/gifs/xstrycatdq.gif". This command works perfectly on my local windows machine. As I use the path module to get a variable with path.joinand __dirname.

I have installed heroku buildpack:

The error I am receiving is:

Command failed: convert -quiet -delay 1 output.avi /app/temp/gifs/xstrycatdq.gif
convert: DelegateFailed `'ffmpeg' -nostdin -v -1 -vframes %S -i '%i' -vcodec pam -an -f rawvideo -y '%u.pam' 2> '%Z'' @ error/delegate.c/InvokeDelegate/1919.
convert: UnableToOpenBlob `magick-93R4VJcemPz0z1.pam': No such file or directory @ error/blob.c/OpenBlob/2705.
convert: NoImagesDefined `/app/temp/gifs/xstrycatdq.gif' @ error/convert.c/ConvertImageCommand/3257.

It seems that the /tmp/ directory can’t be written to or anything. I also tried to mkdir /tmp/ but bash tells me that this dir already exists.

I have also tried changing the imagemagick’s temp directory with the environment variable by doing export MAGICK_TMPDIR="temp".

Any help?

Edit: The variables are now absolute.


Get this bounty!!!

#StackBounty: #node.js #promise #typescript #express.js #oracle Exception handling and releasing of OracleDB connection

Bounty: 50

Before I start implementing several REST API service endpoints, I’d like to make sure that I’m not doing it totally wrong.

/**
 * GET /api/test
 * Test API example.
 */
export let getTest = (req: Request, res: Response, next: NextFunction) => {
    // const token = req.user.tokens.find((token: any) => token.kind === "facebook");
    const db = new Database();

    db.getConnection()
        .then(con => {
            con.execute('SELECT * FROM BTO_MDS.AlARMS', {}, { maxRows: 22000 })
                .then(result => {
                    con.release();
                    res.json({data: result.rows});
                })
                .catch(ex => {
                    con.release();
                    res.status(500).json({message: ex.message});
                });
        })
        .catch(ex => {
            res.status(500).json({message: ex.message});
        });

};
  • Is the connection always released properly, or have I forgotten something?

  • What seems a bit messy is that I need to release the connection two times, and that I have two catch’es, since I cannot release the connection in the second catch.

For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:

import * as oracledb from 'oracledb';
import { IConnectionPool } from 'oracledb';

const config = {
    user: 'user',
    password: 'pw',
    connectString: 'databaseNameFromTNSNames',
    poolMax: 16
};

export default class Database {
    private pool: IConnectionPool;    
    constructor() {  
    }

    public createPool(): void {
        oracledb.createPool(config).then(conpool => {
                this.pool = conpool;
                console.log('Connection Pool created!');
            },
            err => {
                console.log('Error creating pool!');
            });
    }

    public getConnection() {
        return oracledb.getConnection();
    }    
}


Get this bounty!!!