Skip to content

Commit

Permalink
One tap migration (#714)
Browse files Browse the repository at this point in the history
* Migrates to new one-tap sign-up API

Legacy one-tap API is being shutdown on 6/30/2020.

Migrates to new one-tap sign-up API:
https://developers.google.com/identity/one-tap/web/

All existing functionality is maintained.

* Adds missing config_test.js

* Disabled Microsoft Edge browser due to instability.

* Update CHANGELOG for upcoming release.
  • Loading branch information
bojeil-google authored Jun 3, 2020
1 parent 7404a41 commit bc42a21
Show file tree
Hide file tree
Showing 18 changed files with 399 additions and 634 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules/
generated/
out/
dist/
.firebase

# Generated files.
*.log
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Migrated to new one-tap sign-up API.
* Fixed issue when existing email link user tries to sign in when only email/password sign-in method is provided.
68 changes: 66 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ FirebaseUI includes the following flows:
by default.)
6. [Account Chooser](https://www.accountchooser.com/learnmore.html?lang=en) for
remembering emails
7. Ability to upgrade anonymous users through sign-in/sign-up
8. Sign-in as a guest
7. Integration with
[one-tap sign-up](https://developers.google.com/identity/one-tap/web/)
8. Ability to upgrade anonymous users through sign-in/sign-up.
9. Sign-in as a guest

### Configuring sign-in providers

Expand Down Expand Up @@ -452,6 +454,7 @@ When one is enabled, your users will be prompted with email addresses and
usernames they have saved from your app or other applications.
FirebaseUI supports the following credential helpers:

- [one-tap sign-up](https://developers.google.com/identity/one-tap/web/)
- [accountchooser.com](https://www.accountchooser.com/learnmore.html)

#### accountchooser.com
Expand All @@ -463,9 +466,70 @@ website and will be able to select one of their saved accounts. You can
disable it by specifying the value below. This feature is always disabled for
non HTTP/HTTPS environments.

#### One-tap sign-up

[One-tap sign-up](https://developers.google.com/identity/one-tap/web/)
provides seamless authentication flows to
your users with Google's one tap sign-up and automatic sign-in APIs.
With one tap sign-up, users are prompted to create an account with a dialog
that's inline with FirebaseUI NASCAR screen. With just one tap, they get a
secure, token-based, passwordless account with your service, protected by their
Google Account. As the process is frictionless, users are much more likely to
register.
Returning users are signed in automatically, even when they switch devices or
platforms, or after their session expires.
One-tap sign-up integrates with FirebaseUI and if you request Google OAuth
scopes, you will still get back the expected Google OAuth access token even if
the user goes through the one-tap flow. However, in that case 'redirect' flow is
always used even when 'popup' is specified.
In addition, if you choose to force prompt for Google sign-in, one-tap auto
sign-in will be automatically disabled.
One-tap is an additive feature and is only supported in the latest evergreen
modern browser environments.
For more information on how to configure one-tap sign-up, refer to the
[one-tap get started guide](https://developers.google.com/identity/one-tap/web/guides/get-google-api-clientid).

The following example shows how to configure one-tap sign-up with FirebaseUI.
Along with the corresponding one-tap `credentialHelper`, the Google OAuth
`clientId` has to be provided with the Firebase Google provider:

```javascript
ui.start('#firebaseui-auth-container', {
signInOptions: [
{
// Google provider must be enabled in Firebase Console to support one-tap
// sign-up.
provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
// Required to enable ID token credentials for this provider.
// This can be obtained from the Credentials page of the Google APIs
// console. Use the same OAuth client ID used for the Google provider
// configured with GCIP or Firebase Auth.
clientId: 'xxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
},
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
],
// Required to enable one-tap sign-up credential helper.
credentialHelper: firebaseui.auth.CredentialHelper.GOOGLE_YOLO
});
// Auto sign-in for returning users is enabled by default except when prompt is
// not 'none' in the Google provider custom parameters. To manually disable:
ui.disableAutoSignIn();
```

Auto sign-in for returning users can be disabled by calling
`ui.disableAutoSignIn()`. This may be needed if the FirebaseUI sign-in page is
being rendered after the user signs out.

To see FirebaseUI in action with one-tap sign-up, check out the FirebaseUI
[demo app](https://fir-ui-demo-84a6c.firebaseapp.com/).

|Credential Helper |Value |
|------------------|------------------------------------------------------|
|accountchooser.com|`firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM`|
|One-tap sign-up |`firebaseui.auth.CredentialHelper.GOOGLE_YOLO` |
|None (disable) |`firebaseui.auth.CredentialHelper.NONE` |

### Available providers
Expand Down
2 changes: 0 additions & 2 deletions demo/public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ function getUiConfig() {
// TODO(developer): Remove the providers you don't need for your app.
{
provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
// Required to enable this provider in One-Tap Sign-up.
authMethod: 'https://accounts.google.com',
// Required to enable ID token credentials for this provider.
clientId: CLIENT_ID
},
Expand Down
2 changes: 0 additions & 2 deletions demo/public/widget.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
// TODO(developer): Remove the providers you don't need for your app.
{
provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
// Required to enable this provider in One-Tap Sign-up.
authMethod: 'https://accounts.google.com',
// Required to enable ID token credentials for this provider.
clientId: CLIENT_ID
},
Expand Down
118 changes: 20 additions & 98 deletions javascript/externs/googleyolo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
/**
* Smart Lock API externs.
* Note that this SDK is not dedicated to One-tap API. It seems to cover other
* Google sign-in related functionality. We may want to consider renaming
* these APIs to not be One-tap specific.
* https://developers.google.com/identity/one-tap/web/reference/js-reference
*
* @externs
*/
Expand All @@ -8,55 +12,32 @@
* @record
* @struct
*/
function SmartLockHintOptions() {}
function SmartLockOptions() {}

/** @type {!Array<string>} */
SmartLockHintOptions.prototype.supportedAuthMethods;

/** @type {!Array<!Object<string,string>>} */
SmartLockHintOptions.prototype.supportedIdTokenProviders;

/** @type {?string|undefined} */
SmartLockHintOptions.prototype.context;

/**
* @record
* @struct
*/
function SmartLockRequestOptions() {}
/** @type {string} */
SmartLockOptions.prototype.client_id;

/** @type {!Array<string>} */
SmartLockRequestOptions.prototype.supportedAuthMethods;
/** @type {?boolean|undefined} */
SmartLockOptions.prototype.auto_select;

/** @type {!Array<!Object<string,string>>} */
SmartLockRequestOptions.prototype.supportedIdTokenProviders;
/** @type {function(SmartLockCredential)} */
SmartLockOptions.prototype.callback;

/** @type {?string|undefined} */
SmartLockRequestOptions.prototype.context;

/**
* @record
* @struct
*/
function SmartLockCredential() {}

/** @type {string} */
SmartLockCredential.prototype.id;

/** @type {string} */
SmartLockCredential.prototype.authMethod;

/** @type {string|undefined} */
SmartLockCredential.prototype.authDomain;
SmartLockCredential.prototype.credential;

/** @type {string|undefined} */
SmartLockCredential.prototype.displayName;
SmartLockCredential.prototype.clientId;

/** @type {string|undefined} */
SmartLockCredential.prototype.profilePicture;

/** @type {string|undefined} */
SmartLockCredential.prototype.idToken;
SmartLockCredential.prototype.select_by;

/**
* @record
Expand All @@ -65,80 +46,21 @@ SmartLockCredential.prototype.idToken;
function SmartLockApi() {}

/**
* Requests the credential provider whether hints are available or not for
* the current user.
*
* @param {!SmartLockHintOptions} options
* Describes the types of credentials that are supported by the origin.
* @return {!Promise<boolean>}
* A promise that resolves with true if at least one hint is available,
* and resolves with false if none are available. The promise will not
* reject: if an error happen, it should resolve with false.
*/
SmartLockApi.prototype.hintsAvailable = function(options) {};

/**
* Attempts to retrieve a sign-up hint that can be used to create a new
* user account.
* Initializes GSI sign in process.
*
* @param {!SmartLockHintOptions} options
* @param {!SmartLockOptions} options
* Describes the types of credentials that are supported by the origin,
* and customization properties for the display of any UI pertaining to
* releasing this credential.
* @return {!Promise<!SmartLockCredential>}
* A promise for a credential hint. The promise will be rejected if the
* user cancels the hint selection process, if there are no hints available,
* or if an error happens.
*/
SmartLockApi.prototype.hint = function(options) {};

/**
* Attempts to retrieve a credential for the current origin.
*
* @param {!SmartLockRequestOptions} options
* Describes the types of credentials that are supported by the origin.
* @return {!Promise<!SmartLockCredential>}
* A promise for the credential, which will be rejected if there are no
* credentials available or the user refuses to release the credential.
* Otherwise, the promise will resolve with a credential that the app
* can use.
*/
SmartLockApi.prototype.retrieve = function(options) {};
SmartLockApi.prototype.initialize = function(options) {};

/**
* Prevents the automatic release of a credential from the retrieve operation.
* This should be invoked when the user signs out, in order to prevent an
* automatic sign-in loop. This cannot be called while another operation is
* pending so should be called before retrieve.
* @return {!Promise<void>}
* A promise for the completion of notifying the provider to disable
* automatic sign-in.
* Triggers the prompt to display.
*/
SmartLockApi.prototype.disableAutoSignIn = function() {};
SmartLockApi.prototype.prompt = function() {};

/**
* Cancels the last operation triggered.
* @return {!Promise<void>}
* A promise for the completion of the cancellation.
*/
SmartLockApi.prototype.cancelLastOperation = function() {};

/**
* Sets a custom timeouts, in milliseconds, after which a request is
* considered failed.
* @param {number|null} timeoutMs The timeout in milliseconds.
*/
SmartLockApi.prototype.setTimeouts = function(timeoutMs) {};

/**
* Sets the render mode of the credentials selector, or null if the default
* should be used. Available render modes are: 'bottomSheet' and 'navPopout'.
* @param {string|null} renderMode
*/
SmartLockApi.prototype.setRenderMode = function(renderMode) {};

/** @type {!SmartLockApi} */
var googleyolo;

/** @type {function(!SmartLockApi)|undefined} */
var onGoogleYoloLoad;
SmartLockApi.prototype.cancel = function() {};
Loading

0 comments on commit bc42a21

Please sign in to comment.