import { encodeBase64 } from "https://deno.land/std@0.214.0/encoding/base64.ts";
type AuthTokenData =
| {
bearer: string;
}
| { username: string; password: String };
class AuthToken {
host: string;
token: AuthTokenData;
constructor(host: string, token: AuthTokenData) {
this.host = host;
this.token = token;
}
toString() {
if ("bearer" in this.token) {
return `Bearer ${this.token.bearer}`;
} else {
return `Basic ${encodeBase64(`${this.token.username}:${this.token.password}`)}`;
}
}
}
export class AuthTokens {
tokens: AuthToken[];
constructor(maybe_tokens_str?: string) {
let tokens: AuthToken[] = [];
if (maybe_tokens_str) {
const tokens_str = maybe_tokens_str;
for (const token_str of tokens_str.split(";")) {
if (token_str.includes("@")) {
let pair: string[] = token_str.match(/^(.+)@(.+?)$/)!.slice(1);
let token = pair[0];
let host = pair[1].toLowerCase();
if (token.includes(":")) {
let pair: string[] = token.match(/^(.+):(.+?)$/)!.slice(1);
let username = pair[0];
let password = pair[1];
tokens.push(new AuthToken(host, { username, password }));
} else {
tokens.push(new AuthToken(host, { bearer: token }));
}
} else {
throw new TypeError("Badly formed auth token discarded.");
}
}
}
this.tokens = tokens;
}
get(url: string): AuthToken | void {
return this.tokens.find((t) => {
const parsedSpecifier = new URL(url);
let hostname = parsedSpecifier.port
? `${parsedSpecifier.hostname}:${parsedSpecifier.port}`
: parsedSpecifier.hostname;
return `.${hostname.toLowerCase()}`.endsWith(`.${t.host}`);
});
}
}