Skip to content
Snippets Groups Projects
Unverified Commit 6ffdbf07 authored by mr-chenguang's avatar mr-chenguang Committed by GitHub
Browse files

feat(dataconnectors): support confluence personal access token (#3206)


* feat(dataconnectors): support confluence personal access token

* fix: change select option

* linting
change name on accesstype field

---------

Co-authored-by: default avatartimothycarambat <rambat1010@gmail.com>
parent 89bba682
No related branches found
No related tags found
No related merge requests found
...@@ -19,18 +19,19 @@ async function loadConfluence( ...@@ -19,18 +19,19 @@ async function loadConfluence(
username = null, username = null,
accessToken = null, accessToken = null,
cloud = true, cloud = true,
personalAccessToken = null,
}, },
response response
) { ) {
if (!baseUrl || !spaceKey || !username || !accessToken) { if (!personalAccessToken && (!username || !accessToken)) {
return { return {
success: false, success: false,
reason: 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 { return {
success: false, success: false,
reason: "Provided base URL is not a valid URL.", reason: "Provided base URL is not a valid URL.",
...@@ -52,6 +53,7 @@ async function loadConfluence( ...@@ -52,6 +53,7 @@ async function loadConfluence(
username, username,
accessToken, accessToken,
cloud, cloud,
personalAccessToken,
}); });
const { docs, error } = await loader const { docs, error } = await loader
......
...@@ -6,6 +6,7 @@ import { Tooltip } from "react-tooltip"; ...@@ -6,6 +6,7 @@ import { Tooltip } from "react-tooltip";
export default function ConfluenceOptions() { export default function ConfluenceOptions() {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [accessType, setAccessType] = useState("username");
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
...@@ -27,6 +28,7 @@ export default function ConfluenceOptions() { ...@@ -27,6 +28,7 @@ export default function ConfluenceOptions() {
username: form.get("username"), username: form.get("username"),
accessToken: form.get("accessToken"), accessToken: form.get("accessToken"),
cloud: form.get("isCloud") === "true", cloud: form.get("isCloud") === "true",
personalAccessToken: form.get("personalAccessToken"),
}); });
if (!!error) { if (!!error) {
...@@ -122,70 +124,129 @@ export default function ConfluenceOptions() { ...@@ -122,70 +124,129 @@ export default function ConfluenceOptions() {
<div className="flex flex-col pr-10"> <div className="flex flex-col pr-10">
<div className="flex flex-col gap-y-1 mb-4"> <div className="flex flex-col gap-y-1 mb-4">
<label className="text-white text-sm font-bold"> <label className="text-white text-sm font-bold">
Confluence Username Confluence Auth Type
</label> </label>
<p className="text-xs font-normal text-theme-text-secondary"> <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> </p>
</div> </div>
<input <select
type="text" name="accessType"
name="username" 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"
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" defaultValue={accessType}
placeholder="jdoe@example.com" onChange={(e) => setAccessType(e.target.value)}
required={true} >
autoComplete="off" {[
spellCheck={false} {
/> 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>
<div className="flex flex-col pr-10"> {accessType === "username" && (
<div className="flex flex-col gap-y-1 mb-4"> <>
<label className="text-white text-sm font-bold flex gap-x-2 items-center"> <div className="flex flex-col pr-10">
<p className="font-bold text-white"> <div className="flex flex-col gap-y-1 mb-4">
Confluence Access Token <label className="text-white text-sm font-bold">
</p> Confluence Username
<Warning </label>
size={14} <p className="text-xs font-normal text-theme-text-secondary">
className="ml-1 text-orange-500 cursor-pointer" Your Confluence username.
data-tooltip-id="access-token-tooltip" </p>
data-tooltip-place="right" </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}
/> />
<Tooltip </div>
delayHide={300} <div className="flex flex-col pr-10">
id="access-token-tooltip" <div className="flex flex-col gap-y-1 mb-4">
className="max-w-xs z-99" <label className="text-white text-sm font-bold flex gap-x-2 items-center">
clickable={true} <p className="font-bold text-white">
> Confluence Access Token
<p className="text-sm"> </p>
You need to provide an access token for authentication. <Warning
You can generate an access token{" "} size={14}
<a className="ml-1 text-orange-500 cursor-pointer"
href="https://id.atlassian.com/manage-profile/security/api-tokens" data-tooltip-id="access-token-tooltip"
target="_blank" data-tooltip-place="right"
rel="noopener noreferrer" />
className="underline" <Tooltip
onClick={(e) => e.stopPropagation()} delayHide={300}
id="access-token-tooltip"
className="max-w-xs z-99"
clickable={true}
> >
here <p className="text-sm">
</a> 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> </p>
</Tooltip> </div>
</label> <input
<p className="text-xs font-normal text-theme-text-secondary"> type="password"
Access token for authentication. name="accessToken"
</p> 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> </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>
</div> </div>
......
...@@ -137,6 +137,7 @@ const DataConnector = { ...@@ -137,6 +137,7 @@ const DataConnector = {
username, username,
accessToken, accessToken,
cloud, cloud,
personalAccessToken,
}) { }) {
return await fetch(`${API_BASE}/ext/confluence`, { return await fetch(`${API_BASE}/ext/confluence`, {
method: "POST", method: "POST",
...@@ -147,6 +148,7 @@ const DataConnector = { ...@@ -147,6 +148,7 @@ const DataConnector = {
username, username,
accessToken, accessToken,
cloud, cloud,
personalAccessToken,
}), }),
}) })
.then((res) => res.json()) .then((res) => res.json())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment