Sails: Can `machine-as-action` handle proceed in (req, res, proceed)?

Created on 27 Aug 2019  路  4Comments  路  Source: balderdashy/sails

When working with latest sails 1.2.3, I gather that policies do not have actions2 syntax support. Is this true?

I can make a policy return machine-as-action but exits.success() directly returns the response. A success in policy means proceed - which is what I want. Extracting req params works wonderfully, and I like the fact that I don't need to work with req, res in actions2 format - but as of now only policies are in legacy function (req, res, proceed) format.

To make policies use actions2 style - how can I tell machine-as-action to instead it call proceed?

question what do you think?

Most helpful comment

it would be possible to create machine-as-policy

All 4 comments

@visitsb Thanks for posting! We'll take a look as soon as possible.

In the mean time, there are a few ways you can help speed things along:

  • look for a workaround. _(Even if it's just temporary, sharing your solution can save someone else a lot of time and effort.)_
  • tell us why this issue is important to you and your team. What are you trying to accomplish? _(Submissions with a little bit of human context tend to be easier to understand and faster to resolve.)_
  • make sure you've provided clear instructions on how to reproduce the bug from a clean install.
  • double-check that you've provided all of the requested version and dependency information. _(Some of this info might seem irrelevant at first, like which database adapter you're using, but we ask that you include it anyway. Oftentimes an issue is caused by a confluence of unexpected factors, and it can save everybody a ton of time to know all the details up front.)_
  • read the code of conduct.
  • if appropriate, ask your business to sponsor your issue. _(Open source is our passion, and our core maintainers volunteer many of their nights and weekends working on Sails. But you only get so many nights and weekends in life, and stuff gets done a lot faster when you can work on it during normal daylight hours.)_
  • let us know if you are using a 3rd party plugin; whether that's a database adapter, a non-standard view engine, or any other dependency maintained by someone other than our core team. _(Besides the name of the 3rd party package, it helps to include the exact version you're using. If you're unsure, check out this list of all the core packages we maintain.)_

Please remember: never post in a public forum if you believe you've found a genuine security vulnerability. Instead, disclose it responsibly.

For help with questions about Sails, click here.

@visitsb Thanks for the details on this. We're curious what you use case is.

Generally, policies are best for global route security like verifying a user is logged in, etc.

Ah yes, an example would help.

My intent is to make policies __self-validating__, __self-documenting__. Today, only controller actions, global helpers can be written in actions2 syntax, but policies cannot - don't like to follow 2 _different_ styles in the same project if I can avoid it.

_Today_, this is how I have to write a policy. A very simple example where my policy checks whether someone is logged in based on a req parameter called token. In reality, I wouldn't do this so it is just illustrative for purpose of this discussion.

My logic is intertwined with req, res flow and only comments make it understood. Works, but only as long as I remember it.

// backend/api/policies/user/isLoggedInExample1.js
// Sails policy in traditional style
module.exports = async function (req, res, proceed) {
  let token = req.allParams().token;

  if (_.isEmpty(token)) {
    sails.log.warn(`No token could be extracted`);
    return res.forbidden();
  }

  // A valid user
  return proceed();
};

_Tomorrow_, this is how I'd prefer to write a policy - as a declarative definition machine. Definition of input params, exits is much more explicit, and best of all, my logic does not worry about req, res flow. My logic becomes less coupled, easy to extract into a helper, action as needed.
Note: asAction is used only because sails policies don't yet allow an actions2 format. I would prefer to declare policies in an actions2 syntax similar to actions, or helpers.

// backend/api/policies/user/isLoggedInExample2.js
const asAction = require('machine-as-action');

// Sails policy in actions2 style
module.exports = asAction({
  friendlyName: 'Is user logged in',
  description: 'Determine if user is logged in',
  inputs: {
    token: {
      description: 'Token',
      type: 'string',
      required: true
    }
  },
  exits: {
    success: {
      outputFriendlyName: 'User is logged in',
      outputDescription: 'User is logged in',
    },
    notLoggedIn: {
      description: 'User is not logged in',
      responseType: 'forbidden'
    }
  },

  fn: async function (inputs, exits) {
    let token = inputs.token;

    if (_.isEmpty(token)) {
      sails.log.warn(`No token could be extracted`);
      throw 'notLoggedIn' // return res.forbidden();
    }

    // A valid user
    return exits.success(); // return proceed();
  }
});

In the second example above, throw 'notLoggedIn' achieves the same effect as return res.forbidden();.

The only issue is with return exits.success();. I wish I could tell it to do a return proceed(); instead of a res.ok() which is what machine-as-action does on a successful exit.

Does this help to clarify my ask?

it would be possible to create machine-as-policy

Was this page helpful?
0 / 5 - 0 ratings