-
Notifications
You must be signed in to change notification settings - Fork 937
Added Firebase App Check support to Firebase Auth. #7191
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 all 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,6 @@ | ||
--- | ||
'@firebase/auth': minor | ||
'@firebase/auth-compat': minor | ||
--- | ||
|
||
[feature] Added Firebase App Check support to Firebase Auth. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,36 +63,38 @@ export function registerAuth(clientPlatform: ClientPlatform): void { | |
const app = container.getProvider('app').getImmediate()!; | ||
const heartbeatServiceProvider = | ||
container.getProvider<'heartbeat'>('heartbeat'); | ||
const appCheckServiceProvider = | ||
container.getProvider<'app-check-internal'>('app-check-internal'); | ||
const { apiKey, authDomain } = app.options; | ||
return ((app, heartbeatServiceProvider) => { | ||
_assert( | ||
apiKey && !apiKey.includes(':'), | ||
AuthErrorCode.INVALID_API_KEY, | ||
{ appName: app.name } | ||
); | ||
// Auth domain is optional if IdP sign in isn't being used | ||
_assert(!authDomain?.includes(':'), AuthErrorCode.ARGUMENT_ERROR, { | ||
appName: app.name | ||
}); | ||
const config: ConfigInternal = { | ||
apiKey, | ||
authDomain, | ||
clientPlatform, | ||
apiHost: DefaultConfig.API_HOST, | ||
tokenApiHost: DefaultConfig.TOKEN_API_HOST, | ||
apiScheme: DefaultConfig.API_SCHEME, | ||
sdkClientVersion: _getClientVersion(clientPlatform) | ||
}; | ||
|
||
const authInstance = new AuthImpl( | ||
app, | ||
heartbeatServiceProvider, | ||
config | ||
); | ||
_initializeAuthInstance(authInstance, deps); | ||
_assert( | ||
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. We were previously wrapping it as an anonymous function and invoking it right away, now we are just invoking it without that wrapper, correct? Adding @sam-gc to look at this section, since we had some past discussion about whether initializeAuthInstance needs to be invoked 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. Yep, just invoking without that wrapper - no changes have been made since https://github.com/firebase/firebase-js-sdk/pull/6982/files#r1089404274. 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. Yeah I think this is fine to do. It was unnecessarily complicated creating a throwaway anonymous function that's immediately called. 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. Cool thanks |
||
apiKey && !apiKey.includes(':'), | ||
AuthErrorCode.INVALID_API_KEY, | ||
{ appName: app.name } | ||
); | ||
// Auth domain is optional if IdP sign in isn't being used | ||
_assert(!authDomain?.includes(':'), AuthErrorCode.ARGUMENT_ERROR, { | ||
appName: app.name | ||
}); | ||
const config: ConfigInternal = { | ||
apiKey, | ||
authDomain, | ||
clientPlatform, | ||
apiHost: DefaultConfig.API_HOST, | ||
tokenApiHost: DefaultConfig.TOKEN_API_HOST, | ||
apiScheme: DefaultConfig.API_SCHEME, | ||
sdkClientVersion: _getClientVersion(clientPlatform) | ||
}; | ||
|
||
const authInstance = new AuthImpl( | ||
app, | ||
heartbeatServiceProvider, | ||
appCheckServiceProvider, | ||
config | ||
); | ||
_initializeAuthInstance(authInstance, deps); | ||
|
||
return authInstance; | ||
})(app, heartbeatServiceProvider); | ||
return authInstance; | ||
}, | ||
ComponentType.PUBLIC | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,13 @@ const WIDGET_PATH = '__/auth/handler'; | |
*/ | ||
const EMULATOR_WIDGET_PATH = 'emulator/auth/handler'; | ||
|
||
/** | ||
* Fragment name for the App Check token that gets passed to the widget | ||
* | ||
* @internal | ||
*/ | ||
const FIREBASE_APP_CHECK_FRAGMENT_ID = encodeURIComponent('fac'); | ||
|
||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions | ||
type WidgetParams = { | ||
apiKey: ApiKey; | ||
|
@@ -54,14 +61,14 @@ type WidgetParams = { | |
tid?: string; | ||
} & { [key: string]: string | undefined }; | ||
|
||
export function _getRedirectUrl( | ||
export async function _getRedirectUrl( | ||
auth: AuthInternal, | ||
provider: AuthProvider, | ||
authType: AuthEventType, | ||
redirectUrl?: string, | ||
eventId?: string, | ||
additionalParams?: Record<string, string> | ||
): string { | ||
): Promise<string> { | ||
_assert(auth.config.authDomain, auth, AuthErrorCode.MISSING_AUTH_DOMAIN); | ||
_assert(auth.config.apiKey, auth, AuthErrorCode.INVALID_API_KEY); | ||
|
||
|
@@ -107,7 +114,17 @@ export function _getRedirectUrl( | |
delete paramsDict[key]; | ||
} | ||
} | ||
return `${getHandlerBase(auth)}?${querystring(paramsDict).slice(1)}`; | ||
|
||
// Sets the App Check token to pass to the widget | ||
const appCheckToken = await auth._getAppCheckToken(); | ||
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. What will happen if _getAppCheckToken() failed? Should we return a url without an app check token, or throw an exception? 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.
|
||
const appCheckTokenFragment = appCheckToken | ||
? `#${FIREBASE_APP_CHECK_FRAGMENT_ID}=${encodeURIComponent(appCheckToken)}` | ||
: ''; | ||
|
||
// Start at index 1 to skip the leading '&' in the query string | ||
return `${getHandlerBase(auth)}?${querystring(paramsDict).slice( | ||
1 | ||
)}${appCheckTokenFragment}`; | ||
} | ||
|
||
function getHandlerBase({ config }: AuthInternal): string { | ||
|
Uh oh!
There was an error while loading. Please reload this page.