Cannot access REST API with @forge/bridge

I am trying to access the JIRA Rest API from a forge custom UI app.
Some of the APIs can be accessed without any problem. However this call works in the browsers
rest/agile/1.0/board/2/sprint/1/issue but returns a 403 error when invoking it within the app.

This is the error message:

“Access to the resource was denied due to missing scope grants. Your app was granted the following scopes: [read:jira-work, offline_access, read:me, write:jira-work].\nThe following scopes are necessary to access the resource: [read:issue-details:jira, read:jql:jira, read:sprint:jira-software]”

This is the relevant code in the custom UI Forge app:

import { Injectable } from '@angular/core';
import { requestJira } from '@forge/bridge';

async fetchData() {
    
    //Works
    console.log("/rest/api/3/issue/SW-20");
    var responseIssue = await requestJira('/rest/api/3/issue/SW-20');
    console.log(await responseIssue.json);

    // error with status of 403 - missing permission level
    console.log("/rest/agile/1.0/board/2/sprint/1/issue");
    var responseSprintIssues = await requestJira('/rest/agile/1.0/board/2/sprint/1/issue');
    console.log(await responseSprintIssues.json);
}

In the manifest.yml I have added allmost all permission levels. But no success.

permissions:
scopes:
- read:me
- write:jira-work
- read:jira-user
- read:jira-work
- read:issue-details:jira
- read:board-scope:jira-software
- read:sprint:jira-software
- read:jql:jira
- read:issue.transition:jira
- read:status:jira
- read:field-configuration:jira
- read:webhook:jira
- read:user.property:jira
- read:user:jira
- read:user-configuration:jira
- read:status:jira
- read:project.property:jira
- read:project.feature:jira
- read:project.component:jira
- read:project.avatar:jira
- read:project:jira
- read:project-version:jira
- read:project-type:jira
- read:project-category:jira
- read:issue.vote:jira
- read:issue.property:jira
- read:issue.changelog:jira
- read:issue:jira
- read:issue-worklog.property:jira
- read:issue-worklog:jira
- read:issue-type.property:jira
- read:issue-type:jira
- read:issue-type-hierarchy:jira
- read:issue-status:jira
- read:issue-security-level:jira
- read:issue-meta:jira
- read:issue-link:jira
- read:issue-link-type:jira
- read:issue-details:jira
- read:group:jira
- read:field.option:jira
- read:field.default-value:jira
- read:field:jira
- read:field-configuration:jira
- read:comment.property:jira
- read:avatar:jira

Even when redeploying with forge install --upgrade or un/reinstalling the app there is the same error.
Does anyone know what permission levels are needed for rest/agile/1.0/board/2/sprint/1/issue?

It seems there are quite a few “scope” related posts very recently. It might be something on Atlassian’s side related to changes around how granting access permissions are being handled. Although I haven’t encountered the issue, you might try completely uninstalling, remove all scopes, redeploy, reinstall, readd scopes, redeploy, and then upgrade, to see if you can get it to ask to grant permissions again. It sounds almost as if permission scope changes aren’t being handled.

2 Likes

I’ve tried various things. Other permission scopes and also recrating the forge app template from scratch. However no success.

My current workarroud that works is to use invoke from ‘@forge/bridge’. This is a bit ugly as I do not use requestJira from ‘@forge/bridge’ directly. I also think this is a bit slower than requestJira.

This is my workarround: in the dataservice I use invoke(‘getBoardsOfProject’, { projectId: projectId }) that accesses then a resolver.

See the snippets below:

export class DataService {
....
  getBoards(): Observable<Board[]> {
    const projectId: string = this.getJiraProjectID();
    const promise = invoke('getBoardsOfProject', { projectId: projectId });
    return from(promise).pipe(
      map((boardData: any) => {
        var boards: Board[] = (boardData as invokeResultBoards).values;
        return boards.filter((board) => board?.type === 'scrum');
      }),
      tap(boards => this.boardsSubject.next(boards))
    );
  }
...
}

This invoke(‘getBoardsOfProject’, { projectId: projectId }) resides in the index.js of the main forge app and exposes access through a resolver:

// get all Boards for current Project  
resolver.define("getBoardsOfProject", async ({payload, context }) => {
  console.log (payload)
  try {
    if (payload.projectId.length === 0) {
      // only for project 
      return await getDataFromJiraApi(
        route`/rest/agile/1.0/board?projectKeyOrId=${payload.projectId}` 
      );
    } else {  
      //all
      return await getDataFromJiraApi(
        route`/rest/agile/1.0/board`
      );
    }
  } catch (error) {
    console.error("Error while fetching data from Jira:", error);
    throw error;
  }
});

This is now my workarround for getting data from all APIs of “/rest/agile/1.0/”.
I did not find another solution that works so far.