From de5eba451fda6ee95eba3e0becd09953fd785732 Mon Sep 17 00:00:00 2001 From: hiranya911 Date: Fri, 23 Feb 2018 17:48:12 -0800 Subject: [PATCH 1/2] Using ADC when no credentials are specified in options --- src/firebase-app.ts | 23 +++++++++++------------ test/unit/firebase.spec.ts | 19 +++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/firebase-app.ts b/src/firebase-app.ts index bfcc1f5a90..75c083c9a6 100644 --- a/src/firebase-app.ts +++ b/src/firebase-app.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {Credential, GoogleOAuthAccessToken} from './auth/credential'; +import {ApplicationDefaultCredential, Credential, GoogleOAuthAccessToken} from './auth/credential'; import * as validator from './utils/validator'; import {deepCopy, deepExtend} from './utils/deep-copy'; import {FirebaseServiceInterface} from './firebase-service'; @@ -248,27 +248,26 @@ export class FirebaseApp { this.name_ = name; this.options_ = deepCopy(options) as FirebaseAppOptions; - if (typeof this.options_ !== 'object' || this.options_ === null) { - // Ensure the options are a non-null object - this.options_ = {}; + if (!validator.isNonNullObject(this.options_)) { + throw new FirebaseAppError( + AppErrorCodes.INVALID_APP_OPTIONS, + `Invalid Firebase app options passed as the first argument to initializeApp() for the ` + + `app named "${this.name_}". Options must be a non-null object.`, + ); } const hasCredential = ('credential' in this.options_); - - let errorMessage: string; if (!hasCredential) { - errorMessage = 'Options must be an object containing at least a "credential" property.'; + this.options_.credential = new ApplicationDefaultCredential(); } + const credential = this.options_.credential; if (typeof credential !== 'object' || credential === null || typeof credential.getAccessToken !== 'function') { - errorMessage = 'The "credential" property must be an object which implements the Credential interface.'; - } - - if (typeof errorMessage !== 'undefined') { throw new FirebaseAppError( AppErrorCodes.INVALID_APP_OPTIONS, `Invalid Firebase app options passed as the first argument to initializeApp() for the ` + - `app named "${this.name_}". ${errorMessage}`, + `app named "${this.name_}". The "credential" property must be an object which implements ` + + `the Credential interface.`, ); } diff --git a/test/unit/firebase.spec.ts b/test/unit/firebase.spec.ts index 8b742f5205..a96353c9cd 100644 --- a/test/unit/firebase.spec.ts +++ b/test/unit/firebase.spec.ts @@ -28,6 +28,7 @@ import * as utils from './utils'; import * as mocks from '../resources/mocks'; import * as firebaseAdmin from '../../src/index'; +import {ApplicationDefaultCredential} from '../../src/auth/credential'; chai.should(); chai.use(chaiAsPromised); @@ -55,8 +56,8 @@ describe('Firebase', () => { }); describe('#initializeApp()', () => { - const invalidOptions = [null, NaN, 0, 1, true, false, '', 'a', [], {}, _.noop]; - invalidOptions.forEach((invalidOption) => { + const invalidOptions = [null, NaN, 0, 1, true, false, '', 'a', [], _.noop]; + invalidOptions.forEach((invalidOption: any) => { it('should throw given invalid options object: ' + JSON.stringify(invalidOption), () => { expect(() => { firebaseAdmin.initializeApp(invalidOption); @@ -64,16 +65,10 @@ describe('Firebase', () => { }); }); - it('should throw given an options object that does not contain any of the required keys', () => { - expect(() => { - firebaseAdmin.initializeApp({ a: 1, b: true } as any); - }).to.throw('Invalid Firebase app options'); - }); - - it('should throw given an options object containing no "credential" key', () => { - expect(() => { - firebaseAdmin.initializeApp(mocks.appOptionsNoAuth); - }).to.throw('Invalid Firebase app options'); + it('should use application default credentials when no credentials are explicitly specified', () => { + const app = firebaseAdmin.initializeApp(mocks.appOptionsNoAuth); + expect(app.options).to.have.property('credential'); + expect(app.options.credential).to.be.instanceOf(ApplicationDefaultCredential); }); it('should not modify the provided options object', () => { From e0a86d27a1cfb845362cf7c6586e3df8df4d365c Mon Sep 17 00:00:00 2001 From: hiranya911 Date: Sat, 24 Feb 2018 15:08:55 -0800 Subject: [PATCH 2/2] Updated Changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3fbb999a6..891e2c29c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Unreleased -- +- [changed] The `admin.initializeApp()` method can now be invoked without an + explicit `credential` option. In that case the SDK will get initialized with + Google application default credentials. # v5.9.0