这是indexloc提供的服务,不要输入任何密码
Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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="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"
{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="jdoe@example.com"
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