Skip to content

Commit 1e609d0

Browse files
committed
added basic auth support
1 parent ff03829 commit 1e609d0

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

anchor.ts

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@ interface Anchor {
1212
};
1313
}
1414

15+
interface BasicAuthConfig {
16+
username: string;
17+
password: string;
18+
}
19+
1520
interface UpdateOptions {
1621
localPath?: string; // Local file
1722
remoteUrls?: string[]; // Remote endpoints to fetch anchor file
1823
staticAnchors?: Anchor[]; // Use the following static anchors
1924
checkIntervalMs?: number; // Periodic refresh
25+
basicAuth?: BasicAuthConfig;
2026
}
2127

2228
export class AnchorStore {
@@ -198,12 +204,59 @@ export class AnchorStore {
198204
return null;
199205
}
200206

207+
private extractAuthFromUrl(url: string): { username: string; password: string } | null {
208+
try {
209+
const urlObj = new URL(url);
210+
if (urlObj.username && urlObj.password) {
211+
return {
212+
username: decodeURIComponent(urlObj.username),
213+
password: decodeURIComponent(urlObj.password)
214+
};
215+
}
216+
} catch (err) {
217+
log(`Invalid URL format: ${url}`);
218+
}
219+
return null;
220+
}
221+
222+
private cleanUrl(url: string): string {
223+
try {
224+
const urlObj = new URL(url);
225+
urlObj.username = '';
226+
urlObj.password = '';
227+
return urlObj.toString();
228+
} catch (err) {
229+
log(`Invalid URL format: ${url}`);
230+
return url;
231+
}
232+
}
233+
234+
private createAuthHeaders(url: string): HeadersInit {
235+
const headers: HeadersInit = {};
236+
const authFromUrl = this.extractAuthFromUrl(url);
237+
if (authFromUrl) {
238+
const credentials = Buffer.from(`${authFromUrl.username}:${authFromUrl.password}`).toString('base64');
239+
headers['Authorization'] = `Basic ${credentials}`;
240+
} else if (this.options.basicAuth) {
241+
const { username, password } = this.options.basicAuth;
242+
const credentials = Buffer.from(`${username}:${password}`).toString('base64');
243+
headers['Authorization'] = `Basic ${credentials}`;
244+
}
245+
246+
return headers;
247+
}
248+
201249
private async fetchAnchorsFromRemotes(remoteUrls: string[]): Promise<Anchor[]> {
202250
const responses = await Promise.all(
203251
remoteUrls.map(async url => {
204252
log(`Fetching anchors from: ${url}`);
205253
try {
206-
const res = await fetch(url);
254+
const authHeaders = this.createAuthHeaders(url);
255+
const cleanUrl = this.cleanUrl(url);
256+
257+
const res = await fetch(cleanUrl, {
258+
headers: authHeaders
259+
});
207260
if (!res.ok) {
208261
throw new Error(`Status: ${res.status}`);
209262
}
@@ -238,9 +291,9 @@ export class AnchorStore {
238291
for (const group of groups.values()) {
239292
if (
240293
!chosen ||
241-
group.count > chosen.count ||
242-
(group.count === chosen.count &&
243-
group.anchors[0].block.height > chosen.anchors[0].block.height)
294+
group.count > chosen.count ||
295+
(group.count === chosen.count &&
296+
group.anchors[0].block.height > chosen.anchors[0].block.height)
244297
) {
245298
chosen = group;
246299
}
@@ -251,6 +304,7 @@ export class AnchorStore {
251304
return chosen.anchors;
252305
}
253306

307+
254308
public isStale(version: number): boolean {
255309
return version < this.staleThreshold;
256310
}

0 commit comments

Comments
 (0)