@@ -27,6 +27,7 @@ import { | |||
serializeString | |||
} from '../../../helpers/query'; | |||
import { isBitbucket, isGithub } from '../../../helpers/almIntegrations'; | |||
import { decodeJwt } from '../../../helpers/strings'; | |||
export const ORGANIZATION_IMPORT_REDIRECT_TO_PROJECT_TIMESTAMP = | |||
'sonarcloud.import_org.redirect_to_projects'; | |||
@@ -45,15 +46,23 @@ export interface Query { | |||
export const parseQuery = memoize( | |||
(urlQuery: RawQuery = {}): Query => { | |||
return { | |||
almInstallId: | |||
parseAsOptionalString(urlQuery['installation_id']) || | |||
parseAsOptionalString(urlQuery['clientKey']), | |||
almKey: | |||
(urlQuery['installation_id'] && 'github') || | |||
(urlQuery['clientKey'] && 'bitbucket') || | |||
undefined | |||
}; | |||
let almInstallId = undefined; | |||
let almKey = undefined; | |||
if (urlQuery['installation_id']) { | |||
almKey = 'github'; | |||
almInstallId = parseAsOptionalString(urlQuery['installation_id']); | |||
} else if (urlQuery['clientKey']) { | |||
almKey = 'bitbucket'; | |||
almInstallId = parseAsOptionalString(urlQuery['clientKey']); | |||
} else if (urlQuery['jwt']) { | |||
const jwt = decodeJwt(urlQuery['jwt']); | |||
if (jwt && jwt.iss) { | |||
almKey = 'bitbucket'; | |||
almInstallId = jwt.iss; | |||
} | |||
} | |||
return { almInstallId, almKey }; | |||
} | |||
); | |||
@@ -17,7 +17,29 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { latinize, slugify } from '../strings'; | |||
import { decodeJwt, latinize, slugify } from '../strings'; | |||
describe('#decodeJwt', () => { | |||
it('should correctly decode a jwt token', () => { | |||
const claims = { | |||
aud: 'ari:cloud:bitbucket::app/{327713ed-f1b2-4659-9c91-c8ecf8be7f3e}/sonarcloud-greg', | |||
exp: 1541062205, | |||
iat: 1541058605, | |||
iss: 'ari:cloud:bitbucket::app/{327713ed-f1b2-4659-9c91-c8ecf8be7f3e}/sonarcloud-greg', | |||
qsh: 'a6c93addd971c05d08da1e1669c2640fba529e98fbb5b2b9effadf00bf484277' | |||
}; | |||
expect( | |||
decodeJwt( | |||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhcmk6Y2xvdWQ6Yml0YnVja2V0OjphcHAvezMyNzcxM2VkLWYxYjItNDY1OS05YzkxLWM4ZWNmOGJlN2YzZX0vc29uYXJjbG91ZC1ncmVnIiwiaWF0IjoxNTQxMDU4NjA1LCJxc2giOiJhNmM5M2FkZGQ5NzFjMDVkMDhkYTFlMTY2OWMyNjQwZmJhNTI5ZTk4ZmJiNWIyYjllZmZhZGYwMGJmNDg0Mjc3IiwiYXVkIjoiYXJpOmNsb3VkOmJpdGJ1Y2tldDo6YXBwL3szMjc3MTNlZC1mMWIyLTQ2NTktOWM5MS1jOGVjZjhiZTdmM2V9L3NvbmFyY2xvdWQtZ3JlZyIsImV4cCI6MTU0MTA2MjIwNX0.5_0dFh_TPT_UorDewu2JEErgQE2ZnzBjvCDrOThseRo' | |||
) | |||
).toEqual(claims); | |||
expect( | |||
decodeJwt( | |||
'eyJpc3MiOiJhcmk6Y2xvdWQ6Yml0YnVja2V0OjphcHAvezMyNzcxM2VkLWYxYjItNDY1OS05YzkxLWM4ZWNmOGJlN2YzZX0vc29uYXJjbG91ZC1ncmVnIiwiaWF0IjoxNTQxMDU4NjA1LCJxc2giOiJhNmM5M2FkZGQ5NzFjMDVkMDhkYTFlMTY2OWMyNjQwZmJhNTI5ZTk4ZmJiNWIyYjllZmZhZGYwMGJmNDg0Mjc3IiwiYXVkIjoiYXJpOmNsb3VkOmJpdGJ1Y2tldDo6YXBwL3szMjc3MTNlZC1mMWIyLTQ2NTktOWM5MS1jOGVjZjhiZTdmM2V9L3NvbmFyY2xvdWQtZ3JlZyIsImV4cCI6MTU0MTA2MjIwNX0' | |||
) | |||
).toEqual(claims); | |||
}); | |||
}); | |||
describe('#latinize', () => { | |||
it('should remove diacritics and replace them with normal letters', () => { |
@@ -417,3 +417,10 @@ export function slugify(text: string) { | |||
.replace(/^-+/, '') // Remove heading dash | |||
.replace(/-+$/, ''); // Remove trailing dash | |||
} | |||
export function decodeJwt(token: string) { | |||
const segments = token.split('.'); | |||
const base64Url = segments.length > 1 ? segments[1] : segments[0]; | |||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); | |||
return JSON.parse(window.atob(base64)); | |||
} |