MrRefactoring / jira.js

A JavaScript/TypeScript wrapper for the JIRA Cloud, Service Desk and Agile REST API
https://mrrefactoring.github.io/jira.js/
MIT License
349 stars 46 forks source link

OAuth2 Issues #269

Open cmerther opened 1 year ago

cmerther commented 1 year ago

Hello,

I am trying to use jira.js to read project info and write issues to my jira project. I'm using atlassian's OAuth (3LO) authentication flow. The scopes that I use for this login are read:jira-work write:jira-work read:me offline_access.

I was reading over issue #231 and found out about https://api.atlassian.com/oauth/token/accessible-resources and the api at https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3.

After much trial and error I've got one endpoint working through a raw get request https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/project/{jiraProjectKey} which will return information. However when I try to do the same call through the library it doesn't find any project with that key.

//`https://site.atlassian.net/rest/api/3/project/${jiraProjectKey}` interestingly does not work
//this will work
axios.get(`https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/project/${jiraProjectKey}`, {
    headers: {
        Authorization: `Bearer ${accessToken.access_token}`
    }
}).then(response => {
    console.log('success', response.data);
}).catch(error => {
    console.log('err', error);
});

const jira = new Version3Client({
    // I've tried settings the host to the api.atlassian.com base but it produces the same results. which I think was the solution for #231 
    // host: `https://api.atlassian.com/ex/jira/${cloudId}`,
    host: 'https://site.atlassian.net',
    newErrorHandling: true,
    authentication: {
        oauth2: {
            accessToken: `Bearer ${accessToken.access_token}`,
        },
    },
});

//this does not work, can't find the project key or id
const resp = await jira.projects.getProject({ projectIdOrKey: settings.jiraProjectKey });
console.log('lib resp', resp);

Any ideas what I'm doing wrong?

MrRefactoring commented 1 year ago

Hello @cmerther! Right config for you:

const jira = new Version3Client({
    // I've tried settings the host to the api.atlassian.com base but it produces the same results. which I think was the solution for #231 
    // host: `https://api.atlassian.com/ex/jira/${cloudId}`,
    host: 'https://site.atlassian.net',
    newErrorHandling: true,
    authentication: {
        oauth2: {
            accessToken: accessToken.access_token,
        },
    },
});
cmerther commented 1 year ago

Thank you for the quick reply!

But I forgot to include that I've tried that. If I don't have Bearer before the accessToken.access_token I get Client must be authenticated to access this resource.

MrRefactoring commented 1 year ago

Please show me an exact example of how you tried

cmerther commented 1 year ago

The access_token is short lived, only an hour, let me know if you need another one. index.js

const { Version3Client } = require('jira.js');
const axios = require('axios');

