Skip to content

Commit 6caf8ef

Browse files
authored
Migrate Auth to component framework (#2342)
* Mirgrate Auth to component framework * update Auth types * [AUTOMATED]: Prettier Code Styling * address comments
1 parent f2a3c5d commit 6caf8ef

File tree

8 files changed

+141
-71
lines changed

8 files changed

+141
-71
lines changed

packages/auth-interop-types/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# @firebase/auth-interop-types
2+
3+
**This package is not intended for direct usage, and should only be used via the officially supported [firebase](https://www.npmjs.com/package/firebase) package.**
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
export interface FirebaseAuthTokenData {
19+
accessToken: string;
20+
}
21+
22+
export interface FirebaseAuthInternal {
23+
getToken(refreshToken?: boolean): Promise<FirebaseAuthTokenData | null>;
24+
getUid(): string | null;
25+
addAuthTokenListener(fn: (token: string | null) => void): void;
26+
removeAuthTokenListener(fn: (token: string | null) => void): void;
27+
}
28+
29+
export type FirebaseAuthInternalName = 'auth-internal';
30+
31+
declare module '@firebase/component' {
32+
interface NameServiceMapping {
33+
'auth-internal': FirebaseAuthInternal;
34+
}
35+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "@firebase/auth-interop-types",
3+
"version": "0.1.0",
4+
"description": "@firebase/auth interop Types",
5+
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
6+
"license": "Apache-2.0",
7+
"scripts": {
8+
"test": "tsc"
9+
},
10+
"files": [
11+
"index.d.ts"
12+
],
13+
"peerDependencies": {
14+
"@firebase/app-types": "0.x",
15+
"@firebase/util": "0.x"
16+
},
17+
"repository": {
18+
"directory": "packages/auth-types",
19+
"type": "git",
20+
"url": "https://github.com/firebase/firebase-js-sdk.git"
21+
},
22+
"bugs": {
23+
"url": "https://github.com/firebase/firebase-js-sdk/issues"
24+
},
25+
"devDependencies": {
26+
"typescript": "3.6.4"
27+
}
28+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../../config/tsconfig.base.json",
3+
"compilerOptions": {
4+
"noEmit": true
5+
},
6+
"exclude": [
7+
"dist/**/*"
8+
]
9+
}

packages/auth-types/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,9 @@ declare module '@firebase/app-types' {
386386
auth?(): FirebaseAuth;
387387
}
388388
}
389+
390+
declare module '@firebase/component' {
391+
interface NameServiceMapping {
392+
'auth': FirebaseAuth;
393+
}
394+
}

packages/auth/src/exports_auth.js

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -618,27 +618,10 @@ fireauth.exportlib.exportFunction(
618618

619619
(function() {
620620
if (typeof firebase === 'undefined' || !firebase.INTERNAL ||
621-
!firebase.INTERNAL.registerService) {
621+
!firebase.INTERNAL.registerComponent) {
622622
throw new Error('Cannot find the firebase namespace; be sure to include ' +
623623
'firebase-app.js before this library.');
624624
} else {
625-
/** @type {!firebase.ServiceFactory} */
626-
var factory = function(app, extendApp) {
627-
var auth = new fireauth.Auth(app);
628-
extendApp({
629-
'INTERNAL': {
630-
// Extend app.INTERNAL.getUid.
631-
'getUid': goog.bind(auth.getUid, auth),
632-
'getToken': goog.bind(auth.getIdTokenInternal, auth),
633-
'addAuthTokenListener':
634-
goog.bind(auth.addAuthTokenListenerInternal, auth),
635-
'removeAuthTokenListener':
636-
goog.bind(auth.removeAuthTokenListenerInternal, auth)
637-
}
638-
});
639-
return auth;
640-
};
641-
642625
var namespace = {
643626
// Exports firebase.auth.ActionCodeInfo.Operation.
644627
'ActionCodeInfo': {
@@ -687,34 +670,45 @@ fireauth.exportlib.exportFunction(
687670
fireauth.exportlib.exportFunction(namespace,
688671
'ActionCodeURL', fireauth.ActionCodeURL, []);
689672

690-
// Register Auth service with firebase.App.
691-
firebase.INTERNAL.registerService(
692-
fireauth.exportlib.AUTH_TYPE,
693-
factory,
694-
namespace,
695-
// Initialize Auth when an App is created, so that tokens and Auth state
696-
// listeners are available.
697-
function (event, app) {
698-
if (event === 'create') {
699-
try {
700-
app[fireauth.exportlib.AUTH_TYPE]();
701-
} catch (e) {
702-
// This is a silent operation in the background. If the auth
703-
// initialization fails, it should not cause a fatal error.
704-
// Instead when the developer tries to initialize again manually,
705-
// the error will be thrown.
706-
// One specific use case here is the initialization for the nodejs
707-
// client when no API key is provided. This is commonly used
708-
// for unauthenticated database access.
709-
}
710-
}
711-
}
712-
);
713-
673+
// Create auth components to register with firebase.
674+
// Provides Auth public APIs.
675+
const authComponent = {
676+
'name': fireauth.exportlib.AUTH_TYPE,
677+
'instanceFactory': function(container) {
678+
var app = container['getProvider']('app')['getImmediate']();
679+
return new fireauth.Auth(app);
680+
},
681+
'multipleInstances': false,
682+
'serviceProps': namespace,
683+
'instantiationMode': 'LAZY',
684+
'type': 'PUBLIC'
685+
};
686+
687+
// Provides Auth internal APIs.
688+
const authInteropComponent = {
689+
'name': 'auth-internal',
690+
'instanceFactory': function(container) {
691+
var auth = container['getProvider'](fireauth.exportlib.AUTH_TYPE)['getImmediate']();
692+
return {
693+
'getUid': goog.bind(auth.getUid, auth),
694+
'getToken': goog.bind(auth.getIdTokenInternal, auth),
695+
'addAuthTokenListener':
696+
goog.bind(auth.addAuthTokenListenerInternal, auth),
697+
'removeAuthTokenListener':
698+
goog.bind(auth.removeAuthTokenListenerInternal, auth)
699+
};
700+
},
701+
'multipleInstances': false,
702+
'instantiationMode': 'LAZY',
703+
'type': 'PRIVATE'
704+
};
705+
706+
firebase.INTERNAL.registerComponent(authComponent);
707+
firebase.INTERNAL.registerComponent(authInteropComponent);
714708

715709
// Expose User as firebase.User.
716710
firebase.INTERNAL.extendNamespace({
717711
'User': fireauth.AuthUser
718712
});
719713
}
720-
})();
714+
})();

packages/auth/test/auth_test.js

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ var appId1 = 'appId1';
7373
var appId2 = 'appId2';
7474
var auth1 = null;
7575
var auth2 = null;
76+
var authInternal1 = null;
77+
var authInternal2 = null;
7678
var app1 = null;
7779
var app2 = null;
7880
var authUi1 = null;
@@ -1014,17 +1016,18 @@ function testGetUid_userSignedIn() {
10141016
// Initialize App and Auth.
10151017
app1 = firebase.initializeApp(config1, appId1);
10161018
auth1 = app1.auth();
1019+
authInternal1 = app1.container.getProvider('auth-internal').getImmediate();
10171020
// Initially getUid() should return null;
10181021
assertNull(auth1.getUid());
1019-
assertNull(app1.INTERNAL.getUid());
1022+
assertNull(authInternal1.getUid());
10201023
// Listen to Auth changes.
10211024
var unsubscribe = auth1.onIdTokenChanged(function(currentUser) {
10221025
// Unsubscribe of Auth state change listener.
10231026
unsubscribe();
10241027
// Logged in test user should be detected.
10251028
// Confirm getUid() returns expected UID.
10261029
assertEquals(accountInfo1['uid'], auth1.getUid());
1027-
assertEquals(accountInfo1['uid'], app1.INTERNAL.getUid());
1030+
assertEquals(accountInfo1['uid'], authInternal1.getUid());
10281031
goog.Timer.promise(10).then(function() {
10291032
// Sign out.
10301033
return auth1.signOut();
@@ -1033,7 +1036,7 @@ function testGetUid_userSignedIn() {
10331036
}).then(function() {
10341037
// getUid() should return null.
10351038
assertNull(auth1.getUid());
1036-
assertNull(app1.INTERNAL.getUid());
1039+
assertNull(authInternal1.getUid());
10371040
asyncTestCase.signal();
10381041
});
10391042
});
@@ -1065,19 +1068,20 @@ function testGetUid_noUserSignedIn() {
10651068
// Initialize App and Auth.
10661069
app1 = firebase.initializeApp(config1, appId1);
10671070
auth1 = app1.auth();
1071+
authInternal1 = app1.container.getProvider('auth-internal').getImmediate();
10681072
// Listen to Auth changes.
10691073
var unsubscribe = auth1.onIdTokenChanged(function(currentUser) {
10701074
// Unsubscribe of Auth state change listener.
10711075
unsubscribe();
10721076
// Initially getUid() should return null;
10731077
assertNull(auth1.getUid());
1074-
assertNull(app1.INTERNAL.getUid());
1078+
assertNull(authInternal1.getUid());
10751079
// Sign in with email and password.
10761080
auth1.signInWithEmailAndPassword('[email protected]', 'password')
10771081
.then(function(userCredential) {
10781082
// getUid() should return the test user UID.
10791083
assertEquals(accountInfo1['uid'], auth1.getUid());
1080-
assertEquals(accountInfo1['uid'], app1.INTERNAL.getUid());
1084+
assertEquals(accountInfo1['uid'], authInternal1.getUid());
10811085
asyncTestCase.signal();
10821086
});
10831087
});
@@ -1118,11 +1122,13 @@ function testNotifyAuthListeners() {
11181122
config1['apiKey'] + ':' + appId1);
11191123
currentUserStorageManager.setCurrentUser(user).then(function() {
11201124
app1 = firebase.initializeApp(config1, appId1);
1121-
app1.INTERNAL.addAuthTokenListener(app1AuthTokenListener);
11221125
auth1 = app1.auth();
1126+
authInternal1 = app1.container.getProvider('auth-internal').getImmediate();
1127+
authInternal1.addAuthTokenListener(app1AuthTokenListener);
11231128
app2 = firebase.initializeApp(config2, appId2);
1124-
app2.INTERNAL.addAuthTokenListener(app2AuthTokenListener);
11251129
auth2 = app2.auth();
1130+
authInternal2 = app2.container.getProvider('auth-internal').getImmediate();
1131+
authInternal2.addAuthTokenListener(app2AuthTokenListener);
11261132
// Confirm all listeners reset.
11271133
assertEquals(0, listener1.getCallCount());
11281134
assertEquals(0, listener2.getCallCount());
@@ -1170,7 +1176,7 @@ function testNotifyAuthListeners() {
11701176
app1AuthTokenListener.reset();
11711177
listener2.reset();
11721178
auth1.removeAuthTokenListener(listener2);
1173-
app1.INTERNAL.removeAuthTokenListener(app1AuthTokenListener);
1179+
authInternal1.removeAuthTokenListener(app1AuthTokenListener);
11741180
// Force token change.
11751181
currentAccessToken = 'accessToken3';
11761182
auth1['currentUser'].getIdToken().then(function(token) {
@@ -10077,7 +10083,7 @@ function testAuth_proactiveTokenRefresh_multipleUsers() {
1007710083
auth1 = app1.auth();
1007810084
var subscriber = function(token) {};
1007910085
// Simulate Firebase service added.
10080-
app1.INTERNAL.addAuthTokenListener(subscriber);
10086+
app1.container.getProvider('auth-internal').getImmediate().addAuthTokenListener(subscriber);
1008110087
// Simulate user1 signed in.
1008210088
auth1.signInWithIdTokenResponse(expectedTokenResponse).then(function() {
1008310089
// Current user should be set to user1.
@@ -10155,7 +10161,7 @@ function testAuth_proactiveTokenRefresh_firebaseServiceAddedAfterSignIn() {
1015510161
assertEquals(
1015610162
0, fireauth.AuthUser.prototype.startProactiveRefresh.getCallCount());
1015710163
// Simulate Firebase service added.
10158-
app1.INTERNAL.addAuthTokenListener(subscriber);
10164+
app1.container.getProvider('auth-internal').getImmediate().addAuthTokenListener(subscriber);
1015910165
// Confirm proactive refresh started on that user.
1016010166
assertEquals(
1016110167
1, fireauth.AuthUser.prototype.startProactiveRefresh.getCallCount());
@@ -10199,10 +10205,11 @@ function testAuth_proactiveTokenRefresh_firebaseServiceRemovedAfterSignIn() {
1019910205
auth1 = app1.auth();
1020010206
var subscriber = function(token) {};
1020110207
// Simulate Firebase service added.
10202-
app1.INTERNAL.addAuthTokenListener(subscriber);
10208+
authInternal1 = app1.container.getProvider('auth-internal').getImmediate();
10209+
authInternal1.addAuthTokenListener(subscriber);
1020310210
// Add same listener again to check that removing it once will ensure the
1020410211
// proactive refresh is stopped.
10205-
app1.INTERNAL.addAuthTokenListener(subscriber);
10212+
authInternal1.addAuthTokenListener(subscriber);
1020610213
// Simulate user signed in.
1020710214
auth1.signInWithIdTokenResponse(expectedTokenResponse).then(function() {
1020810215
// Current user should be set to user1.
@@ -10214,7 +10221,7 @@ function testAuth_proactiveTokenRefresh_firebaseServiceRemovedAfterSignIn() {
1021410221
assertEquals(
1021510222
0, fireauth.AuthUser.prototype.stopProactiveRefresh.getCallCount());
1021610223
// Simulate Firebase service removed.
10217-
app1.INTERNAL.removeAuthTokenListener(subscriber);
10224+
authInternal1.removeAuthTokenListener(subscriber);
1021810225
// Confirm proactive refresh stopped on that user.
1021910226
assertEquals(
1022010227
1, fireauth.AuthUser.prototype.stopProactiveRefresh.getCallCount());

packages/firebase/externs/firebase-app-internal-externs.js

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,9 @@
2020
*/
2121

2222
/**
23-
* @param {string} name Service name
24-
* @param {!firebase.ServiceFactory} createService
25-
* @param {Object=} serviceProperties
26-
* @param {(function(string, !firebase.app.App): void)=} appHook
27-
* @param {boolean=} allowMultipleInstances Whether the service registered
28-
* supports multiple instances on the same app.
29-
* @return {firebase.ServiceNamespace}
30-
*/
31-
firebase.INTERNAL.registerService = function(
32-
name,
33-
createService,
34-
serviceProperties,
35-
appHook,
36-
allowMultipleInstances
37-
) {};
23+
* @param {!firebase.FirebaseComponent}
24+
*/
25+
firebase.INTERNAL.registerComponent = function(component) {};
3826

3927
/** @param {!Object} props */
4028
firebase.INTERNAL.extendNamespace = function(props) {};

0 commit comments

Comments
 (0)