From 97788440c716ccee43c3200345e95b1b4320d533 Mon Sep 17 00:00:00 2001 From: tidbit1 <194808961+tidbit1@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:11:18 +0000 Subject: [PATCH 1/2] set development server port to 3003 --- vite.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vite.config.ts b/vite.config.ts index 187d657..7404bf2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,7 +7,8 @@ export default defineConfig({ base: "", plugins: [react()], server: { - allowedHosts: true + allowedHosts: true, + port: 3003 }, build: { rollupOptions: { From 9525ddd971bf734c52164262613dd8dabdd0c4ca Mon Sep 17 00:00:00 2001 From: tidbit1 <194808961+tidbit1@users.noreply.github.com> Date: Wed, 19 Mar 2025 17:24:23 +0000 Subject: [PATCH 2/2] create admin callback page for local OAuth2 flow --- manifest.json | 51 ++++++++++++++++--- package.json | 2 +- pnpm-lock.yaml | 32 ++++++------ src/App.tsx | 2 + .../AdminCallbackPage/AdminCallbackPage.tsx | 49 ++++++++++++++++++ src/pages/AdminCallbackPage/index.ts | 1 + src/pages/index.ts | 1 + 7 files changed, 113 insertions(+), 25 deletions(-) create mode 100644 src/pages/AdminCallbackPage/AdminCallbackPage.tsx create mode 100644 src/pages/AdminCallbackPage/index.ts diff --git a/manifest.json b/manifest.json index bcb5c15..2d2445d 100644 --- a/manifest.json +++ b/manifest.json @@ -31,6 +31,14 @@ } }, "settings": { + "use_api_key": { + "title": "Use Access Token", + "type": "boolean", + "isRequired": false, + "isBackendOnly": false, + "default": false, + "order": 1 + }, "instance_url": { "title": "Jira Data Center Instance URL", "description": "Enter the URL of your Jira Data Centre instance, e.g. https://my-jira-instance.com", @@ -38,15 +46,41 @@ "type": "string", "isRequired": true, "isBackendOnly": false, - "order": 10 + "order": 2 + }, + "client_id": { + "title": "Client ID", + "type": "string", + "isRequired": false, + "isBackendOnly": false, + "condition": "settings.use_api_key != true", + "order": 3 + }, + "client_secret": { + "title": "Client Secret", + "type": "string", + "isRequired": false, + "isBackendOnly": true, + "condition": "settings.use_api_key != true", + "order": 4 + }, + "callback_url": { + "title": "Callback URL", + "type": "app_embedded", + "options": { "entrypoint": "#/admin/callback", "height": "100px" }, + "isRequired": false, + "isBackendOnly": true, + "condition": "settings.use_api_key != true", + "order": 5 }, "api_key": { "title": "Access Token", "description": "JIRA Data Centre user's access token, please follow the app setup guide to get this", "type": "string", - "isRequired": true, + "isRequired": false, "isBackendOnly": true, - "order": 30 + "condition": "settings.use_api_key != false", + "order": 6 }, "verify_settings": { "title": "", @@ -54,7 +88,8 @@ "options": { "entrypoint": "#/admin/verify_settings", "height": "30px" }, "isRequired": false, "isBackendOnly": false, - "order": 40 + "condition": "settings.use_api_key != false", + "order": 7 }, "default_comment_on_ticket_reply": { "title": "Ticket reply as Jira comment?", @@ -62,7 +97,7 @@ "type": "boolean", "isRequired": false, "isBackendOnly": false, - "order": 50 + "order": 8 }, "default_comment_on_ticket_note": { "title": "Ticket note as Jira comment?", @@ -70,7 +105,7 @@ "type": "boolean", "isRequired": false, "isBackendOnly": false, - "order": 60 + "order": 9 }, "ticket_subject_as_issue_summary": { "title": "Use ticket ID and subject as summary", @@ -78,7 +113,7 @@ "type": "boolean", "isRequired": false, "isBackendOnly": false, - "order": 70 + "order": 10 } }, "proxy": { @@ -90,4 +125,4 @@ } ] } -} +} \ No newline at end of file diff --git a/package.json b/package.json index ea6fefb..83cd645 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "dependencies": { "@atlaskit/adf-utils": "14.4.0", - "@deskpro/app-sdk": "^5.1.1", + "@deskpro/app-sdk": "^6.0.3", "@deskpro/deskpro-ui": "^8.2.0", "@fortawesome/free-regular-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c27621..9c2e7c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: 14.4.0 version: 14.4.0 '@deskpro/app-sdk': - specifier: ^5.1.1 - version: 5.1.1(@deskpro/deskpro-ui@8.2.0(@types/web@0.0.86)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)))(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2) + specifier: ^6.0.3 + version: 6.0.3(@deskpro/deskpro-ui@8.2.0(@types/web@0.0.86)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)))(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2) '@deskpro/deskpro-ui': specifier: ^8.2.0 version: 8.2.0(@types/web@0.0.86)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) @@ -188,7 +188,7 @@ importers: version: 5.7.2 vite: specifier: ^6.0.11 - version: 6.0.11(@types/node@22.10.5)(sass@1.83.1) + version: 6.0.11(@types/node@22.10.5)(sass@1.86.0) packages: @@ -404,8 +404,8 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@deskpro/app-sdk@5.1.1': - resolution: {integrity: sha512-GVwjVb/8EX4aBHtDu7YqWKpVPxslyFy0nAEjbo59hycy73KPqV0UdOCQNM5LasZnrC1U6epV/BYVQrUDplTzuw==} + '@deskpro/app-sdk@6.0.3': + resolution: {integrity: sha512-7IYRxJ6SRCKrsSFO5bZwGYhRoEvX08LPv0pDGIxhNejrqp+eaDb8hjobKnPKwK22pRNJ/riExGPsbGXeSuuCZQ==} engines: {node: '>=20.0.0'} peerDependencies: '@deskpro/deskpro-ui': ^8.0.0 @@ -2416,8 +2416,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - libphonenumber-js@1.11.17: - resolution: {integrity: sha512-Jr6v8thd5qRlOlc6CslSTzGzzQW03uiscab7KHQZX1Dfo4R6n6FDhZ0Hri6/X7edLIDv9gl4VMZXhxTjLnl0VQ==} + libphonenumber-js@1.12.6: + resolution: {integrity: sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2966,8 +2966,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass@1.83.1: - resolution: {integrity: sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==} + sass@1.86.0: + resolution: {integrity: sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==} engines: {node: '>=14.0.0'} hasBin: true @@ -3710,7 +3710,7 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@deskpro/app-sdk@5.1.1(@deskpro/deskpro-ui@8.2.0(@types/web@0.0.86)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)))(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)': + '@deskpro/app-sdk@6.0.3(@deskpro/deskpro-ui@8.2.0(@types/web@0.0.86)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)))(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)': dependencies: '@deskpro/deskpro-ui': 8.2.0(@types/web@0.0.86)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@fortawesome/fontawesome-svg-core': 6.7.2 @@ -3726,7 +3726,7 @@ snapshots: fuse.js: 7.0.0 handlebars: 4.7.7 i18n-iso-countries: 7.13.0 - libphonenumber-js: 1.11.17 + libphonenumber-js: 1.12.6 modern-normalize: 1.1.0 penpal: 6.2.1 react: 18.3.1 @@ -3735,7 +3735,7 @@ snapshots: react-flatpickr: 3.10.7(react@18.3.1) react-intl: 5.25.1(react@18.3.1)(typescript@5.7.2) regenerator-runtime: 0.14.1 - sass: 1.83.1 + sass: 1.86.0 shortcut-buttons-flatpickr: 0.4.0 styled-components: 6.1.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ts-pattern: 4.3.0 @@ -6104,7 +6104,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.11.17: {} + libphonenumber-js@1.12.6: {} lines-and-columns@1.2.4: {} @@ -6661,7 +6661,7 @@ snapshots: safer-buffer@2.1.2: {} - sass@1.83.1: + sass@1.86.0: dependencies: chokidar: 4.0.3 immutable: 5.0.3 @@ -6975,7 +6975,7 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - vite@6.0.11(@types/node@22.10.5)(sass@1.83.1): + vite@6.0.11(@types/node@22.10.5)(sass@1.86.0): dependencies: esbuild: 0.24.2 postcss: 8.4.49 @@ -6983,7 +6983,7 @@ snapshots: optionalDependencies: '@types/node': 22.10.5 fsevents: 2.3.3 - sass: 1.83.1 + sass: 1.86.0 w3c-keyname@2.2.8: {} diff --git a/src/App.tsx b/src/App.tsx index 80ec0da..999e789 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -19,6 +19,7 @@ import { VerifySettingsPage, ViewPermissionsPage, CreateIssueCommentPage, + AdminCallbackPage } from "./pages"; import type { ElementEventPayload } from "./types"; @@ -55,6 +56,7 @@ const App = () => { return ( }/> + }/> }/> }/> }/> diff --git a/src/pages/AdminCallbackPage/AdminCallbackPage.tsx b/src/pages/AdminCallbackPage/AdminCallbackPage.tsx new file mode 100644 index 0000000..90f2e20 --- /dev/null +++ b/src/pages/AdminCallbackPage/AdminCallbackPage.tsx @@ -0,0 +1,49 @@ +import { useState } from 'react'; +import { createSearchParams } from 'react-router-dom'; +import styled from 'styled-components'; +import { CopyToClipboardInput, LoadingSpinner, useInitialisedDeskproAppClient } from '@deskpro/app-sdk'; +import { P1 } from '@deskpro/deskpro-ui'; + +const Description = styled(P1)` + margin-top: 8px; + color: ${({ theme }) => theme.colors.grey80}; +`; + +export function AdminCallbackPage() { + const [callbackURL, setCallbackURL] = useState(null); + + useInitialisedDeskproAppClient(client => { + client.startOauth2Local( + ({ callbackUrl, state }) => { + setCallbackURL(callbackUrl); + + return `https://auth.atlassian.com/authorize?${createSearchParams([ + ['client_id', 'clientID'], + ['state', state], + ['audience', 'api.atlassian.com'], + ['scope', ''], + ['prompt', 'consent'], + ['response_type', 'code'], + ['redirect_uri', callbackUrl] + ])}`; + }, + /^$/, + async () => ({data: {access_token: ''}}), + { + pollInterval: 10000, + timeout: 600 + } + ); + }, []); + + if (!callbackURL) { + return + }; + + return ( + <> + + The callback URL will be required during Jira Data Center setup + + ); +}; \ No newline at end of file diff --git a/src/pages/AdminCallbackPage/index.ts b/src/pages/AdminCallbackPage/index.ts new file mode 100644 index 0000000..b413683 --- /dev/null +++ b/src/pages/AdminCallbackPage/index.ts @@ -0,0 +1 @@ +export { AdminCallbackPage } from './AdminCallbackPage'; \ No newline at end of file diff --git a/src/pages/index.ts b/src/pages/index.ts index 974f412..bf1d97e 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -7,3 +7,4 @@ export { LoadingAppPage } from "./LoadingAppPage"; export { VerifySettingsPage } from "./VerifySettingsPage"; export { ViewPage } from "./ViewPage"; export { ViewPermissionsPage } from "./ViewPermissionsPage"; +export { AdminCallbackPage } from './AdminCallbackPage'; \ No newline at end of file