From 845e225d64423a377dd80055dbeb0621080bae2a Mon Sep 17 00:00:00 2001 From: bwieger-atlassian-com Date: Wed, 12 Feb 2025 11:25:19 -0800 Subject: [PATCH 1/3] AXON-113: Fix Bitbucket DC 8.0 and later bugs with 404s (#106) * Can open a PR * task can be created, editted, and deleted * task now show up properly * refactors to be pretty * small fixes * nits * nits * nits --- .../bitbucket-server/pullRequests.ts | 157 +++++++++++++++++- src/bitbucket/model.ts | 1 + 2 files changed, 156 insertions(+), 2 deletions(-) diff --git a/src/bitbucket/bitbucket-server/pullRequests.ts b/src/bitbucket/bitbucket-server/pullRequests.ts index 9082a053..344b812c 100644 --- a/src/bitbucket/bitbucket-server/pullRequests.ts +++ b/src/bitbucket/bitbucket-server/pullRequests.ts @@ -180,8 +180,38 @@ export class ServerPullRequestApi implements PullRequestApi { } async getTasks(pr: PullRequest): Promise { + try { + return this.getTasks_v8(pr); + } catch (error) { + if (error.message && error.message['status-code'] === 404) { + return this.getTasks_v0(pr); + } else { + throw error; + } + } + } + + private async getTasks_v8(pr: PullRequest) { const { ownerSlug, repoSlug } = pr.site; + let { data } = await this.client.get( + `/rest/api/1.0/projects/${ownerSlug}/repos/${repoSlug}/pull-requests/${pr.data.id}/blocker-comments`, + ); + if (!data.values) { + return []; + } + const accumulatedTasks = data.values as any[]; + while (data.next) { + const nextPage = await this.client.get(data.next); + data = nextPage.data; + accumulatedTasks.push(...(data.values || [])); + } + + return accumulatedTasks.map((task: any) => this.convertDataToTask_v8(task, pr.site)); + } + + private async getTasks_v0(pr: PullRequest) { + const { ownerSlug, repoSlug } = pr.site; let { data } = await this.client.get( `/rest/api/1.0/projects/${ownerSlug}/repos/${repoSlug}/pull-requests/${pr.data.id}/tasks`, ); @@ -201,9 +231,22 @@ export class ServerPullRequestApi implements PullRequestApi { } async postTask(site: BitbucketSite, prId: string, content: string, commentId?: string): Promise { + try { + return this.postTask_v8(site, prId, content, commentId); + } catch (error) { + if (error.message && error.message['status-code'] === 404) { + // Retry with the legacy endpoint + return this.postTask_v0(site, prId, content, commentId); + } else { + throw error; + } + } + } + + private async postTask_v0(site: BitbucketSite, prId: string, content: string, commentId?: string) { const bbApi = await clientForSite(site); const repo = await bbApi.repositories.get(site); - let { data } = await this.client.post(`/rest/api/latest/tasks`, { + const { data } = await this.client.post(`/rest/api/latest/tasks`, { anchor: { id: commentId, type: 'COMMENT', @@ -218,7 +261,57 @@ export class ServerPullRequestApi implements PullRequestApi { return this.convertDataToTask(data, site); } + + private async postTask_v8(site: BitbucketSite, prId: string, content: string, commentId?: string) { + const bbApi = await clientForSite(site); + const repo = await bbApi.repositories.get(site); + const ownerSlug = site.ownerSlug; + const data = await this.client.post( + `/rest/api/latest/projects/${ownerSlug}/repos/${repo.name}/pull-requests/${prId}/comments`, + { + id: commentId, + state: 'OPEN', + version: 1, + severity: 'BLOCKER', + text: content, + properties: {}, + }, + ); + return this.convertDataToTask_v8(data.data, site); + } + async editTask(site: BitbucketSite, prId: string, task: Task): Promise { + try { + return this.editTask_v8(site, prId, task); + } catch (error) { + if (error.message && error.message['status-code'] === 404) { + return this.editTask_v0(site, prId, task); + } else { + throw error; + } + } + } + + private async editTask_v8(site: BitbucketSite, pullRequestId: string, task: Task) { + const projectKey = site.ownerSlug; + const repositorySlug = site.repoSlug; + const commentId = task.commentId; + const { data } = await this.client.put( + `/rest/api/1.0/projects/${projectKey}/repos/${repositorySlug}/pull-requests/${pullRequestId}/comments/${commentId}`, + { + id: task.id, + state: task.isComplete ? 'RESOLVED' : 'OPEN', + version: task.version, + severity: 'BLOCKER', + text: task.content, + properties: {}, + }, + ); + + return this.convertDataToTask_v8(data, site); + } + + private async editTask_v0(site: BitbucketSite, prId: string, task: Task) { const { data } = await this.client.put(`/rest/api/1.0/tasks/${task.id}`, { id: task.id, text: task.content, @@ -229,9 +322,50 @@ export class ServerPullRequestApi implements PullRequestApi { } async deleteTask(site: BitbucketSite, prId: string, task: Task): Promise { + try { + return this.deleteTask_v8(site, prId, task); + } catch (error) { + if (error.message && error.message['status-code'] === 404) { + return this.deleteTask_v0(site, prId, task); + } else { + throw error; + } + } + } + + private async deleteTask_v8(site: BitbucketSite, pullRequestId: string, task: Task) { + const projectKey = site.ownerSlug; + const repositorySlug = site.repoSlug; + const commentId = task.commentId; + + await this.client.delete( + `/rest/api/1.0/projects/${projectKey}/repos/${repositorySlug}/pull-requests/${pullRequestId}/comments/${commentId}`, + {}, + { version: task.version }, + ); + } + + private async deleteTask_v0(site: BitbucketSite, prId: string, task: Task) { await this.client.delete(`/rest/api/1.0/tasks/${task.id}`, {}); } + convertDataToTask_v8(taskData: any, site: BitbucketSite): Task { + const user = taskData.author ? ServerPullRequestApi.toUser(site.details, taskData.author) : UnknownUser; + const taskBelongsToUser: boolean = user.accountId === site.details.userId; + return { + commentId: taskData.id, + creator: ServerPullRequestApi.toUser(site.details, taskData.author), + created: taskData.createdDate, + updated: taskData.updatedDate, + isComplete: taskData.state !== 'OPEN', + editable: taskBelongsToUser && taskData.permittedOperations.editable, + deletable: taskBelongsToUser && taskData.permittedOperations.deletable, + id: taskData.id, + content: taskData.text, + version: taskData.version, + }; + } + convertDataToTask(taskData: any, site: BitbucketSite): Task { const user = taskData.author ? ServerPullRequestApi.toUser(site.details, taskData.author) : UnknownUser; const taskBelongsToUser: boolean = user.accountId === site.details.userId; @@ -785,8 +919,20 @@ export class ServerPullRequestApi implements PullRequestApi { } private async getTaskCount(site: BitbucketSite, prId: string): Promise { - const { ownerSlug, repoSlug } = site; + try { + return this.getTaskCount_v8(site, prId); + } catch (error) { + if (error.message && error.message['status-code'] === 404) { + // Retry with the legacy endpoint + return this.getTaskCount_v0(site, prId); + } else { + throw error; + } + } + } + private async getTaskCount_v0(site: BitbucketSite, prId: string): Promise { + const { ownerSlug, repoSlug } = site; const { data } = await this.client.get( `/rest/api/1.0/projects/${ownerSlug}/repos/${repoSlug}/pull-requests/${prId}/tasks/count`, ); @@ -794,6 +940,13 @@ export class ServerPullRequestApi implements PullRequestApi { return data; } + private getTaskCount_v8(site: BitbucketSite, prId: string): number | PromiseLike { + const { ownerSlug, repoSlug } = site; + return this.client.get( + `/rest/api/1.0/projects/${ownerSlug}/repos/${repoSlug}/pull-requests/${prId}/blocker-comments?count=true`, + ); + } + static toUser(site: DetailedSiteInfo, input: any): User { return { accountId: input.slug!, diff --git a/src/bitbucket/model.ts b/src/bitbucket/model.ts index f7d6b951..3a9e21ac 100644 --- a/src/bitbucket/model.ts +++ b/src/bitbucket/model.ts @@ -81,6 +81,7 @@ export type Task = { editable: boolean; deletable: boolean; content: string; + version?: number; }; export type Comment = { From 7ecc8dac29fea9a75c01ab081158c3ea1a7e1f36 Mon Sep 17 00:00:00 2001 From: bwieger-atlassian-com Date: Wed, 12 Feb 2025 11:38:35 -0800 Subject: [PATCH 2/3] changelog 3.4.5 (#108) --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161cfb82..24269094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## What's new in 3.4.5 + +### Bug Fixes + +- Fixed bitbucket PR erroring out due to deprecated API being used + ## What's new in 3.4.4 ### Bug Fixes From 14ef8970bbc7d7915f4cd6ee7cf8b0be32ce9bfd Mon Sep 17 00:00:00 2001 From: Stan Dzhumaev Date: Thu, 13 Feb 2025 10:33:04 -0800 Subject: [PATCH 3/3] [AXON-46] chore: add unit tests for auth strategies (to avoid creating problems when changing this code) --- package-lock.json | 822 +++---------------------------- package.json | 3 +- src/atlclients/strategy.test.ts | 105 ++++ src/atlclients/strategy.ts | 24 +- src/atlclients/strategyCrypto.ts | 20 + 5 files changed, 193 insertions(+), 781 deletions(-) create mode 100644 src/atlclients/strategy.test.ts create mode 100644 src/atlclients/strategyCrypto.ts diff --git a/package-lock.json b/package-lock.json index 2f14df73..297074a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,6 +126,7 @@ }, "devDependencies": { "@babel/core": "^7.25.0", + "@jest/globals": "^29.7.0", "@stylistic/eslint-plugin-js": "^2.8.0", "@types/analytics-node": "^3.1.7", "@types/chai": "^4", @@ -135,7 +136,7 @@ "@types/git-url-parse": "^9.0.1", "@types/glob": "^7.1.1", "@types/html-webpack-plugin": "^3.2.2", - "@types/jest": "^25.1.3", + "@types/jest": "^29.5.14", "@types/jquery": "^3.3.23", "@types/lodash.debounce": "^4.0.6", "@types/lodash.orderby": "^4.6.6", @@ -5447,35 +5448,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/@jest/core/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -5687,35 +5659,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/environment/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/environment/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/environment/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/@jest/environment/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -5788,6 +5731,7 @@ "resolved": "https://packages.atlassian.com/api/npm/npm-remote/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -5981,35 +5925,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/reporters/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/@jest/reporters/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -6180,35 +6095,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-sequencer/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/test-sequencer/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/@jest/test-sequencer/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -7210,13 +7096,6 @@ "@types/node": "*" } }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/connect": { "version": "3.4.33", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", @@ -7427,26 +7306,15 @@ "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, "node_modules/@types/jest": { - "version": "25.1.4", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.4.tgz", - "integrity": "sha512-QDDY2uNAhCV7TMCITrxz+MRk1EizcsevzfeS6LykIlq2V1E5oO4wXG8V2ZEd9w7Snxeeagk46YbMgZ8ESHx3sw==", + "version": "29.5.14", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-diff": "^25.1.0", - "pretty-format": "^25.1.0" + "expect": "^29.0.0", + "pretty-format": "^29.0.0" } }, "node_modules/@types/jquery": { @@ -11905,35 +11773,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/create-jest/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/create-jest/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/create-jest/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/create-jest/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -13564,16 +13403,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.3" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/dir-glob/-/dir-glob-3.0.1.tgz", @@ -15331,15 +15160,6 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/expect/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/color-convert/-/color-convert-2.0.1.tgz", @@ -15430,26 +15250,6 @@ "node": ">=10" } }, - "node_modules/expect/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/expect/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/expect/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -18660,35 +18460,6 @@ "node": ">=10" } }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-circus/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-circus/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -18967,35 +18738,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-cli/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-cli/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-cli/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -19101,59 +18843,64 @@ "node": ">=12" } }, - "node_modules/jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, - "license": "MIT", "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 8.3" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/jest-diff/node_modules/color-convert": { + "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -19161,110 +18908,15 @@ "node": ">=7.0.0" } }, - "node_modules/jest-diff/node_modules/color-name": { + "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" + "dev": true }, - "node_modules/jest-diff/node_modules/has-flag": { + "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/has-flag/-/has-flag-4.0.0.tgz", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { @@ -19280,35 +18932,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-each/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/supports-color/-/supports-color-7.2.0.tgz", @@ -19447,35 +19070,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-environment-node/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-environment-node/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -19509,16 +19103,6 @@ "node": ">=8" } }, - "node_modules/jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8.3" - } - }, "node_modules/jest-haste-map": { "version": "29.7.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-haste-map/-/jest-haste-map-29.7.0.tgz", @@ -19557,15 +19141,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-leak-detector/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-leak-detector/node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -19575,26 +19150,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-matcher-utils": { "version": "29.7.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", @@ -19695,35 +19250,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/supports-color/-/supports-color-7.2.0.tgz", @@ -20029,35 +19555,6 @@ "node": ">=10" } }, - "node_modules/jest-runner/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-runner/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-runner/node_modules/source-map": { "version": "0.6.1", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/source-map/-/source-map-0.6.1.tgz", @@ -20298,35 +19795,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-runtime/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-runtime/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -20511,35 +19979,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-snapshot/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -20750,35 +20189,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-validate/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/supports-color/-/supports-color-7.2.0.tgz", @@ -20920,35 +20330,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-watcher/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-watcher/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watcher/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, "node_modules/jest-watcher/node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://packages.atlassian.com/api/npm/npm-remote/stack-utils/-/stack-utils-2.0.6.tgz", @@ -25005,121 +24386,40 @@ } }, "node_modules/pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^25.1.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/pretty-format/node_modules/@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "29.7.0", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 8.3" - } - }, - "node_modules/pretty-format/node_modules/@types/yargs": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", - "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "5.2.0", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-format/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/pretty-format/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://packages.atlassian.com/api/npm/npm-remote/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, "license": "MIT" }, - "node_modules/pretty-format/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/pretty-quick": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.1.tgz", diff --git a/package.json b/package.json index 1e8c2fe5..39b69d86 100644 --- a/package.json +++ b/package.json @@ -1486,6 +1486,7 @@ }, "devDependencies": { "@babel/core": "^7.25.0", + "@jest/globals": "^29.7.0", "@stylistic/eslint-plugin-js": "^2.8.0", "@types/analytics-node": "^3.1.7", "@types/chai": "^4", @@ -1495,7 +1496,7 @@ "@types/git-url-parse": "^9.0.1", "@types/glob": "^7.1.1", "@types/html-webpack-plugin": "^3.2.2", - "@types/jest": "^25.1.3", + "@types/jest": "^29.5.14", "@types/jquery": "^3.3.23", "@types/lodash.debounce": "^4.0.6", "@types/lodash.orderby": "^4.6.6", diff --git a/src/atlclients/strategy.test.ts b/src/atlclients/strategy.test.ts new file mode 100644 index 00000000..348f435a --- /dev/null +++ b/src/atlclients/strategy.test.ts @@ -0,0 +1,105 @@ +jest.mock('./strategyCrypto', () => { + return { + createVerifier: jest.fn(() => 'verifier'), + base64URLEncode: jest.fn(() => 'base64URLEncode'), + sha256: jest.fn(() => 'sha256'), + basicAuth: jest.fn(() => 'basicAuth'), + }; +}); + +import { OAuthProvider } from './authInfo'; +import { strategyForProvider } from './strategy'; + +// it.each is not found without this: +import { it } from '@jest/globals'; + +const expectedData = { + bbcloud: { + provider: 'bbcloud', + authorizeUrl: + 'https://bitbucket.org/site/oauth2/authorize?client_id=3hasX42a7Ugka2FJja&response_type=code&state=state', + accessibleResourcesUrl: '', + tokenAuthorizationData: 'grant_type=authorization_code&code=code', + tokenUrl: 'https://bitbucket.org/site/oauth2/access_token', + apiUrl: 'https://bitbucket.org', + refreshHeaders: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: 'basicAuth', + }, + tokenRefreshData: 'grant_type=refresh_token&refresh_token=refreshToken', + profileUrl: 'https://api.bitbucket.org/2.0/user', + emailsUrl: 'https://api.bitbucket.org/2.0/user/emails', + }, + bbcloudstaging: { + provider: 'bbcloudstaging', + authorizeUrl: + 'https://staging.bb-inf.net/site/oauth2/authorize?client_id=7jspxC7fgemuUbnWQL&response_type=code&state=state', + accessibleResourcesUrl: '', + tokenAuthorizationData: 'grant_type=authorization_code&code=code', + tokenUrl: 'https://staging.bb-inf.net/site/oauth2/access_token', + apiUrl: 'https://staging.bb-inf.net', + refreshHeaders: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: 'basicAuth', + }, + tokenRefreshData: 'grant_type=refresh_token&refresh_token=refreshToken', + profileUrl: 'https://api-staging.bb-inf.net/2.0/user', + emailsUrl: 'https://api-staging.bb-inf.net/2.0/user/emails', + }, + jiracloud: { + provider: 'jiracloud', + authorizeUrl: + 'https://auth.atlassian.com/authorize?client_id=bJChVgBQd0aNUPuFZ8YzYBVZz3X4QTe2&redirect_uri=http%3A%2F%2F127.0.0.1%3A31415%2Fjiracloud&response_type=code&scope=read%3Ajira-user+read%3Ajira-work+write%3Ajira-work+offline_access+manage%3Ajira-project&audience=api.atlassian.com&prompt=consent&state=state&code_challenge=base64URLEncode&code_challenge_method=S256', + accessibleResourcesUrl: 'https://api.atlassian.com/oauth/token/accessible-resources', + tokenAuthorizationData: + '{"grant_type":"authorization_code","code":"code","redirect_uri":"http://127.0.0.1:31415/jiracloud","client_id":"bJChVgBQd0aNUPuFZ8YzYBVZz3X4QTe2","code_verifier":"verifier"}', + tokenUrl: 'https://auth.atlassian.com/oauth/token', + apiUrl: 'api.atlassian.com', + refreshHeaders: { + 'Content-Type': 'application/json', + }, + tokenRefreshData: + '{"grant_type":"refresh_token","client_id":"bJChVgBQd0aNUPuFZ8YzYBVZz3X4QTe2","refresh_token":"refreshToken"}', + profileUrl: '', + emailsUrl: '', + }, + jiracloudstaging: { + provider: 'jiracloudstaging', + authorizeUrl: + 'https://auth.stg.atlassian.com/authorize?client_id=pmzXmUav3Rr5XEL0Sie7Biec0WGU8BKg&redirect_uri=http%3A%2F%2F127.0.0.1%3A31415%2Fjiracloudstaging&response_type=code&scope=read%3Ajira-user+read%3Ajira-work+write%3Ajira-work+offline_access+manage%3Ajira-project&audience=api.stg.atlassian.com&prompt=consent&state=state&code_challenge=base64URLEncode&code_challenge_method=S256', + accessibleResourcesUrl: 'https://api.stg.atlassian.com/oauth/token/accessible-resources', + tokenAuthorizationData: + '{"grant_type":"authorization_code","code":"code","redirect_uri":"http://127.0.0.1:31415/jiracloudstaging","client_id":"pmzXmUav3Rr5XEL0Sie7Biec0WGU8BKg","code_verifier":"verifier"}', + tokenUrl: 'https://auth.stg.atlassian.com/oauth/token', + apiUrl: 'api.stg.atlassian.com', + refreshHeaders: { + 'Content-Type': 'application/json', + }, + tokenRefreshData: + '{"grant_type":"refresh_token","client_id":"pmzXmUav3Rr5XEL0Sie7Biec0WGU8BKg","refresh_token":"refreshToken"}', + profileUrl: '', + emailsUrl: '', + }, +}; + +describe('Authentication strategies', () => { + it.each([ + [OAuthProvider.BitbucketCloud], + [OAuthProvider.BitbucketCloudStaging], + [OAuthProvider.JiraCloud], + [OAuthProvider.JiraCloudStaging], + ])('Strategy for provider %s yields expected results', (provider: OAuthProvider) => { + const expected = expectedData[provider] as any; + const strategy = strategyForProvider(provider); + expect(strategy.provider()).toBe(expected.provider); + expect(strategy.authorizeUrl('state')).toBe(expected.authorizeUrl); + expect(strategy.accessibleResourcesUrl()).toBe(expected.accessibleResourcesUrl); + expect(strategy.tokenAuthorizationData('code')).toBe(expected.tokenAuthorizationData); + expect(strategy.tokenUrl()).toBe(expected.tokenUrl); + expect(strategy.apiUrl()).toBe(expected.apiUrl); + expect(strategy.refreshHeaders()).toStrictEqual(expected.refreshHeaders); + expect(strategy.tokenRefreshData('refreshToken')).toBe(expected.tokenRefreshData); + expect(strategy.profileUrl()).toBe(expected.profileUrl); + expect(strategy.emailsUrl()).toBe(expected.emailsUrl); + }); +}); diff --git a/src/atlclients/strategy.ts b/src/atlclients/strategy.ts index 1e3ce36b..cd9c3da5 100644 --- a/src/atlclients/strategy.ts +++ b/src/atlclients/strategy.ts @@ -1,5 +1,5 @@ import { OAuthProvider } from './authInfo'; -import crypto from 'crypto'; +import { createVerifier, base64URLEncode, sha256, basicAuth } from './strategyCrypto'; const JiraProdStrategyData = { clientID: 'bJChVgBQd0aNUPuFZ8YzYBVZz3X4QTe2', @@ -90,7 +90,7 @@ class PKCEJiraProdStrategy extends Strategy { public constructor() { super(); - this.verifier = base64URLEncode(crypto.randomBytes(32)); + this.verifier = createVerifier(); } public provider(): OAuthProvider { @@ -151,20 +151,12 @@ class PKCEJiraProdStrategy extends Strategy { } } -function base64URLEncode(str: Buffer): string { - return str.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); -} - -function sha256(buffer: any) { - return crypto.createHash('sha256').update(buffer).digest(); -} - class PKCEJiraStagingStrategy extends Strategy { private verifier: string; public constructor() { super(); - this.verifier = base64URLEncode(crypto.randomBytes(32)); + this.verifier = createVerifier(); } public provider(): OAuthProvider { @@ -258,12 +250,9 @@ class BitbucketProdStrategy extends Strategy { // We kinda abuse refreshHeaders for bitbucket. Maybe have a authorizationHeaders as well? Just rename? public refreshHeaders() { - const basicAuth = Buffer.from( - `${BitbucketProdStrategyData.clientID}:${BitbucketProdStrategyData.clientSecret}`, - ).toString('base64'); return { 'Content-Type': 'application/x-www-form-urlencoded', - Authorization: `Basic ${basicAuth}`, + Authorization: basicAuth(BitbucketProdStrategyData.clientID, BitbucketProdStrategyData.clientSecret), }; } @@ -311,12 +300,9 @@ class BitbucketStagingStrategy extends Strategy { } public refreshHeaders() { - const basicAuth = Buffer.from( - `${BitbucketStagingStrategyData.clientID}:${BitbucketStagingStrategyData.clientSecret}`, - ).toString('base64'); return { 'Content-Type': 'application/x-www-form-urlencoded', - Authorization: `Basic ${basicAuth}`, + Authorization: basicAuth(BitbucketStagingStrategyData.clientID, BitbucketStagingStrategyData.clientSecret), }; } diff --git a/src/atlclients/strategyCrypto.ts b/src/atlclients/strategyCrypto.ts new file mode 100644 index 00000000..1755f9a2 --- /dev/null +++ b/src/atlclients/strategyCrypto.ts @@ -0,0 +1,20 @@ +import crypto from 'crypto'; + +// for some reason jest doesn't play nice with crypto, +// so these are now in a separate file for easy mocking + +export function createVerifier() { + return base64URLEncode(crypto.randomBytes(32)); +} + +export function base64URLEncode(str: Buffer): string { + return str.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); +} + +export function sha256(buffer: any) { + return crypto.createHash('sha256').update(buffer).digest(); +} + +export function basicAuth(username: string, password: string) { + return 'Basic ' + Buffer.from(username + ':' + password).toString('base64'); +}