(() => {
    try {
        const accessToken = {
            access_token: 'eyJraWQiOiJmZTM2ZThkMzZjMTA2N2RjYTgyNTg5MmEiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIyODAzYzVmMi03Y2I2LTRkYjMtYWQ0YS1iOWE4ZGIxM2IxMDkiLCJzdWIiOiI3MTIwMjA6NGI5MjczMWEtYjRiZi00NDJmLWJhMzEtYjRlNDE4ZjZjNzgwIiwibmJmIjoxNjg4MjY0MjI1LCJpc3MiOiJodHRwczovL2F1dGguYXRsYXNzaWFuLmNvbSIsImlhdCI6MTY4ODI2NDIyNSwiZXhwIjoxNjg4MjY3ODI1LCJhdWQiOiJvbkRZVVd0TVc0aHZraWNVcDNKTXF1UkxuSkQxMXdrOCIsInNjb3BlIjoicmVhZDpqaXJhLXdvcmsgb2ZmbGluZV9hY2Nlc3Mgd3JpdGU6amlyYS13b3JrIHJlYWQ6bWUiLCJodHRwczovL2lkLmF0bGFzc2lhbi5jb20vc2Vzc2lvbl9pZCI6Ijg0NjNhNGZlLTNhYzItNDVlMi04ZDJmLWMxNzFiMjMzYWRmNSIsImh0dHBzOi8vaWQuYXRsYXNzaWFuLmNvbS9hdGxfdG9rZW5fdHlwZSI6IkFDQ0VTUyIsImh0dHBzOi8vaWQuYXRsYXNzaWFuLmNvbS91anQiOiI2OTQzZGZkNC0yOTJmLTQ1ODUtODZjNC0wYTVmNDk4MmRjNTQiLCJodHRwczovL2F0bGFzc2lhbi5jb20vZmlyc3RQYXJ0eSI6ZmFsc2UsImNsaWVudF9pZCI6Im9uRFlVV3RNVzRodmtpY1VwM0pNcXVSTG5KRDExd2s4IiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL3ZlcmlmaWVkIjp0cnVlLCJodHRwczovL2lkLmF0bGFzc2lhbi5jb20vcHJvY2Vzc1JlZ2lvbiI6InVzLWVhc3QtMSIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9zeXN0ZW1BY2NvdW50RW1haWwiOiIwNTU3OTdlZS1lYjhlLTRkNGMtYjlhMS1lYjYzODJkYmJkYTNAY29ubmVjdC5hdGxhc3NpYW4uY29tIiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL2VtYWlsRG9tYWluIjoiYmV0YXRlc3RteXByb2R1Y3QuY29tIiwiY2xpZW50X2F1dGhfdHlwZSI6IlBPU1QiLCJodHRwczovL2F0bGFzc2lhbi5jb20vc3lzdGVtQWNjb3VudElkIjoiNzEyMDIwOjUxMjA2NWE0LTM3MzEtNDBjNi1hZTE2LTViNmEzMDU3NGE0OCIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS8zbG8iOnRydWUsImh0dHBzOi8vaWQuYXRsYXNzaWFuLmNvbS92ZXJpZmllZCI6dHJ1ZSwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL29hdXRoQ2xpZW50SWQiOiJvbkRZVVd0TVc0aHZraWNVcDNKTXF1UkxuSkQxMXdrOCIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9zeXN0ZW1BY2NvdW50RW1haWxEb21haW4iOiJjb25uZWN0LmF0bGFzc2lhbi5jb20ifQ.AWI-iPMWrgPjDpdG2Wwg2MzlUMcQjMhBCnYUDGiLggfyEmdoJR1901i1Tug1RJjLegcni5c4DneAs7V_3kqpfFWh40VFx_ZXVQW50TzlQKkjKFTQXmu5qlPmQv0yDaXpgRqazNYAtltg9mJyqe0DfMosmvmHGvkHZ5FrtsL8CVHbb2xSWqNdiaWB7TZIc5SMFIRCLt4WEllVCE4f8cW9iixuaBNSFud1VEr5rbxy_C11ftsARLeHWJ5e3Og0WdFjYRI2WG0mqGBriSxZvAJ1mZE1TwyhJIHKXljDnu8oeVPIhL2kV_puxPbLAHI3vgI0fZ5Dpa9GznRSykp29ica4A',
            expires_in: 3600,
            token_type: 'Bearer',
            scope: 'read:jira-work offline_access write:jira-work read:me',
            expAt: '2023-07-02T07:17:05.000Z',
            cloudId: 'be06a76e-a378-4695-a251-5cc9a358920c'
        }
        const jiraProjectKey = 'BET';

        const jira = new Version3Client({
            host: `https://betatestmyproduct.atlassian.net`,
            newErrorHandling: true,
            authentication: {
                oauth2: {
                    accessToken: `Bearer ${accessToken.access_token}`,
                },
            }
        });

        jira.projects.getProject({ projectIdOrKey: jiraProjectKey })
            .then(response => {
                console.log('lib resp', response);
            })
            .catch(error => { console.log('lib error', error) });

        axios.get(`https://api.atlassian.com/ex/jira/${accessToken.cloudId}/rest/api/3/project/${jiraProjectKey}`, {
            headers: {
                Authorization: `Bearer ${accessToken.access_token}`
            }
        }).then(response => {
            console.log('get success', response.data);
        }).catch(error => {
            console.log('get error', error);
        });
    } catch (error) {
        console.log('general error', error);
    }
})();

package.json

{
  "name": "jira-example",
  "version": "1.0.0",
  "main": "index.js",
  "author": "Chris",
  "license": "MIT",
  "dependencies": {
    "axios": "1.1.3",
    "jira.js": "2.19.0"
  },
  "scripts": {
    "start": "node index.js"
  }
}
MrRefactoring commented 1 year ago

No I mean when you used accessToken: accessToken.access_token

This example I need

cmerther commented 1 year ago

Alright,

const { Version3Client } = require('jira.js');
const axios = require('axios');

