Search code examples
javascriptnode.jsdecoratorbabeljsecmascript-2016

How to implement an authenticated es 7 decorator with babel for my js service module


I'm using babel with decorator stage:0 support in my flux fluxible js project, and I want to use an authenticated decorator for my service api modules to check for a valid user session.

Googling around, there seems to be several posts that explain different variations but couldn't find one definitive docs or instructionals.

Here's what I tried so far, I know that my parameters for the authenticated function are incorrect, and not sure if I need to implement a class for my module rather than just using the exports object.

The part that I couldn't find the docs for is how to implement the decorator itself - in this case something that takes the req parameter the decorated function will receive and checking it.

// how do I change this method so that it can be implemented as a decorator
function checkAuthenticated(req) {

    if (!req.session || !req.session.username)
    {
        throw new Error('unauthenticated');
    }
}

module.exports = {
    @checkAuthenticated
    read: function(req, resource, params, serviceConfig, callback) {
        //@authenticated decorator should allow me to move this out of this here
        //checkAuthenticated(req);
        if (resource === 'product.search') {
            var keyword = params.text;
            if (!keyword || keyword.length === 0) {
                return callback('empty param', null);
            } else {
                searchProducts(keyword, callback);
            }
        }

    }
};

Solution

  • class Http{
      @checkAuthenticated
      read(req, resource, params, serviceConfig, callback) {
        if (resource === 'product.search') {
          var keyword = params.text;
          if (!keyword || keyword.length === 0) {
            return callback('empty param', null);
          } else {
            this.searchProducts(keyword, callback);
          }
        }
      }
    
      searchProducts(keyword, callback) {
        callback(null, 'worked');
      }
    }
    
    function checkAuthenticated(target, key, descriptor) {
        return {
          ...descriptor,
          value: function(){
            console.log(arguments);
            const req = arguments[0];
            if (!req.session || !req.session.username) {
                throw new Error('unauthenticated');
            }
            return descriptor.value.apply(this, arguments);
          }
        };
    }
    
    let h = new Http();
    
    h.read(
      { session: { username: 'user' } },
      'product.search',
      { text: 'my keywords' },
      null,
      function(err, result) {
        if (err) return alert(err);
        return alert(result);
      }
    );
    

    See jsbin http://jsbin.com/yebito/edit?js,console,output