Skip to content

Commit

Permalink
Merge 75a6871 into 931c80d
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-gc committed Dec 7, 2021
2 parents 931c80d + 75a6871 commit 87ec08b
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-files-learn.md
@@ -0,0 +1,5 @@
---
"@firebase/auth": patch
---

Add X-Firebase-gmpid header to requests
23 changes: 22 additions & 1 deletion packages/auth/src/api/authentication/token.test.ts
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as sinon from 'sinon';
import { expect, use } from 'chai';
import chaiAsPromised from 'chai-as-promised';

Expand All @@ -41,7 +42,10 @@ describe('requestStsToken', () => {
fetch.setUp();
});

afterEach(fetch.tearDown);
afterEach(() => {
fetch.tearDown();
sinon.restore();
});

it('should POST to the correct endpoint', async () => {
const mock = fetch.mock(endpoint, {
Expand Down Expand Up @@ -90,6 +94,23 @@ describe('requestStsToken', () => {
);
});

it('should include whatever headers come from auth impl', async () => {
sinon.stub(auth, '_getAdditionalHeaders').returns(Promise.resolve({
'look-at-me-im-a-header': 'header-value',
'anotherheader': 'header-value-2',
}));

const mock = fetch.mock(endpoint, {
'access_token': 'new-access-token',
'expires_in': '3600',
'refresh_token': 'new-refresh-token'
});
await requestStsToken(auth, 'old-refresh-token');

expect(mock.calls[0].headers.get('look-at-me-im-a-header')).to.eq('header-value');
expect(mock.calls[0].headers.get('anotherheader')).to.eq('header-value-2');
});

it('should handle errors', async () => {
const mock = fetch.mock(
endpoint,
Expand Down
13 changes: 7 additions & 6 deletions packages/auth/src/api/authentication/token.ts
Expand Up @@ -22,7 +22,8 @@ import { querystring } from '@firebase/util';
import {
_getFinalTarget,
_performFetchWithErrorHandling,
HttpMethod
HttpMethod,
HttpHeader
} from '../index';
import { FetchProvider } from '../../core/util/fetch_provider';
import { Auth } from '../../model/public_types';
Expand Down Expand Up @@ -52,7 +53,7 @@ export async function requestStsToken(
const response = await _performFetchWithErrorHandling<RequestStsTokenServerResponse>(
auth,
{},
() => {
async () => {
const body = querystring({
'grant_type': 'refresh_token',
'refresh_token': refreshToken
Expand All @@ -65,12 +66,12 @@ export async function requestStsToken(
`key=${apiKey}`
);

const headers = await (auth as AuthInternal)._getAdditionalHeaders();
headers[HttpHeader.CONTENT_TYPE] = 'application/x-www-form-urlencoded';

return FetchProvider.fetch()(url, {
method: HttpMethod.POST,
headers: {
'X-Client-Version': (auth as AuthInternal)._getSdkClientVersion(),
'Content-Type': 'application/x-www-form-urlencoded'
},
headers,
body
});
}
Expand Down
15 changes: 15 additions & 0 deletions packages/auth/src/api/index.test.ts
Expand Up @@ -94,6 +94,21 @@ describe('api/_performApiRequest', () => {
);
});

it('should include whatever headers the auth impl attaches', async () => {
sinon.stub(auth, '_getAdditionalHeaders').returns(Promise.resolve({
'look-at-me-im-a-header': 'header-value',
'anotherheader': 'header-value-2',
}));

const mock = mockEndpoint(Endpoint.SIGN_UP, serverResponse);
await _performApiRequest<
typeof request,
typeof serverResponse
>(auth, HttpMethod.POST, Endpoint.SIGN_UP, request);
expect(mock.calls[0].headers.get('look-at-me-im-a-header')).to.eq('header-value');
expect(mock.calls[0].headers.get('anotherheader')).to.eq('header-value-2');
});

it('should set the framework in clientVersion if logged', async () => {
auth._logFramework('Mythical');
const mock = mockEndpoint(Endpoint.SIGN_UP, serverResponse);
Expand Down
15 changes: 6 additions & 9 deletions packages/auth/src/api/index.ts
Expand Up @@ -36,7 +36,8 @@ export const enum HttpMethod {
export const enum HttpHeader {
CONTENT_TYPE = 'Content-Type',
X_FIREBASE_LOCALE = 'X-Firebase-Locale',
X_CLIENT_VERSION = 'X-Client-Version'
X_CLIENT_VERSION = 'X-Client-Version',
X_FIREBASE_GMPID = 'X-Firebase-gmpid'
}

export const enum Endpoint {
Expand Down Expand Up @@ -84,7 +85,7 @@ export async function _performApiRequest<T, V>(
request?: T,
customErrorMap: Partial<ServerErrorMap<ServerError>> = {}
): Promise<V> {
return _performFetchWithErrorHandling(auth, customErrorMap, () => {
return _performFetchWithErrorHandling(auth, customErrorMap, async () => {
let body = {};
let params = {};
if (request) {
Expand All @@ -102,15 +103,11 @@ export async function _performApiRequest<T, V>(
...params
}).slice(1);

const headers = new (FetchProvider.headers())();
headers.set(HttpHeader.CONTENT_TYPE, 'application/json');
headers.set(
HttpHeader.X_CLIENT_VERSION,
(auth as AuthInternal)._getSdkClientVersion()
);
const headers = await (auth as AuthInternal)._getAdditionalHeaders();
headers[HttpHeader.CONTENT_TYPE] = 'application/json';

if (auth.languageCode) {
headers.set(HttpHeader.X_FIREBASE_LOCALE, auth.languageCode);
headers[HttpHeader.X_FIREBASE_LOCALE] = auth.languageCode;
}

return FetchProvider.fetch()(
Expand Down
16 changes: 16 additions & 0 deletions packages/auth/src/core/auth/auth_impl.test.ts
Expand Up @@ -460,4 +460,20 @@ describe('core/auth/auth_impl', () => {
expect(spy).not.to.have.been.called;
});
});

context ('#_getAdditionalHeaders', () => {
it('always adds the client version', async () => {
expect(await auth._getAdditionalHeaders()).to.eql({
'X-Client-Version': 'v',
});
});

it('adds the gmp app ID if available', async () => {
auth.app.options.appId = 'app-id';
expect(await auth._getAdditionalHeaders()).to.eql({
'X-Client-Version': 'v',
'X-Firebase-gmpid': 'app-id',
});
});
});
});
12 changes: 10 additions & 2 deletions packages/auth/src/core/auth/auth_impl.ts
Expand Up @@ -58,6 +58,7 @@ import { _assert } from '../util/assert';
import { _getInstance } from '../util/instantiator';
import { _getUserLanguage } from '../util/navigator';
import { _getClientVersion } from '../util/version';
import { HttpHeader } from '../../api';

interface AsyncAction {
(): Promise<void>;
Expand Down Expand Up @@ -577,8 +578,15 @@ export class AuthImpl implements AuthInternal, _FirebaseService {
_getFrameworks(): readonly string[] {
return this.frameworks;
}
_getSdkClientVersion(): string {
return this.clientVersion;
async _getAdditionalHeaders(): Promise<Record<string, string>> {
// Additional headers on every request
const headers: Record<string, string> = {
[HttpHeader.X_CLIENT_VERSION]: this.clientVersion,
};
if (this.app.options.appId) {
headers[HttpHeader.X_FIREBASE_GMPID] = this.app.options.appId;
}
return headers;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/auth/src/model/auth.ts
Expand Up @@ -81,7 +81,7 @@ export interface AuthInternal extends Auth {
_getPersistence(): string;
_logFramework(framework: string): void;
_getFrameworks(): readonly string[];
_getSdkClientVersion(): string;
_getAdditionalHeaders(): Promise<Record<string, string>>;

readonly name: AppName;
readonly config: ConfigInternal;
Expand Down

0 comments on commit 87ec08b

Please sign in to comment.