Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/google_sign_in/google_sign_in_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 1.0.0

* Flutter for web initial release
26 changes: 26 additions & 0 deletions packages/google_sign_in/google_sign_in_web/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Copyright 2016, the Flutter project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66 changes: 66 additions & 0 deletions packages/google_sign_in/google_sign_in_web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# google_sign_in_web
Comment thread
ditman marked this conversation as resolved.

The web implementation of [google_sign_in](https://pub.dev/google_sign_in/google_sign_in)

## Web integration

First, go through the instructions [here](https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin) to create your Google Sign-In OAuth client ID.

On your `web/index.html` file, add the following `meta` tag, somewhere in the
`head` of the document:

```
<meta name="google-signin-client_id" content="YOUR_GOOGLE_SIGN_IN_OAUTH_CLIENT_ID.apps.googleusercontent.com">
```

Read the rest of the instructions if you need to add extra APIs (like Google People API).


## Usage

### Import the package
To use this plugin, follow the [plugin installation instructions](https://pub.dartlang.org/packages/google_sign_in#pub-pkg-tab-installing).

### Use the plugin
Add the following import to your Dart code:

```dart
import 'package:google_sign_in/google_sign_in.dart';
```

Initialize GoogleSignIn with the scopes you want:

```dart
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
```
[Full list of available scopes](https://developers.google.com/identity/protocols/googlescopes).

You can now use the `GoogleSignIn` class to authenticate in your Dart code, e.g.

```dart
Future<void> _handleSignIn() async {
try {
await _googleSignIn.signIn();
} catch (error) {
print(error);
}
}
```

## Example

Find the example wiring in the [Google sign-in example application](https://github.com/flutter/plugins/blob/master/packages/google_sign_in/google_sign_in/example/lib/main.dart).

## API details

See the [google_sign_in.dart](https://github.com/flutter/plugins/blob/master/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart) for more API details.

## Issues and feedback

Please file [issues](https://github.com/flutter/flutter/issues/new)
to send feedback or report a bug. Thank you!
149 changes: 149 additions & 0 deletions packages/google_sign_in/google_sign_in_web/lib/google_sign_in_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:html' as html;

import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:js/js.dart';
import 'package:meta/meta.dart';

import 'src/generated/gapiauth2.dart' as auth2;
// TODO: Remove once this lands https://github.com/dart-lang/language/issues/671
import 'src/generated/gapiauth2.dart' show GoogleAuthExtensions;
import 'src/load_gapi.dart' as gapi;
import 'src/utils.dart' show gapiUserToPluginUserData;

const String _kClientIdMetaSelector = 'meta[name=google-signin-client_id]';
const String _kClientIdAttributeName = 'content';

@visibleForTesting
String gapiUrl = 'https://apis.google.com/js/platform.js';

/// Implementation of the google_sign_in plugin for Web
class GoogleSignInPlugin extends GoogleSignInPlatform {
GoogleSignInPlugin() {
_autoDetectedClientId = html
.querySelector(_kClientIdMetaSelector)
?.getAttribute(_kClientIdAttributeName);

_isGapiInitialized = gapi.inject(gapiUrl).then((_) => gapi.init()).then((_) {
isInitialized = true;
});
}

Future<void> _isGapiInitialized;

@visibleForTesting
Future<void> get isInitializing => _isGapiInitialized;
Comment thread
ditman marked this conversation as resolved.
Outdated
@visibleForTesting
bool isInitialized;
Comment thread
ditman marked this conversation as resolved.
Outdated

String _autoDetectedClientId;
FutureOr<auth2.GoogleUser> _lastSeenUser;

static void registerWith(Registrar registrar) {
GoogleSignInPlatform.instance = GoogleSignInPlugin();
}

@override
Future<void> init(
{@required String hostedDomain,
List<String> scopes = const <String>[],
SignInOption signInOption = SignInOption.standard,
String clientId}) async {
final String appClientId = clientId ?? _autoDetectedClientId;
assert(
appClientId != null,
'ClientID not set. Either set it on a '
'<meta name="google-signin-client_id" content="CLIENT_ID" /> tag,'
' or pass clientId when calling init()');

await _isGapiInitialized;

// This init returns an user, so let's wait for its future
Comment thread
ditman marked this conversation as resolved.
Outdated
final auth2.GoogleAuth auth = auth2.init(auth2.ClientConfig(
hosted_domain: hostedDomain,
// The js lib wants a space-separated list of values
scope: scopes.join(' '),
Comment thread
ditman marked this conversation as resolved.
client_id: appClientId,
));

// Subscribe to changes in the auth user, and cache the latest seen for signInSilently
final Completer<auth2.GoogleUser> initUserCompleter =
Completer<auth2.GoogleUser>();

auth.currentUser.listen(allowInterop((auth2.GoogleUser nextUser) {
if (!initUserCompleter.isCompleted) {
initUserCompleter.complete(nextUser);
} else {
_lastSeenUser = nextUser;
}
}));
_lastSeenUser = initUserCompleter.future;

return null;
}

@override
Future<GoogleSignInUserData> signInSilently() async {
await _isGapiInitialized;

return gapiUserToPluginUserData(await _lastSeenUser);
}

@override
Future<GoogleSignInUserData> signIn() async {
await _isGapiInitialized;

return gapiUserToPluginUserData(await auth2.getAuthInstance().signIn());
}

@override
Future<GoogleSignInTokenData> getTokens(
{@required String email, bool shouldRecoverAuth}) async {
await _isGapiInitialized;

final auth2.GoogleUser currentUser =
auth2.getAuthInstance()?.currentUser?.get();
final auth2.AuthResponse response = currentUser.getAuthResponse();

return GoogleSignInTokenData(
idToken: response.id_token, accessToken: response.access_token);
}

@override
Future<void> signOut() async {
await _isGapiInitialized;

return auth2.getAuthInstance().signOut();
}

@override
Future<void> disconnect() async {
await _isGapiInitialized;

final auth2.GoogleUser currentUser =
auth2.getAuthInstance()?.currentUser?.get();
return currentUser.disconnect();
}

@override
Future<bool> isSignedIn() async {
await _isGapiInitialized;

final auth2.GoogleUser currentUser =
auth2.getAuthInstance()?.currentUser?.get();
return currentUser.isSignedIn();
}

@override
Future<void> clearAuthCache({String token}) async {
await _isGapiInitialized;

_lastSeenUser = null;
return auth2.getAuthInstance().disconnect();
}
}
Loading