-
Notifications
You must be signed in to change notification settings - Fork 939
Migrate Auth to component framework #2342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# @firebase/auth-interop-types | ||
|
||
**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.** |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* @license | ||
* Copyright 2019 Google Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
export interface FirebaseAuthTokenData { | ||
accessToken: string; | ||
} | ||
|
||
export interface FirebaseAuthInternal { | ||
getToken(refreshToken?: boolean): Promise<FirebaseAuthTokenData | null>; | ||
getUid(): string | null; | ||
addAuthTokenListener(fn: (token: string | null) => void): void; | ||
removeAuthTokenListener(fn: (token: string | null) => void): void; | ||
} | ||
|
||
export type FirebaseAuthInternalName = 'auth-internal'; | ||
|
||
declare module '@firebase/component' { | ||
interface NameServiceMapping { | ||
'auth-internal': FirebaseAuthInternal; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"name": "@firebase/auth-interop-types", | ||
"version": "0.1.0", | ||
"description": "@firebase/auth interop Types", | ||
"author": "Firebase <[email protected]> (https://firebase.google.com/)", | ||
"license": "Apache-2.0", | ||
"scripts": { | ||
"test": "tsc" | ||
}, | ||
"files": [ | ||
"index.d.ts" | ||
], | ||
"peerDependencies": { | ||
"@firebase/app-types": "0.x", | ||
"@firebase/util": "0.x" | ||
}, | ||
"repository": { | ||
"directory": "packages/auth-types", | ||
"type": "git", | ||
"url": "https://github.com/firebase/firebase-js-sdk.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/firebase/firebase-js-sdk/issues" | ||
}, | ||
"devDependencies": { | ||
"typescript": "3.6.4" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "../../config/tsconfig.base.json", | ||
"compilerOptions": { | ||
"noEmit": true | ||
}, | ||
"exclude": [ | ||
"dist/**/*" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -618,27 +618,10 @@ fireauth.exportlib.exportFunction( | |
|
||
(function() { | ||
if (typeof firebase === 'undefined' || !firebase.INTERNAL || | ||
!firebase.INTERNAL.registerService) { | ||
!firebase.INTERNAL.registerComponent) { | ||
throw new Error('Cannot find the firebase namespace; be sure to include ' + | ||
'firebase-app.js before this library.'); | ||
} else { | ||
/** @type {!firebase.ServiceFactory} */ | ||
var factory = function(app, extendApp) { | ||
var auth = new fireauth.Auth(app); | ||
extendApp({ | ||
'INTERNAL': { | ||
// Extend app.INTERNAL.getUid. | ||
'getUid': goog.bind(auth.getUid, auth), | ||
'getToken': goog.bind(auth.getIdTokenInternal, auth), | ||
'addAuthTokenListener': | ||
goog.bind(auth.addAuthTokenListenerInternal, auth), | ||
'removeAuthTokenListener': | ||
goog.bind(auth.removeAuthTokenListenerInternal, auth) | ||
} | ||
}); | ||
return auth; | ||
}; | ||
|
||
var namespace = { | ||
// Exports firebase.auth.ActionCodeInfo.Operation. | ||
'ActionCodeInfo': { | ||
|
@@ -687,34 +670,43 @@ fireauth.exportlib.exportFunction( | |
fireauth.exportlib.exportFunction(namespace, | ||
'ActionCodeURL', fireauth.ActionCodeURL, []); | ||
|
||
// Register Auth service with firebase.App. | ||
firebase.INTERNAL.registerService( | ||
fireauth.exportlib.AUTH_TYPE, | ||
factory, | ||
namespace, | ||
// Initialize Auth when an App is created, so that tokens and Auth state | ||
// listeners are available. | ||
function (event, app) { | ||
if (event === 'create') { | ||
try { | ||
app[fireauth.exportlib.AUTH_TYPE](); | ||
} catch (e) { | ||
// This is a silent operation in the background. If the auth | ||
// initialization fails, it should not cause a fatal error. | ||
// Instead when the developer tries to initialize again manually, | ||
// the error will be thrown. | ||
// One specific use case here is the initialization for the nodejs | ||
// client when no API key is provided. This is commonly used | ||
// for unauthenticated database access. | ||
} | ||
} | ||
} | ||
); | ||
|
||
// Create auth components to register with firebase | ||
const authComponent = { // provides Auth public APIs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preferably move comment to newline. Capitalize first letter and add dot to end of line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
'name': fireauth.exportlib.AUTH_TYPE, | ||
'instanceFactory': function(container) { | ||
var app = container['getProvider']('app')['getImmediate'](); | ||
return new fireauth.Auth(app); | ||
}, | ||
'multipleInstances': false, | ||
'serviceProps': namespace, | ||
'instantiationMode': 'LAZY', | ||
'type': 'PUBLIC' | ||
}; | ||
|
||
const authInteropComponent = { // provides Auth internal APIs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
'name': 'auth-internal', | ||
'instanceFactory': function(container) { | ||
var auth = container['getProvider'](fireauth.exportlib.AUTH_TYPE)['getImmediate'](); | ||
return { | ||
'getUid': goog.bind(auth.getUid, auth), | ||
'getToken': goog.bind(auth.getIdTokenInternal, auth), | ||
'addAuthTokenListener': | ||
goog.bind(auth.addAuthTokenListenerInternal, auth), | ||
'removeAuthTokenListener': | ||
goog.bind(auth.removeAuthTokenListenerInternal, auth) | ||
}; | ||
}, | ||
'multipleInstances': false, | ||
'instantiationMode': 'LAZY', | ||
'type': 'PRIVATE' | ||
}; | ||
|
||
firebase.INTERNAL.registerComponent(authComponent); | ||
firebase.INTERNAL.registerComponent(authInteropComponent); | ||
|
||
// Expose User as firebase.User. | ||
firebase.INTERNAL.extendNamespace({ | ||
'User': fireauth.AuthUser | ||
}); | ||
} | ||
})(); | ||
})(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,8 @@ var appId1 = 'appId1'; | |
var appId2 = 'appId2'; | ||
var auth1 = null; | ||
var auth2 = null; | ||
var authInternal1 = null; | ||
var authInternal2 = null; | ||
var app1 = null; | ||
var app2 = null; | ||
var authUi1 = null; | ||
|
@@ -1014,17 +1016,18 @@ function testGetUid_userSignedIn() { | |
// Initialize App and Auth. | ||
app1 = firebase.initializeApp(config1, appId1); | ||
auth1 = app1.auth(); | ||
authInternal1 = app1.container.getProvider('auth-internal').getImmediate(); | ||
// Initially getUid() should return null; | ||
assertNull(auth1.getUid()); | ||
assertNull(app1.INTERNAL.getUid()); | ||
assertNull(authInternal1.getUid()); | ||
// Listen to Auth changes. | ||
var unsubscribe = auth1.onIdTokenChanged(function(currentUser) { | ||
// Unsubscribe of Auth state change listener. | ||
unsubscribe(); | ||
// Logged in test user should be detected. | ||
// Confirm getUid() returns expected UID. | ||
assertEquals(accountInfo1['uid'], auth1.getUid()); | ||
assertEquals(accountInfo1['uid'], app1.INTERNAL.getUid()); | ||
assertEquals(accountInfo1['uid'], authInternal1.getUid()); | ||
goog.Timer.promise(10).then(function() { | ||
// Sign out. | ||
return auth1.signOut(); | ||
|
@@ -1033,7 +1036,7 @@ function testGetUid_userSignedIn() { | |
}).then(function() { | ||
// getUid() should return null. | ||
assertNull(auth1.getUid()); | ||
assertNull(app1.INTERNAL.getUid()); | ||
assertNull(authInternal1.getUid()); | ||
asyncTestCase.signal(); | ||
}); | ||
}); | ||
|
@@ -1065,19 +1068,20 @@ function testGetUid_noUserSignedIn() { | |
// Initialize App and Auth. | ||
app1 = firebase.initializeApp(config1, appId1); | ||
auth1 = app1.auth(); | ||
authInternal1 = app1.container.getProvider('auth-internal').getImmediate(); | ||
// Listen to Auth changes. | ||
var unsubscribe = auth1.onIdTokenChanged(function(currentUser) { | ||
// Unsubscribe of Auth state change listener. | ||
unsubscribe(); | ||
// Initially getUid() should return null; | ||
assertNull(auth1.getUid()); | ||
assertNull(app1.INTERNAL.getUid()); | ||
assertNull(authInternal1.getUid()); | ||
// Sign in with email and password. | ||
auth1.signInWithEmailAndPassword('[email protected]', 'password') | ||
.then(function(userCredential) { | ||
// getUid() should return the test user UID. | ||
assertEquals(accountInfo1['uid'], auth1.getUid()); | ||
assertEquals(accountInfo1['uid'], app1.INTERNAL.getUid()); | ||
assertEquals(accountInfo1['uid'], authInternal1.getUid()); | ||
asyncTestCase.signal(); | ||
}); | ||
}); | ||
|
@@ -1118,11 +1122,13 @@ function testNotifyAuthListeners() { | |
config1['apiKey'] + ':' + appId1); | ||
currentUserStorageManager.setCurrentUser(user).then(function() { | ||
app1 = firebase.initializeApp(config1, appId1); | ||
app1.INTERNAL.addAuthTokenListener(app1AuthTokenListener); | ||
auth1 = app1.auth(); | ||
authInternal1 = app1.container.getProvider('auth-internal').getImmediate(); | ||
authInternal1.addAuthTokenListener(app1AuthTokenListener); | ||
app2 = firebase.initializeApp(config2, appId2); | ||
app2.INTERNAL.addAuthTokenListener(app2AuthTokenListener); | ||
auth2 = app2.auth(); | ||
authInternal2 = app2.container.getProvider('auth-internal').getImmediate(); | ||
authInternal2.addAuthTokenListener(app2AuthTokenListener); | ||
// Confirm all listeners reset. | ||
assertEquals(0, listener1.getCallCount()); | ||
assertEquals(0, listener2.getCallCount()); | ||
|
@@ -1170,7 +1176,7 @@ function testNotifyAuthListeners() { | |
app1AuthTokenListener.reset(); | ||
listener2.reset(); | ||
auth1.removeAuthTokenListener(listener2); | ||
app1.INTERNAL.removeAuthTokenListener(app1AuthTokenListener); | ||
authInternal1.removeAuthTokenListener(app1AuthTokenListener); | ||
// Force token change. | ||
currentAccessToken = 'accessToken3'; | ||
auth1['currentUser'].getIdToken().then(function(token) { | ||
|
@@ -10077,7 +10083,7 @@ function testAuth_proactiveTokenRefresh_multipleUsers() { | |
auth1 = app1.auth(); | ||
var subscriber = function(token) {}; | ||
// Simulate Firebase service added. | ||
app1.INTERNAL.addAuthTokenListener(subscriber); | ||
app1.container.getProvider('auth-internal').getImmediate().addAuthTokenListener(subscriber); | ||
// Simulate user1 signed in. | ||
auth1.signInWithIdTokenResponse(expectedTokenResponse).then(function() { | ||
// Current user should be set to user1. | ||
|
@@ -10155,7 +10161,7 @@ function testAuth_proactiveTokenRefresh_firebaseServiceAddedAfterSignIn() { | |
assertEquals( | ||
0, fireauth.AuthUser.prototype.startProactiveRefresh.getCallCount()); | ||
// Simulate Firebase service added. | ||
app1.INTERNAL.addAuthTokenListener(subscriber); | ||
app1.container.getProvider('auth-internal').getImmediate().addAuthTokenListener(subscriber); | ||
// Confirm proactive refresh started on that user. | ||
assertEquals( | ||
1, fireauth.AuthUser.prototype.startProactiveRefresh.getCallCount()); | ||
|
@@ -10199,10 +10205,11 @@ function testAuth_proactiveTokenRefresh_firebaseServiceRemovedAfterSignIn() { | |
auth1 = app1.auth(); | ||
var subscriber = function(token) {}; | ||
// Simulate Firebase service added. | ||
app1.INTERNAL.addAuthTokenListener(subscriber); | ||
authInternal1 = app1.container.getProvider('auth-internal').getImmediate(); | ||
authInternal1.addAuthTokenListener(subscriber); | ||
// Add same listener again to check that removing it once will ensure the | ||
// proactive refresh is stopped. | ||
app1.INTERNAL.addAuthTokenListener(subscriber); | ||
authInternal1.addAuthTokenListener(subscriber); | ||
// Simulate user signed in. | ||
auth1.signInWithIdTokenResponse(expectedTokenResponse).then(function() { | ||
// Current user should be set to user1. | ||
|
@@ -10214,7 +10221,7 @@ function testAuth_proactiveTokenRefresh_firebaseServiceRemovedAfterSignIn() { | |
assertEquals( | ||
0, fireauth.AuthUser.prototype.stopProactiveRefresh.getCallCount()); | ||
// Simulate Firebase service removed. | ||
app1.INTERNAL.removeAuthTokenListener(subscriber); | ||
authInternal1.removeAuthTokenListener(subscriber); | ||
// Confirm proactive refresh stopped on that user. | ||
assertEquals( | ||
1, fireauth.AuthUser.prototype.stopProactiveRefresh.getCallCount()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Add dot at the end of the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.