Skip to content

Commit 16a2c12

Browse files
authored
Adding X-Firebase-Client header to rules API calls (#651)
* Adding X-Firebase-Client header to Rules API calls * Removed test resources
1 parent 4ae950d commit 16a2c12

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

src/security-rules/security-rules-api-client.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import { FirebaseSecurityRulesError, SecurityRulesErrorCode } from './security-r
2020
import * as validator from '../utils/validator';
2121

2222
const RULES_V1_API = 'https://firebaserules.googleapis.com/v1';
23+
const FIREBASE_VERSION_HEADER = {
24+
'X-Firebase-Client': 'fire-admin-node/<XXX_SDK_VERSION_XXX>',
25+
};
2326

2427
export interface Release {
2528
readonly name: string;
@@ -30,7 +33,7 @@ export interface Release {
3033

3134
export interface RulesetContent {
3235
readonly source: {
33-
readonly files: Array<{name: string, content: string}>;
36+
readonly files: Array<{ name: string, content: string }>;
3437
};
3538
}
3639

@@ -40,7 +43,7 @@ export interface RulesetResponse extends RulesetContent {
4043
}
4144

4245
export interface ListRulesetsResponse {
43-
readonly rulesets: Array<{name: string, createTime: string}>;
46+
readonly rulesets: Array<{ name: string, createTime: string }>;
4447
readonly nextPageToken?: string;
4548
}
4649

@@ -64,8 +67,8 @@ export class SecurityRulesApiClient {
6467
throw new FirebaseSecurityRulesError(
6568
'invalid-argument',
6669
'Failed to determine project ID. Initialize the SDK with service account credentials, or '
67-
+ 'set project ID as an app option. Alternatively, set the GOOGLE_CLOUD_PROJECT '
68-
+ 'environment variable.');
70+
+ 'set project ID as an app option. Alternatively, set the GOOGLE_CLOUD_PROJECT '
71+
+ 'environment variable.');
6972
}
7073

7174
this.projectIdPrefix = `projects/${projectId}`;
@@ -209,6 +212,7 @@ export class SecurityRulesApiClient {
209212
}
210213

211214
private sendRequest<T>(request: HttpRequestConfig): Promise<T> {
215+
request.headers = FIREBASE_VERSION_HEADER;
212216
return this.httpClient.send(request)
213217
.then((resp) => {
214218
return resp.data as T;
@@ -247,7 +251,7 @@ interface Error {
247251
status?: string;
248252
}
249253

250-
const ERROR_CODE_MAPPING: {[key: string]: SecurityRulesErrorCode} = {
254+
const ERROR_CODE_MAPPING: { [key: string]: SecurityRulesErrorCode } = {
251255
INVALID_ARGUMENT: 'invalid-argument',
252256
NOT_FOUND: 'not-found',
253257
RESOURCE_EXHAUSTED: 'resource-exhausted',

test/unit/security-rules/security-rules-api-client.spec.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ describe('SecurityRulesApiClient', () => {
3838
status: 'NOT_FOUND',
3939
},
4040
};
41+
const EXPECTED_HEADERS = {
42+
'X-Firebase-Client': 'fire-admin-node/<XXX_SDK_VERSION_XXX>',
43+
};
4144

4245
const apiClient: SecurityRulesApiClient = new SecurityRulesApiClient(
4346
new HttpClient(), 'test-project');
@@ -87,14 +90,15 @@ describe('SecurityRulesApiClient', () => {
8790
it('should resolve with the requested ruleset on success', () => {
8891
const stub = sinon
8992
.stub(HttpClient.prototype, 'send')
90-
.resolves(utils.responseFrom({name: 'bar'}));
93+
.resolves(utils.responseFrom({ name: 'bar' }));
9194
stubs.push(stub);
9295
return apiClient.getRuleset(RULESET_NAME)
9396
.then((resp) => {
9497
expect(resp.name).to.equal('bar');
9598
expect(stub).to.have.been.calledOnce.and.calledWith({
9699
method: 'GET',
97100
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets/ruleset-id',
101+
headers: EXPECTED_HEADERS,
98102
});
99103
});
100104
});
@@ -153,7 +157,7 @@ describe('SecurityRulesApiClient', () => {
153157
},
154158
};
155159

156-
const invalidContent: any[] = [null, undefined, {}, {source: {}}];
160+
const invalidContent: any[] = [null, undefined, {}, { source: {} }];
157161
invalidContent.forEach((content) => {
158162
it(`should reject when called with: ${JSON.stringify(content)}`, () => {
159163
return apiClient.createRuleset(content)
@@ -162,7 +166,7 @@ describe('SecurityRulesApiClient', () => {
162166
});
163167
});
164168

165-
const invalidFiles: any[] = [null, undefined, 'test', {}, {name: 'test'}, {content: 'test'}];
169+
const invalidFiles: any[] = [null, undefined, 'test', {}, { name: 'test' }, { content: 'test' }];
166170
invalidFiles.forEach((file) => {
167171
it(`should reject when called with: ${JSON.stringify(file)}`, () => {
168172
const ruleset: RulesetContent = {
@@ -190,7 +194,7 @@ describe('SecurityRulesApiClient', () => {
190194
it('should resolve with the created resource on success', () => {
191195
const stub = sinon
192196
.stub(HttpClient.prototype, 'send')
193-
.resolves(utils.responseFrom({name: 'some-name', ...RULES_CONTENT}));
197+
.resolves(utils.responseFrom({ name: 'some-name', ...RULES_CONTENT }));
194198
stubs.push(stub);
195199
return apiClient.createRuleset(RULES_CONTENT)
196200
.then((resp) => {
@@ -200,6 +204,7 @@ describe('SecurityRulesApiClient', () => {
200204
method: 'POST',
201205
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets',
202206
data: RULES_CONTENT,
207+
headers: EXPECTED_HEADERS,
203208
});
204209
});
205210
});
@@ -312,7 +317,8 @@ describe('SecurityRulesApiClient', () => {
312317
expect(stub).to.have.been.calledOnce.and.calledWith({
313318
method: 'GET',
314319
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets',
315-
data: {pageSize: 100},
320+
data: { pageSize: 100 },
321+
headers: EXPECTED_HEADERS,
316322
});
317323
});
318324
});
@@ -328,7 +334,8 @@ describe('SecurityRulesApiClient', () => {
328334
expect(stub).to.have.been.calledOnce.and.calledWith({
329335
method: 'GET',
330336
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets',
331-
data: {pageSize: 50},
337+
data: { pageSize: 50 },
338+
headers: EXPECTED_HEADERS,
332339
});
333340
});
334341
});
@@ -344,7 +351,8 @@ describe('SecurityRulesApiClient', () => {
344351
expect(stub).to.have.been.calledOnce.and.calledWith({
345352
method: 'GET',
346353
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets',
347-
data: {pageSize: 50, pageToken: 'next'},
354+
data: { pageSize: 50, pageToken: 'next' },
355+
headers: EXPECTED_HEADERS,
348356
});
349357
});
350358
});
@@ -395,14 +403,15 @@ describe('SecurityRulesApiClient', () => {
395403
it('should resolve with the requested release on success', () => {
396404
const stub = sinon
397405
.stub(HttpClient.prototype, 'send')
398-
.resolves(utils.responseFrom({name: 'bar'}));
406+
.resolves(utils.responseFrom({ name: 'bar' }));
399407
stubs.push(stub);
400408
return apiClient.getRelease(RELEASE_NAME)
401409
.then((resp) => {
402410
expect(resp.name).to.equal('bar');
403411
expect(stub).to.have.been.calledOnce.and.calledWith({
404412
method: 'GET',
405413
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/releases/test.service',
414+
headers: EXPECTED_HEADERS,
406415
});
407416
});
408417
});
@@ -453,7 +462,7 @@ describe('SecurityRulesApiClient', () => {
453462
it('should resolve with the updated release on success', () => {
454463
const stub = sinon
455464
.stub(HttpClient.prototype, 'send')
456-
.resolves(utils.responseFrom({name: 'bar'}));
465+
.resolves(utils.responseFrom({ name: 'bar' }));
457466
stubs.push(stub);
458467
return apiClient.updateRelease(RELEASE_NAME, RULESET_NAME)
459468
.then((resp) => {
@@ -467,6 +476,7 @@ describe('SecurityRulesApiClient', () => {
467476
rulesetName: 'projects/test-project/rulesets/ruleset-id',
468477
},
469478
},
479+
headers: EXPECTED_HEADERS,
470480
});
471481
});
472482
});
@@ -539,6 +549,7 @@ describe('SecurityRulesApiClient', () => {
539549
expect(stub).to.have.been.calledOnce.and.calledWith({
540550
method: 'DELETE',
541551
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets/ruleset-id',
552+
headers: EXPECTED_HEADERS,
542553
});
543554
});
544555
});

0 commit comments

Comments
 (0)