Permissions for dynamic webhooks in connect app

Hi, I am relatively new to Jira Cloud development and hoping someone can point me in the right direction… I am wanting to register a dynamic webhook that basically enables my app for specific projects inside Jira Service Desk. What is best practice for handling permissions for this type of scenario? How should I initiate dynamic webhook registration within my app for a project based on the user enabling/disabling this from the front end? Any help or pattern/examples would be greatly appreciated.

1 Like

Hi @MichaelMoriarty,

I don’t think we have any guides relating to this specifically. There are a few pages in the documentation relating to guides, patterns and tutorials, but none of them seem to answer your query:

The community may be able to offer better help for a more specific question.

Regards,
Dugald

1 Like

Thanks Dugald
When the user visits my settings page within my app, I need to check if I have already registered a dynamic webhook for their project and toggle the settings accordingly. It seems that I can’t initiate this check from the front end using the rest api ‘/rest/api/2/webhook’ … “only apps can request this resource” is the result I get when attempting this. Any idea how I can achieve this check from the front end?

1 Like

Hi @MichaelMoriarty,

You can make calls to the Jira REST API from your frontend using the AP.request JavaScript API, however, these are interpreted by Jira as if the logged in user is making the request so the POST /rest/api/3/webhook resource will return a 403 error.

I think you’ll have to send the request from your frontend to your backend and make a JWT request to Jira from there. Before making the request from your backend, you should check the permissions. To do this, you can retrieve a token in your frontend using AP.context.getToken() and transfer this to your backend with the request to subscribe to the webhook. You can extract the user out of the token on your backend after validating it, then make the permission check by calling Jira with the user.

The guide on cacheable app iframes may also be worth reading if you haven’t already.

Regards,
Dugald

2 Likes

Thanks Dugald
Very helpful as usual…

Regards

Michael

1 Like

Hi Dugald
I have followed your suggested pattern and the approach seems to work OK so-far, but I just wanted to check that I am on the right path…

Send request to register dynamic webhook from front-end to the backend with the user token

const getSettings = await fetch('/create-project-webhook', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `JWT ${userToken}`,
            },
            body: JSON.stringify({ projectKey: projectKey, userToken: userToken }),
            });

Authenticate request on backend using user token and create webbhook as App

app.post('/create-project-webhook', addon.authenticate(), async(req, res) => {
        const projectKey = req.body.projectKey;
        const userToken = req.body.userToken;
        
       // Check user has permission utilising token?
         ...

        // Create webhook as App
        const httpClient = addon.httpClient(req);
        const serviceDeskClient = new ServiceDeskClient(httpClient);
        const registeredWebHooks = await serviceDeskClient.registerProjectWebhooks(projectKey);

        res.send(
            `Project Key: ${projectKey} has been enabled`,
          );
        res.end();
    });

Is this an adequate approach?
Can I use the JWT token sent to the backend to check if the user has sufficient privileges? Any examples you can point me towards to achieve this?

Once again thanks for your support

Michael

1 Like

Just thought I would post the solution for checking user permissions from the backend of ACE as the App in case it is helpful for others:
In the app manifest we added the scope: act_as_user and from the backend utilised the asUserByAccountId method whilst calling the ‘mypermissions’ endpoint:

this.httpClient.asUserByAccountId(`${accountId}`).get({
               url: `/rest/api/3/mypermissions?permissions=ADMINISTER_PROJECTS`,
               json: true
               ...

which returns:

permissions: {
    ADMINISTER_PROJECTS: {
      id: '23',
      key: 'ADMINISTER_PROJECTS',
      name: 'Administer Projects',
      type: 'PROJECT',
      description: 'Ability to administer a project in Jira.',
      havePermission: true
    }
  }
1 Like