Skip to content

Commit 32f4804

Browse files
committed
Add optional GitHub token support for authenticated attachment downloads
- Updated `downloadFile` to include an authorization header when a GitHub token is provided and URLs are GitHub-related. - Modified `downloadAttachmentsAndRewriteText` and related calls to accept an optional `githubToken`. - Adjusted `prepareJunieTask` and `getValidatedTextTask` to propagate the token where necessary.
1 parent 86b1fcb commit 32f4804

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

src/github/junie/attachment-downloader.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@ export const ATTACHMENT_PATTERNS = {
1515
legacy: /https:\/\/user-images\.githubusercontent\.com\/[^\s)]+/g
1616
} as const;
1717

18-
async function downloadFile(url: string): Promise<string> {
19-
const response = await fetch(url);
18+
async function downloadFile(url: string, githubToken?: string): Promise<string> {
19+
// Add authentication header for GitHub URLs
20+
const headers: Record<string, string> = {};
21+
if (githubToken && (url.includes('github.com') || url.includes('githubusercontent.com'))) {
22+
headers['Authorization'] = `token ${githubToken}`;
23+
}
24+
25+
const response = await fetch(url, { headers });
2026
if (!response.ok) {
2127
throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`);
2228
}
@@ -54,16 +60,19 @@ async function downloadFile(url: string): Promise<string> {
5460
* - Markdown images: ![](https://github.com/user-attachments/assets/...)
5561
* - Markdown files: (https://github.com/user-attachments/files/...)
5662
* - Legacy images: https://user-images.githubusercontent.com/...
63+
*
64+
* @param text - Text containing attachment URLs
65+
* @param githubToken - GitHub token for authenticating downloads from GitHub
5766
*/
58-
export async function downloadAttachmentsAndRewriteText(text: string): Promise<string> {
67+
export async function downloadAttachmentsAndRewriteText(text: string, githubToken?: string): Promise<string> {
5968
let updatedText = text;
6069

6170
// Handle HTML image tags with user-attachments URLs
6271
const imgMatches = [...text.matchAll(ATTACHMENT_PATTERNS.imgTag)];
6372
for (const match of imgMatches) {
6473
const url = match[1];
6574
try {
66-
const localPath = await downloadFile(url);
75+
const localPath = await downloadFile(url, githubToken);
6776
updatedText = updatedText.replace(match[0], `src="${localPath}"`);
6877
} catch (error) {
6978
console.error(`Failed to download image: ${url}`, error);
@@ -75,7 +84,7 @@ export async function downloadAttachmentsAndRewriteText(text: string): Promise<s
7584
for (const match of mdImgMatches) {
7685
const url = match[1];
7786
try {
78-
const localPath = await downloadFile(url);
87+
const localPath = await downloadFile(url, githubToken);
7988
updatedText = updatedText.replace(match[1], localPath);
8089
} catch (error) {
8190
console.error(`Failed to download markdown image: ${url}`, error);
@@ -87,7 +96,7 @@ export async function downloadAttachmentsAndRewriteText(text: string): Promise<s
8796
for (const match of fileMatches) {
8897
const url = match[1];
8998
try {
90-
const localPath = await downloadFile(url);
99+
const localPath = await downloadFile(url, githubToken);
91100
updatedText = updatedText.replace(match[0], `(${localPath})`);
92101
} catch (error) {
93102
console.error(`Failed to download file: ${url}`, error);
@@ -99,7 +108,7 @@ export async function downloadAttachmentsAndRewriteText(text: string): Promise<s
99108
for (const match of legacyMatches) {
100109
const url = match[0];
101110
try {
102-
const localPath = await downloadFile(url);
111+
const localPath = await downloadFile(url, githubToken);
103112
updatedText = updatedText.replace(url, localPath);
104113
} catch (error) {
105114
console.error(`Failed to download legacy image: ${url}`, error);

src/github/junie/junie-tasks.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import {CliInput} from "./types/junie";
2020
import {generateMcpToolsPrompt} from "../../mcp/mcp-prompts";
2121
import {junieArgsToString} from "../../utils/junie-args-parser";
2222

23-
async function getValidatedTextTask(text: string): Promise<string> {
23+
async function getValidatedTextTask(text: string, githubToken?: string): Promise<string> {
2424
// Download attachments and rewrite URLs in the text
25-
return await downloadAttachmentsAndRewriteText(text)
25+
return await downloadAttachmentsAndRewriteText(text, githubToken)
2626
}
2727

2828
function getTriggerTime(context: JunieExecutionContext): string | undefined {
@@ -45,7 +45,8 @@ export async function prepareJunieTask(
4545
branchInfo: BranchInfo,
4646
octokit: Octokits,
4747
enabledMcpServers: string[] = [],
48-
isDefaultToken: boolean = false
48+
isDefaultToken: boolean = false,
49+
githubToken?: string
4950
) {
5051
const owner = context.payload.repository.owner.login;
5152
const repo = context.payload.repository.name;
@@ -82,7 +83,7 @@ export async function prepareJunieTask(
8283
promptText = promptText + mcpToolsPrompt;
8384
}
8485

85-
junieCLITask.task = await getValidatedTextTask(promptText);
86+
junieCLITask.task = await getValidatedTextTask(promptText, githubToken);
8687
}
8788

8889
if (!junieCLITask.task && !junieCLITask.mergeTask) {

src/github/junie/prepare-junie.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export async function initializeJunieExecution({
8989
isFixCI: isFixCIEvent(context)
9090
})
9191

92-
await prepareJunieTask(context, branchInfo, octokit, mcpConfig.enabledServers, tokenConfig.isDefaultToken())
92+
await prepareJunieTask(context, branchInfo, octokit, mcpConfig.enabledServers, tokenConfig.isDefaultToken(), tokenConfig.workingToken)
9393
}
9494

9595
async function shouldHandle(context: JunieExecutionContext, octokit: Octokits): Promise<boolean> {

0 commit comments

Comments
 (0)