Skip to content

Commit

Permalink
feat: add custom http headers support (#512)
Browse files Browse the repository at this point in the history
  • Loading branch information
ecaroth authored Dec 11, 2024
1 parent e9f48fc commit eb04f5b
Show file tree
Hide file tree
Showing 14 changed files with 901 additions and 1,138 deletions.
3 changes: 0 additions & 3 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit ${1}
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,26 @@ Chromiumly.configure({
});
```

### Advanced Authentication with Custom HTTP Headers

To implement advanced authentication or add custom HTTP headers to your requests, you can use the `customHttpHeaders` option within the `configure` method. This allows you to pass additional headers, such as authentication tokens or custom metadata, with each API call.

For example, you can include a Bearer token for authentication along with a custom header as follows:

```typescript
const token = await generateToken();

Chromiumly.configure({
endpoint: "http://localhost:3000",
customHttpHeaders: {
Authorization: `Bearer ${token}`,
"X-Custom-Header": "value",
},
});
```

## Modules

## Modules

Chromiumly introduces different classes that serve as wrappers to
Expand Down
3 changes: 2 additions & 1 deletion src/chromium/converters/html.converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ export class HtmlConverter extends Converter {
this.endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
3 changes: 2 additions & 1 deletion src/chromium/converters/markdown.converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ export class MarkdownConverter extends Converter {
this.endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
3 changes: 2 additions & 1 deletion src/chromium/converters/url.converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ export class UrlConverter extends Converter {
this.endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
3 changes: 2 additions & 1 deletion src/chromium/screenshots/html.screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ export class HtmlScreenshot extends Screenshot {
this.endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
3 changes: 2 additions & 1 deletion src/chromium/screenshots/markdown.screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ export class MarkdownScreenshot extends Screenshot {
this.endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
3 changes: 2 additions & 1 deletion src/chromium/screenshots/url.screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ export class UrlScreenshot extends Screenshot {
this.endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
10 changes: 8 additions & 2 deletions src/common/gotenberg.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,23 @@ export class GotenbergUtils {
* @param {string} endpoint - The Gotenberg endpoint URL.
* @param {string} username - The username for basic authentication.
* @param {string} password - The password for basic authentication.
* @param {Record<string, string>} [customHttpHeaders] - Custom HTTP headers to be sent with the request.
* @param {FormData} data - The FormData object to be sent in the POST request.
* @param {Record<string, string>} customHeaders - List of custom headers to include in the fetch
* @returns {Promise<Buffer>} A Promise that resolves to the response body as a Buffer.
* @throws {Error} Throws an error if the HTTP response status is not OK.
*/
public static async fetch(
endpoint: string,
data: FormData,
username?: string,
password?: string
password?: string,
customHttpHeaders?: Record<string, string>
): Promise<Buffer> {
const headers: Record<string, string> = { ...data.getHeaders() };
const headers: Record<string, string> = {
...data.getHeaders(),
...customHttpHeaders
};

if (username && password) {
const authHeader =
Expand Down
31 changes: 27 additions & 4 deletions src/common/tests/gotenberg.utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,38 @@ describe('GotenbergUtils', () => {
const endpoint = 'http://localhost:3000/forms/chromium/convert/html';
const basicAuthUsername = 'username';
const basicAuthPassword = 'pass';
const customHttpHeaders = { 'X-Custom-Header': 'value' };

describe('when fetch request succeeds', () => {
it('should return a buffer', async () => {
it('should return a buffer and send correct headers', async () => {
mockFetch.mockResolvedValueOnce(new Response('content'));

const response = await GotenbergUtils.fetch(
endpoint,
data,
basicAuthUsername,
basicAuthPassword
basicAuthPassword,
customHttpHeaders
);

await expect(response).toEqual(Buffer.from('content'));

expect(mockFetch).toHaveBeenCalledWith(
endpoint,
expect.objectContaining({
method: 'post',
headers: expect.objectContaining({
Authorization: `Basic ${Buffer.from(
`${basicAuthUsername}:${basicAuthPassword}`
).toString('base64')}`,
'X-Custom-Header': 'value',
'content-type': expect.stringMatching(
/^multipart\/form-data; boundary=/
)
}),
body: expect.any(Object)
})
);
});
});

Expand All @@ -68,7 +89,8 @@ describe('GotenbergUtils', () => {
endpoint,
data,
basicAuthUsername,
basicAuthPassword
basicAuthPassword,
customHttpHeaders
)
).rejects.toThrow(errorMessage);
});
Expand All @@ -90,7 +112,8 @@ describe('GotenbergUtils', () => {
endpoint,
data,
basicAuthUsername,
basicAuthPassword
basicAuthPassword,
customHttpHeaders
)
).rejects.toThrow('500 Internal server error');
});
Expand Down
3 changes: 2 additions & 1 deletion src/libre-office/libre-office.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export class LibreOffice {
endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}
}
19 changes: 19 additions & 0 deletions src/main.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export class Chromiumly {
private static gotenbergApiBasicAuthPassword: string | undefined =
Gotenberg.password;

/**
* Custom HTTP headers to be sent with each request.
* @type {Record<string, string> | undefined}
*/
private static customHttpHeaders: Record<string, string> | undefined;

/**
* The path for Chromium-related conversions.
* @type {string}
Expand Down Expand Up @@ -113,11 +119,13 @@ export class Chromiumly {
* @param {string} config.endpoint - The Gotenberg service endpoint.
* @param {string} [config.username] - The username for basic authentication.
* @param {string} [config.password] - The password for basic authentication.
* @param {Record<string, string>} [config.customHttpHeaders] - Custom HTTP headers to be sent with each request.
*/
public static configure(config: {
endpoint: string;
username?: string;
password?: string;
customHttpHeaders?: Record<string, string>;
}): void {
this.gotenbergEndpoint = config.endpoint;

Expand All @@ -127,6 +135,9 @@ export class Chromiumly {
if (config.password !== undefined) {
this.gotenbergApiBasicAuthPassword = config.password;
}
if (config.customHttpHeaders !== undefined) {
this.customHttpHeaders = config.customHttpHeaders;
}
}

/**
Expand Down Expand Up @@ -156,4 +167,12 @@ export class Chromiumly {
public static getGotenbergApiBasicAuthPassword(): string | undefined {
return this.gotenbergApiBasicAuthPassword;
}

/**
* Gets the custom HTTP headers.
* @returns {Record<string, string> | undefined}
*/
public static getCustomHttpHeaders(): Record<string, string> | undefined {
return this.customHttpHeaders;
}
}
12 changes: 8 additions & 4 deletions src/pdf-engines/pdf-engines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ export class PDFEngines {
endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}

Expand Down Expand Up @@ -93,7 +94,8 @@ export class PDFEngines {
endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}

Expand All @@ -116,7 +118,8 @@ export class PDFEngines {
endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}

Expand Down Expand Up @@ -145,7 +148,8 @@ export class PDFEngines {
endpoint,
data,
Chromiumly.getGotenbergApiBasicAuthUsername(),
Chromiumly.getGotenbergApiBasicAuthPassword()
Chromiumly.getGotenbergApiBasicAuthPassword(),
Chromiumly.getCustomHttpHeaders()
);
}

Expand Down
Loading

0 comments on commit eb04f5b

Please sign in to comment.