Skip to content

Commit

Permalink
feat: add simple env var resolution to auth resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduard Lavuš committed Feb 11, 2021
1 parent 9367047 commit 33a080f
Showing 1 changed file with 94 additions and 49 deletions.
143 changes: 94 additions & 49 deletions src/internal/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,87 @@ const queryParameters = (parameters?: Record<string, string>): string => {
return '';
};

const basicAuth = (auth: Auth): string => {
/**
* Attempts to resolve auth value.
*
* If the value starts with `$` character, it attempts to look it up in the environment variables.
* If the value is not in environment or doesn't start with `$` it is returned as is.
*/
const resolveAuthValue = (str: string): string => {
let value = str;

if (str.startsWith('$')) {
const variable = str.slice(1);
const env = process.env[variable];
if (env !== undefined) {
value = env;
} else {
console.warn('Enviroment variable', variable, 'not found');
}
}

return value;
};

const basicAuth = (auth: Auth, headers: Headers): void => {
if (!('BasicAuth' in auth)) {
throw new Error('Missing credentials for Basic auth!');
}

return (
'Basic ' +
Buffer.from(
`${auth.BasicAuth.username}:${auth.BasicAuth.password}`
).toString('base64')
);
const name = resolveAuthValue(auth.BasicAuth.username);
const password = resolveAuthValue(auth.BasicAuth.password);

const value =
'Basic ' + Buffer.from(`${name}:${password}`).toString('base64');
headers.append(AUTH_HEADER_NAME, value);
};

const apikeyAuth = (
auth: Auth,
pathParameters: NonPrimitive,
queryAuth: Record<string, string>,
headers: Headers,
requestBody: Variables | undefined
): void => {
if (!('ApiKey' in auth)) {
throw new Error('Api Key credentials not present.');
}

// TODO: Should we be resolving the name?
const name = resolveAuthValue(auth.ApiKey.name);
const value = resolveAuthValue(auth.ApiKey.value);

switch (auth.ApiKey.in) {
case 'header':
headers.append(name, value);
break;
case 'query':
queryAuth[name] = value;
break;
case 'body':
if (typeof requestBody !== 'object' || Array.isArray(requestBody)) {
throw new Error(
'ApiKey in body can be used only when body is an object.'
);
}
requestBody[name] = value;
break;
case 'path':
pathParameters[name] = value;
break;
}
};

const bearerAuth = (auth: Auth, headers: Headers): void => {
if (!('Bearer' in auth)) {
throw new Error('Bearer credentials not present.');
}

// TODO: Should we be resolving the name?
const name = resolveAuthValue(auth.Bearer.name);
const value = resolveAuthValue(auth.Bearer.value);

headers.append(name, `Bearer ${value}`);
};

const formData = (data?: Record<string, string>): FormData => {
Expand Down Expand Up @@ -175,48 +245,23 @@ export const HttpClient = {
if (parameters.auth === undefined) {
throw new Error('Credentials not present.');
}
if (parameters.security.scheme === 'basic') {
if (!('BasicAuth' in parameters.auth)) {
throw new Error('Basic Auth credentials not present.');
}
headers.append(AUTH_HEADER_NAME, basicAuth(parameters.auth));
} else if (parameters.security.scheme === 'apikey') {
if (!('ApiKey' in parameters.auth)) {
throw new Error('Api Key credentials not present.');
}
switch (parameters.auth.ApiKey.in) {
case 'header':
headers.append(
parameters.auth.ApiKey.name,
parameters.auth.ApiKey.value
);
break;
case 'query':
queryAuth[parameters.auth.ApiKey.name] =
parameters.auth.ApiKey.value;
break;
case 'body':
if (typeof requestBody !== 'object' || Array.isArray(requestBody)) {
throw new Error(
'ApiKey in body can be used only when body is an object.'
);
}
requestBody[parameters.auth.ApiKey.name] =
parameters.auth.ApiKey.value;
break;
case 'path':
pathParameters[parameters.auth.ApiKey.name] =
parameters.auth.ApiKey.value;
break;
}
} else if (parameters.security.scheme === 'bearer') {
if (!('Bearer' in parameters.auth)) {
throw new Error('Bearer credentials not present.');
}
headers.append(
parameters.auth.Bearer.name,
`Bearer ${parameters.auth.Bearer.value}`
);

switch (parameters.security.scheme) {
case 'basic':
basicAuth(parameters.auth, headers);
break;
case 'apikey':
apikeyAuth(
parameters.auth,
pathParameters,
queryAuth,
headers,
requestBody
);
break;
case 'bearer':
bearerAuth(parameters.auth, headers);
break;
}
}

Expand Down

0 comments on commit 33a080f

Please sign in to comment.