Skip to content

Commit

Permalink
fix(Client): retry once with new token if FileMaker reporst invalid t…
Browse files Browse the repository at this point in the history
…oken
  • Loading branch information
DASPRiD committed Apr 17, 2022
1 parent 9a2b6cc commit ef9b348
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,26 @@ export default class Client {
return new Layout<T, U>(layout, this);
}

public async request<T>(path : string, request ?: RequestInit) : Promise<T> {
request = Client.injectHeaders(
public async request<T>(path : string, request ?: RequestInit, retryOnInvalidToken = true) : Promise<T> {
const authorizedRequest = Client.injectHeaders(
new Headers({
'Content-Type': 'application/json',
'Authorization': `Bearer ${await this.getToken()}`,
}),
request
);
request.agent = this.agent;
authorizedRequest.agent = this.agent;

const response = await fetch(`${this.uri}/fmi/data/v1/databases/${this.database}/${path}`, request);
const response = await fetch(`${this.uri}/fmi/data/v1/databases/${this.database}/${path}`, authorizedRequest);

if (!response.ok) {
const data = await response.json() as FileMakerErrorResponse;

if (data.messages[0].code === '952' && retryOnInvalidToken) {
this.token = null;
return this.request(path, request, false);
}

throw new FileMakerError(data.messages[0].code, data.messages[0].message);
}

Expand Down
42 changes: 42 additions & 0 deletions test/Client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,48 @@ describe('Client', () => {
await client.request('test');
});

it('should retry with a new token if server reports invalid data API token', async () => {
let firstRequest = true;

nock('http://example.com')
.post('/fmi/data/v1/databases/db/sessions')
.twice()
.reply(() => {
if (firstRequest) {
firstRequest = false;
return [200, {}, {'X-FM-Data-Access-Token': 'foo'}] as const;
}

return [200, {}, {'X-FM-Data-Access-Token': 'bar'}] as const;
});
nock('http://example.com')
.get('/fmi/data/v1/databases/db/test')
.matchHeader('authorization', 'Bearer foo')
.matchHeader('content-type', 'application/json')
.reply(400, {messages: [{code: '952', message: 'Invalid FileMaker DATA API token'}]});
nock('http://example.com')
.get('/fmi/data/v1/databases/db/test')
.matchHeader('authorization', 'Bearer bar')
.reply(200, {response: 'test'});

const response = await client.request('test');
expect(response).toBe('test');
});

it('should fail when the token is reported as invalid twice', async () => {
nock('http://example.com')
.post('/fmi/data/v1/databases/db/sessions')
.twice()
.reply(200, {}, {'X-FM-Data-Access-Token': 'foo'});
nock('http://example.com')
.get('/fmi/data/v1/databases/db/test')
.twice()
.reply(400, {messages: [{code: '952', message: 'Invalid FileMaker DATA API token'}]});

const request = client.request('test');
await expect(request).rejects.toEqual(new FileMakerError('952', 'Invalid FileMaker DATA API token'));
});

it('should sign in with basic auth', async () => {
nock('http://example.com')
.post('/fmi/data/v1/databases/db/sessions')
Expand Down

0 comments on commit ef9b348

Please sign in to comment.