(() => {
    try {
        const accessToken = {
            access_token: 'eyJraWQiOiJmZTM2ZThkMzZjMTA2N2RjYTgyNTg5MmEiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIzN2NmNzJlZi0zYTE4LTQ3OTktODBhMi01YTEwY2M3YjVhNGIiLCJzdWIiOiI3MTIwMjA6NGI5MjczMWEtYjRiZi00NDJmLWJhMzEtYjRlNDE4ZjZjNzgwIiwibmJmIjoxNjg4MzE0MTQxLCJpc3MiOiJodHRwczovL2F1dGguYXRsYXNzaWFuLmNvbSIsImlhdCI6MTY4ODMxNDE0MSwiZXhwIjoxNjg4MzE3NzQxLCJhdWQiOiJvbkRZVVd0TVc0aHZraWNVcDNKTXF1UkxuSkQxMXdrOCIsInNjb3BlIjoicmVhZDpqaXJhLXdvcmsgb2ZmbGluZV9hY2Nlc3Mgd3JpdGU6amlyYS13b3JrIHJlYWQ6bWUiLCJodHRwczovL2lkLmF0bGFzc2lhbi5jb20vdWp0IjoiNjE4MmQ1NWMtNzAwMi00M2YxLTgyNzQtY2EwYjIwMGViM2FiIiwiaHR0cHM6Ly9pZC5hdGxhc3NpYW4uY29tL3Nlc3Npb25faWQiOiI4NDYzYTRmZS0zYWMyLTQ1ZTItOGQyZi1jMTcxYjIzM2FkZjUiLCJodHRwczovL2lkLmF0bGFzc2lhbi5jb20vYXRsX3Rva2VuX3R5cGUiOiJBQ0NFU1MiLCJodHRwczovL2F0bGFzc2lhbi5jb20vZmlyc3RQYXJ0eSI6ZmFsc2UsImNsaWVudF9pZCI6Im9uRFlVV3RNVzRodmtpY1VwM0pNcXVSTG5KRDExd2s4IiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL3ZlcmlmaWVkIjp0cnVlLCJodHRwczovL2lkLmF0bGFzc2lhbi5jb20vcHJvY2Vzc1JlZ2lvbiI6InVzLWVhc3QtMSIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9zeXN0ZW1BY2NvdW50RW1haWwiOiIwNTU3OTdlZS1lYjhlLTRkNGMtYjlhMS1lYjYzODJkYmJkYTNAY29ubmVjdC5hdGxhc3NpYW4uY29tIiwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL2VtYWlsRG9tYWluIjoiYmV0YXRlc3RteXByb2R1Y3QuY29tIiwiY2xpZW50X2F1dGhfdHlwZSI6IlBPU1QiLCJodHRwczovL2F0bGFzc2lhbi5jb20vc3lzdGVtQWNjb3VudElkIjoiNzEyMDIwOjUxMjA2NWE0LTM3MzEtNDBjNi1hZTE2LTViNmEzMDU3NGE0OCIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS8zbG8iOnRydWUsImh0dHBzOi8vaWQuYXRsYXNzaWFuLmNvbS92ZXJpZmllZCI6dHJ1ZSwiaHR0cHM6Ly9hdGxhc3NpYW4uY29tL29hdXRoQ2xpZW50SWQiOiJvbkRZVVd0TVc0aHZraWNVcDNKTXF1UkxuSkQxMXdrOCIsImh0dHBzOi8vYXRsYXNzaWFuLmNvbS9zeXN0ZW1BY2NvdW50RW1haWxEb21haW4iOiJjb25uZWN0LmF0bGFzc2lhbi5jb20ifQ.Fu5fWb_WieQKSE6ZSoEJY-H1yMriUA7ROND_zi75kImjQa68BVGzrhODr1NRWOfkRl4ks12U3Sl9aAc34iZDM3Ou9VfN6se84qI2KzlOWiSYTNOg0RxSnG1SnmaqmQU4zTVC0JZkpPDjJ17nTDMcMgRGZIEYVGsfi2bFlWFDSMCctTqkKrbJfXrESFhJHjzKp5QwmSXVqrunhq_PJQW1uOkjtXON_DmD0PXSAc53T0kSPQLqYMqPIqENUn0tCQYT9R3QTBN1_jB_fXGpi4CZfc7KVDWFIktkmGGuu9_vdsEuKMAm1XM368CIrNSofRjryM8VxQdSZVESJC-3vR5MGA',
            expires_in: 3600,
            token_type: 'Bearer',
            scope: 'read:jira-work offline_access write:jira-work read:me',
            expAt: '2023-07-02T21:09:00.000Z',
            cloudId: 'be06a76e-a378-4695-a251-5cc9a358920c'
        }
        const jiraProjectKey = 'BET';

        const jira = new Version3Client({
            host: `https://betatestmyproduct.atlassian.net`,
            newErrorHandling: true,
            authentication: {
                oauth2: {
                    accessToken: accessToken.access_token,
                },
            }
        });

        jira.projects.getProject({ projectIdOrKey: jiraProjectKey })
            .then(response => {
                console.log('lib resp', response);
            })
            .catch(error => { console.log('lib error', error) });
    } catch (error) {
        console.log('general error', error);
    }
})();
MrRefactoring commented 1 year ago

Very weird. Looks like it should work

ameer-clara commented 11 months ago

I can confirm this works for me for version3Client as well as AgileClient:

const jira = new Version3Client({
    host: `https://api.atlassian.com/ex/jira/${cloudId}`,
    newErrorHandling: true,
    authentication: {
        oauth2: {
            accessToken: accessToken.access_token,
        },
    },
});

None of the above solutions described above work for me, either using:

host:`${yoursite}.atlassian.net`

or

accessToken: `Bearer ${accessToken.access_token}`

Thanks for raising this issue @cmerther, made my day 👍