Skip to content

Commit

Permalink
Merge branch 'master' into db/feat/validate-blob-ids
Browse files Browse the repository at this point in the history
  • Loading branch information
petertonysmith94 authored Sep 3, 2024
2 parents 03d54f3 + 90a1d0f commit c13f69d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/swift-tools-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": patch
---

feat: support basic auth
43 changes: 43 additions & 0 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,49 @@ const getCustomFetch =
* @group node
*/
describe('Provider', () => {
it('supports basic auth', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider: { url },
} = launched;

const usernameAndPassword = 'securest:ofpasswords';
const parsedUrl = new URL(url);
const hostAndPath = `${parsedUrl.host}${parsedUrl.pathname}`;
const authUrl = `http://${usernameAndPassword}@${hostAndPath}`;
const provider = await Provider.create(authUrl);

const fetchSpy = vi.spyOn(global, 'fetch');

await provider.operations.getChain();

const expectedAuthToken = `Basic ${btoa(usernameAndPassword)}`;
const [requestUrl, request] = fetchSpy.mock.calls[0];
expect(requestUrl).toEqual(url);
expect(request?.headers).toMatchObject({
Authorization: expectedAuthToken,
});
});

it('custom requestMiddleware is not overwritten by basic auth', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider: { url },
} = launched;

const usernameAndPassword = 'securest:ofpasswords';
const parsedUrl = new URL(url);
const hostAndPath = `${parsedUrl.host}${parsedUrl.pathname}`;
const authUrl = `http://${usernameAndPassword}@${hostAndPath}`;

const requestMiddleware = vi.fn();
await Provider.create(authUrl, {
requestMiddleware,
});

expect(requestMiddleware).toHaveBeenCalled();
});

it('should throw an error when retrieving a transaction with an unknown transaction type', async () => {
using launched = await setupTestProviderAndWallets();
const { provider } = launched;
Expand Down
28 changes: 27 additions & 1 deletion packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,20 @@ export default class Provider {
}
}

private static extractBasicAuth(url: string): { url: string; auth: string | undefined } {
const parsedUrl = new URL(url);

const username = parsedUrl.username;
const password = parsedUrl.password;
const urlNoBasicAuth = `${parsedUrl.origin}${parsedUrl.pathname}`;
if (!(username && password)) {
return { url, auth: undefined };
}

const auth = `Basic ${btoa(`${username}:${password}`)}`;
return { url: urlNoBasicAuth, auth };
}

/**
* Creates a new instance of the Provider class. This is the recommended way to initialize a Provider.
*
Expand All @@ -463,8 +477,20 @@ export default class Provider {
* @returns A promise that resolves to a Provider instance.
*/
static async create(url: string, options: ProviderOptions = {}): Promise<Provider> {
const provider = new Provider(url, options);
const { url: urlToUse, auth } = this.extractBasicAuth(url);
const provider = new Provider(urlToUse, {
...options,
requestMiddleware: async (request) => {
if (auth) {
request.headers ??= {};
(request.headers as Record<string, string>).Authorization = auth;
}
return options.requestMiddleware?.(request) ?? request;
},
});

await provider.fetchChainAndNodeInfo();

return provider;
}

Expand Down

0 comments on commit c13f69d

Please sign in to comment.