diff --git a/collector/utils/extensions/Confluence/index.js b/collector/utils/extensions/Confluence/index.js index e0699222a..4d17d56be 100644 --- a/collector/utils/extensions/Confluence/index.js +++ b/collector/utils/extensions/Confluence/index.js @@ -19,18 +19,19 @@ async function loadConfluence( username = null, accessToken = null, cloud = true, + personalAccessToken = null, }, response ) { - if (!baseUrl || !spaceKey || !username || !accessToken) { + if (!personalAccessToken && (!username || !accessToken)) { return { success: false, reason: - "You need either a username and access token, or a personal access token (PAT), to use the Confluence connector.", + "You need either a personal access token (PAT), or a username and access token to use the Confluence connector.", }; } - if (!validBaseUrl(baseUrl)) { + if (!baseUrl || !validBaseUrl(baseUrl)) { return { success: false, reason: "Provided base URL is not a valid URL.", @@ -52,6 +53,7 @@ async function loadConfluence( username, accessToken, cloud, + personalAccessToken, }); const { docs, error } = await loader diff --git a/frontend/src/components/Modals/ManageWorkspace/DataConnectors/Connectors/Confluence/index.jsx b/frontend/src/components/Modals/ManageWorkspace/DataConnectors/Connectors/Confluence/index.jsx index 620444201..5f63812c8 100644 --- a/frontend/src/components/Modals/ManageWorkspace/DataConnectors/Connectors/Confluence/index.jsx +++ b/frontend/src/components/Modals/ManageWorkspace/DataConnectors/Connectors/Confluence/index.jsx @@ -6,6 +6,7 @@ import { Tooltip } from "react-tooltip"; export default function ConfluenceOptions() { const [loading, setLoading] = useState(false); + const [accessType, setAccessType] = useState("username"); const handleSubmit = async (e) => { e.preventDefault(); @@ -27,6 +28,7 @@ export default function ConfluenceOptions() { username: form.get("username"), accessToken: form.get("accessToken"), cloud: form.get("isCloud") === "true", + personalAccessToken: form.get("personalAccessToken"), }); if (!!error) { @@ -122,70 +124,129 @@ export default function ConfluenceOptions() { <div className="flex flex-col pr-10"> <div className="flex flex-col gap-y-1 mb-4"> <label className="text-white text-sm font-bold"> - Confluence Username + Confluence Auth Type </label> <p className="text-xs font-normal text-theme-text-secondary"> - Your Confluence username. + Your Confluence authentication type, eg: username and access + token / personal access token. </p> </div> - <input - type="text" - name="username" - className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" - placeholder="jdoe@example.com" - required={true} - autoComplete="off" - spellCheck={false} - /> + <select + name="accessType" + className="border-none bg-theme-settings-input-bg w-fit mt-2 px-4 border-gray-500 text-white text-sm rounded-lg block py-2" + defaultValue={accessType} + onChange={(e) => setAccessType(e.target.value)} + > + {[ + { + name: "Username and Access Token", + value: "username", + }, + { + name: "Personal Access Token", + value: "personalToken", + }, + ].map((type) => { + return ( + <option key={type.value} value={type.value}> + {type.name} + </option> + ); + })} + </select> </div> - <div className="flex flex-col pr-10"> - <div className="flex flex-col gap-y-1 mb-4"> - <label className="text-white text-sm font-bold flex gap-x-2 items-center"> - <p className="font-bold text-white"> - Confluence Access Token - </p> - <Warning - size={14} - className="ml-1 text-orange-500 cursor-pointer" - data-tooltip-id="access-token-tooltip" - data-tooltip-place="right" - /> - <Tooltip - delayHide={300} - id="access-token-tooltip" - className="max-w-xs z-99" - clickable={true} - > - <p className="text-sm"> - You need to provide an access token for authentication. - You can generate an access token{" "} - <a - href="https://id.atlassian.com/manage-profile/security/api-tokens" - target="_blank" - rel="noopener noreferrer" - className="underline" - onClick={(e) => e.stopPropagation()} - > - here - </a> - . + {accessType === "username" && ( + <> + <div className="flex flex-col pr-10"> + <div className="flex flex-col gap-y-1 mb-4"> + <label className="text-white text-sm font-bold"> + Confluence Username + </label> + <p className="text-xs font-normal text-theme-text-secondary"> + Your Confluence username. </p> - </Tooltip> - </label> - <p className="text-xs font-normal text-theme-text-secondary"> - Access token for authentication. - </p> + </div> + <input + type="text" + name="username" + className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" + placeholder="jdoe@example.com" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + <div className="flex flex-col pr-10"> + <div className="flex flex-col gap-y-1 mb-4"> + <label className="text-white text-sm font-bold flex gap-x-2 items-center"> + <p className="font-bold text-white"> + Confluence Access Token + </p> + <Warning + size={14} + className="ml-1 text-orange-500 cursor-pointer" + data-tooltip-id="access-token-tooltip" + data-tooltip-place="right" + /> + <Tooltip + delayHide={300} + id="access-token-tooltip" + className="max-w-xs z-99" + clickable={true} + > + <p className="text-sm"> + You need to provide an access token for + authentication. You can generate an access token{" "} + <a + href="https://id.atlassian.com/manage-profile/security/api-tokens" + target="_blank" + rel="noopener noreferrer" + className="underline" + onClick={(e) => e.stopPropagation()} + > + here + </a> + . + </p> + </Tooltip> + </label> + <p className="text-xs font-normal text-theme-text-secondary"> + Access token for authentication. + </p> + </div> + <input + type="password" + name="accessToken" + className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" + placeholder="abcd1234" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + </> + )} + {accessType === "personalToken" && ( + <div className="flex flex-col pr-10"> + <div className="flex flex-col gap-y-1 mb-4"> + <label className="text-white text-sm font-bold"> + Confluence Personal Access Token + </label> + <p className="text-xs font-normal text-theme-text-secondary"> + Your Confluence personal access token. + </p> + </div> + <input + type="password" + name="personalAccessToken" + className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" + placeholder="abcd1234" + required={true} + autoComplete="off" + spellCheck={false} + /> </div> - <input - type="password" - name="accessToken" - className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" - placeholder="abcd1234" - required={true} - autoComplete="off" - spellCheck={false} - /> - </div> + )} </div> </div> diff --git a/frontend/src/models/dataConnector.js b/frontend/src/models/dataConnector.js index 30c17fb12..b35b5ff90 100644 --- a/frontend/src/models/dataConnector.js +++ b/frontend/src/models/dataConnector.js @@ -137,6 +137,7 @@ const DataConnector = { username, accessToken, cloud, + personalAccessToken, }) { return await fetch(`${API_BASE}/ext/confluence`, { method: "POST", @@ -147,6 +148,7 @@ const DataConnector = { username, accessToken, cloud, + personalAccessToken, }), }) .then((res) => res.json())