Assigning users stops working after adding “storage:app" scope

When we are using:

api.asApp().requestJira(`/rest/api/3/issue/${issueId}/assignee`);

With scopes like:

   -  'read:jira-user'
   -  'read:jira-work'
   -  'write:jira-work'
   -  'manage:jira-project'
   -  'manage:jira-configuration'

Assigning users works properly.

But when we add scope for “storage:app” the assigning users on the development environment stops working.

When we are using Forge tunnel then assigning users works partially (user is assigned but not refreshed in UI).
But when we try to assign users in the development environment (from mine or other accounts), assigning users is not working (no errors).
After we remove the scope “storage:app” assigning user starts working again without any issues.

Hey @rafalkedzierski :wave:
Are you assigning users “manually” from Jira or via API call?
Can you reveal with us code snippet with this operation?

Hey,
We are assigning users via API call.
Sample code looks like this:

const bodyData = {
    accountId: assignee,
  };
await api.asApp().requestJira( `/rest/api/3/issue/${issueId}/assignee`, {
    method: 'PUT',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(bodyData),
})

Are you reinstalling after modifying the scopes?

Yes, we are using: forge install --upgrade

Right now we have a problem getting it working event without the storage permission in the app scope. The assigning is working only when we use tunneling locally, it assing user but the change is only visible after page reload. Without the tunnel, there is no change to the assignee field. We don’t get any responses from API or at least none is logged. It is the same on prod and dev instances and both development and production forge environments. The code we have right now looks like this and is similar to forge example on the Jira cloud API page (https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-assignee-put)
Our code looks like this:

const setAssignee = async (
  assignee: string,
  issueId: string,
): Promise<void> => {
  const bodyData = {
    "accountId": assignee,
  };
  const response = await api
    .asUser()
    .requestJira(`/rest/api/3/issue/${issueId}/assignee`, {
      method: 'PUT',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(bodyData),
    });
  console.log(`Response: ${response.status} ${response.statusText}`);
  console.log(await response.json());
};

I also tested the api from postman and it works ok.

I can add that we would like to go to marketplace with our Forge app asap and this issue is blocking us.

@MichalMichalczuk can you folks help us somehow with this issue, or this topic should be maybe in more general jira cloud section ?

Hello @TheopiliusBauer,

I see you are making the call asUser(). This means the request will use permissions of the user interacting with the app, which may make this operation behave unexpectedly, depending on the permissions configuration. Have you tried asApp()?

Other than that, permissions/scopes resolution is known to not work reliably when scopes are updated in the app. Whenever you change your scopes, I would advise to recreate the app from scratch to avoid any issues (i.e. regenerate the app ID with forge register).

We don’t get any responses from API

What do you mean by this? Surely there has to be a status code, there always is. And if not, then the call must be failing even before reaching Jira. It would be helpful if you could share how it is failing exactly.

We have the same problem wiht asApp(). I also tried fresh registration but it did not help.

By no responses I mean that I cannot log them somehow. With code looking like this

const setAssignee = async (
  assignee: string,
  issueId: string,
): Promise<void> => {
  const bodyData = {
    "accountId": assignee,
  };
  const response = await api
    .asUser()
    .requestJira(`/rest/api/3/issue/${issueId}/assignee`, {
      method: 'PUT',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(bodyData),
    });
  console.log(`Response: ${response.status} ${response.statusText}`);
  console.log(await response.json());
};

I should be able to see those console.logs using forge logs but I don’t get anything. My guess is there may be some errors on forge side but we don’t have access to them from forge CLI

1 Like

I just tested this API and it worked for me in my app, I used the code you provided. One thing to note is that the API does not return any response so await response.json() will always fail with the Unexpected end of JSON input error. Perhaps this is part of the problem.

1 Like

What @kkercz wrote

One thing to note is that the API does not return any response so await response.json()

Is valid point.

@TheopiliusBauer can you check what those lines print to you in logs?

console.log(Response: ${response.status} ${response.statusText});

Hi,

Thanks for all the tips. I’m aware that the endpoint is not returning anything when it is successful. Thats the strange thing it looks like it is a success (no response) but the assignee is not changed. Anyway removing console logs is not making any difference and the assigning is still only working while forge tunnelling is on and not working without tunnelling. My code now looks like this:

const setAssignee = async (
  assignee: string,
  issueId: string,
): Promise<void> => {
  const bodyData = {
    accountId: assignee,
  };

  const response = await api.asApp().requestJira(`/rest/api/3/issue/${issueId}/assignee`, {
    method: 'PUT',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(bodyData),
  });
};

Same without using const response and calling it directly.

@MichalMichalczuk That’s the problem I’m not getting any response so I assuming the call is successful but the assignee is not changed.

If it make any diffrence we are making the call from issue action extension point.

So after some more debugging I discovered what was causing the problem, apparently we were closing the issue action modal before the call jira api was finished and closing of it somehow blocked it. Not sure why it worked with tunnelling i guess the call was fast enough to finish before modal was closed.

Another topic that I quite not understand is why sometime the assignee field would update itself after the modal is closed and sometimes it wont do it. Any ideas?

2 Likes

Hi @kkercz - can you elaborate on this advice? This is a highly worrying/irritating statement, as recreating from scratch on scope changes is not even possible for commercial apps (app id is the reference from the marketplace entry), and also not practical for any app that is not completely stateless (e.g. if an app provides issue panels, macros or similar elements with content, those would just be lost after an app id change)!

2 Likes