Sink script: 401 when invoking Compose.findNamespaceBySlug

Hi,
I’m new with Corteza and I need your help.

I’ve managed to create a server automation script that is triggered on a system:sink. I’ve created a sink to that path and manged to invoke with curl. I can see a simple result coming back.

My next step was to attempt to create a record (the overall goal being to inject some records). To do that I saw that I need to use Compose and for a record to be inserted I need to identify the right module in the right namespace.

This is where I got stuck. Whenever I call

Compose.findNamespaceBySlug("crm")

or anything similar I get a 401 exception which I’ll reproduce here:

{
    "message": "Request failed with status code 401",
    "name": "Error",
    "stack": "Error: Request failed with status code 401\n    at createError (/corredor/node_modules/axios/lib/core/createError.js:16:15)\n    at settle (/corredor/node_modules/axios/lib/core/settle.js:17:12)\n    at IncomingMessage.handleStreamEnd (/corredor/node_modules/axios/lib/adapters/http.js:260:11)\n    at IncomingMessage.emit (events.js:228:7)\n    at IncomingMessage.EventEmitter.emit (domain.js:475:20)\n    at endReadableNT (_stream_readable.js:1185:12)\n    at processTicksAndRejections (internal/process/task_queues.js:81:21)",
    "config": {
      "url": "/namespace/",
      "method": "get",
      "headers": {
        "Accept": "application/json, text/plain, */*",
        "Content-Type": "application/json",
        "User-Agent": "axios/0.21.1"
      },
      "params": {
        "slug": "crm"
      },
      "baseURL": "http://server/api/compose",
      "transformRequest": [
        null
      ],
      "transformResponse": [
        null
      ],
      "timeout": 0,
      "withCredentials": true,
      "xsrfCookieName": "XSRF-TOKEN",
      "xsrfHeaderName": "X-XSRF-TOKEN",
      "maxContentLength": -1,
      "maxBodyLength": -1
    }

The sample code I’m using for my script is:

export default {
  label: "hello script",

  security: {
    runAs: 'adi',
  },

  triggers({ on }) {
    return on("request")
      .where("request.path", "/hello")
      .where("request.method", "GET")
      .for("system:sink");
  },

  async exec({ $request, $response }, {Compose}) {
    console.log("hello script running")
    console.log("request: " + JSON.stringify($request))

    try {
      let ns = await Compose.findNamespaceBySlug("crm")
      console.log("ns: " + ns)
    }catch(err) {
      console.error("got error " + err)
      $response.status = 500;
      $response.header = { "Content-Type": ["application/json"] };
      $response.body = JSON.stringify({
        error: true,
        msg: err,
        status: $response.status
      });
      return $response;
    }
  },
};

Note that user adi is an admin, and the script is actually executed. I have my own namespace I want to find, but for the sake of this post I used the available crm.

The servers (2021.3.7) run in docker-compose (hence the http://server/api/compose).

Could you please help me with this? I’m sure I’m missing something but I can’t seem to find the problem :frowning:

Thank you

1 Like

Thank you for the report; I created a ticket for one of us to take a look at this.

Are you able to check if this works with the 2020.12 version? There was a bigger authentication change in 2021.3 and it’s possible that we’ve missed something.
Looking at the code, your script is spot on.

Thank you for looking into it.

In the mean time, I managed a workaround as follows:

import { corredor } from "@cortezaproject/corteza-js";
export default {
  label: "hello script",

  security: {
    runAs: "adi",
  },

  triggers({ on }) {
    return on("request")
      .where("request.path", "/hello")
      .where("request.method", "GET")
      .for("system:sink");
  },

  async exec({ $request, $response, authToken }, { ComposeAPI }) {
    ComposeAPI.accessTokenFn = function () {
      return authToken;
    };
    console.log("hello script running");
    console.log("request: " + JSON.stringify($request));

    try {
      let ch = new corredor.ComposeHelper({ ComposeAPI: ComposeAPI });
      let ns = await ch.findNamespaceBySlug("crm");
      console.log("ns: " + ns);

    } catch (err) {
      console.error("got error " + err);
      $response.status = 500;
      $response.header = { "Content-Type": ["application/json"] };
      $response.body = JSON.stringify({
        error: true,
        msg: err,
        status: $response.status,
      });
      return $response;
    }
  },
};

It seems to me that if my script is ok, the problem is lurking around the destructuring of parameter ctx of the exec. The ComposeHelper does not seem to receive the authToken when using
exec({$request,$response},{Compose}){...
so I’ve helped it a bit.

I have not tried 2020.12 yet.

@ami can you try updating to 2021.3.9 (changelog – Add 2021.3.9 changelog · cortezaproject/corteza-docs@0bead1f · GitHub)?

My suspicions were correct and we’ve made a lapsus when reworking the new authentication logic.
Can you confirm that the above-mentioned patch resolves your issue?

I confirm it works fine with docker image 2021.3.9.

Thank you for your help!

(it does not work yet on the 2021.9.x git branch I was experimenting on now).

Awesome; thanks for confirming it!

\cc @darh can this be ported to 2021.9.x or does it need additional work there?

All ported. corteza-js repo.