Skip to content

Commit

Permalink
feat(dataconnectors): support confluence personal access token (#3206)
Browse files Browse the repository at this point in the history
* feat(dataconnectors): support confluence personal access token

* fix: change select option

* linting
change name on accesstype field

---------

Co-authored-by: timothycarambat <[email protected]>
  • Loading branch information
lcgash and timothycarambat authored Feb 14, 2025
1 parent 89bba68 commit 6ffdbf0
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 58 deletions.
8 changes: 5 additions & 3 deletions collector/utils/extensions/Confluence/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand All @@ -52,6 +53,7 @@ async function loadConfluence(
username,
accessToken,
cloud,
personalAccessToken,
});

const { docs, error } = await loader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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) {
Expand Down Expand Up @@ -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="[email protected]"
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"
{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>
</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="[email protected]"
required={true}
autoComplete="off"
spellCheck={false}
/>
<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()}
</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}
>
here
</a>
.
<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>
</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>

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/models/dataConnector.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ const DataConnector = {
username,
accessToken,
cloud,
personalAccessToken,
}) {
return await fetch(`${API_BASE}/ext/confluence`, {
method: "POST",
Expand All @@ -147,6 +148,7 @@ const DataConnector = {
username,
accessToken,
cloud,
personalAccessToken,
}),
})
.then((res) => res.json())
Expand Down

0 comments on commit 6ffdbf0

Please sign in to comment.