From 644d5ccf9152a1db034e62b93b4d0b6632baaa56 Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 13 Sep 2017 16:20:38 -0400 Subject: [PATCH] Support Google login (two-factor auth) (#999) This doesn't support setting accounts up for Google login: that still has to be manually done via the database by setting the email field to `username@gmail.com@`, where the second `@` denotes that it's using Gmail login. If the email field does end in `@`, `getassertion` will note this by sending `;;@gmail`, to convey that the server is expecting a Google login token rather than a password. Upon receiving `;;@gmail`, the client will replace the password box will with a Google login button, and then send the resulting Google login token to the server in the `password` field. The server will validate the "password" using the Google server libraries, and otherwise handle the login as normal. Note that Google login requires various features that a paranoid person might disable; most notably 3rd-party cookies. Fixes Zarel/Pokemon-Showdown#3394 --- .gitignore | 1 + composer.json | 5 + composer.lock | 702 +++++++++++++++++++++++++++++++++++++++ index.template.html | 1 + js/client-topbar.js | 38 ++- js/client.js | 16 +- lib/ntbb-session.lib.php | 15 +- 7 files changed, 771 insertions(+), 7 deletions(-) create mode 100644 composer.json create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 449eabe506..9cf5f5f3b9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ eslint-cache/ .DS_Store Thumbs.db npm-debug.log +/vendor/ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000..67adc13550 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "google/apiclient": "^2.2" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..18a890526c --- /dev/null +++ b/composer.lock @@ -0,0 +1,702 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "14b5b31e2f70798045355d7ca0e8c52a", + "packages": [ + { + "name": "firebase/php-jwt", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "9984a4d3a32ae7673d6971ea00bae9d0a1abba0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/9984a4d3a32ae7673d6971ea00bae9d0a1abba0e", + "reference": "9984a4d3a32ae7673d6971ea00bae9d0a1abba0e", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": " 4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "time": "2017-06-27T22:17:23+00:00" + }, + { + "name": "google/apiclient", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/google/google-api-php-client.git", + "reference": "f3fadd538315d62ebd1191d89ac791468c617260" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/google/google-api-php-client/zipball/f3fadd538315d62ebd1191d89ac791468c617260", + "reference": "f3fadd538315d62ebd1191d89ac791468c617260", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "~2.0|~3.0|~4.0|~5.0", + "google/apiclient-services": "~0.13", + "google/auth": "^1.0", + "guzzlehttp/guzzle": "~5.3.1|~6.0", + "guzzlehttp/psr7": "^1.2", + "monolog/monolog": "^1.17", + "php": ">=5.4", + "phpseclib/phpseclib": "~0.3.10|~2.0" + }, + "require-dev": { + "cache/filesystem-adapter": "^0.3.2", + "phpunit/phpunit": "~4", + "squizlabs/php_codesniffer": "~2.3", + "symfony/css-selector": "~2.1", + "symfony/dom-crawler": "~2.1" + }, + "suggest": { + "cache/filesystem-adapter": "For caching certs and tokens (using Google_Client::setCache)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Google_": "src/" + }, + "classmap": [ + "src/Google/Service/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Client library for Google APIs", + "homepage": "http://developers.google.com/api-client-library/php", + "keywords": [ + "google" + ], + "time": "2017-07-10T15:34:54+00:00" + }, + { + "name": "google/apiclient-services", + "version": "v0.21", + "source": { + "type": "git", + "url": "https://github.com/google/google-api-php-client-services.git", + "reference": "b8282036684f2989e820b7830e8270f337304f23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/b8282036684f2989e820b7830e8270f337304f23", + "reference": "b8282036684f2989e820b7830e8270f337304f23", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-0": { + "Google_Service_": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Client library for Google APIs", + "homepage": "http://developers.google.com/api-client-library/php", + "keywords": [ + "google" + ], + "time": "2017-08-28T00:23:45+00:00" + }, + { + "name": "google/auth", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/google/google-auth-library-php.git", + "reference": "db8e3022a308cb0e988026d38e67b91a42b41622" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/google/google-auth-library-php/zipball/db8e3022a308cb0e988026d38e67b91a42b41622", + "reference": "db8e3022a308cb0e988026d38e67b91a42b41622", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "~2.0|~3.0|~4.0|~5.0", + "guzzlehttp/guzzle": "~5.3.1|~6.0", + "guzzlehttp/psr7": "~1.2", + "php": ">=5.4", + "psr/cache": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^1.11", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ], + "psr-4": { + "Google\\Auth\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Auth Library for PHP", + "homepage": "http://github.com/google/google-auth-library-php", + "keywords": [ + "Authentication", + "google", + "oauth2" + ], + "time": "2017-07-31T16:34:40+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0 || ^5.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2017-06-22T18:50:49+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2017-03-20T17:10:46+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.23.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2017-06-19T01:22:40+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34a7699e6f31b1ef4035ee36444407cecf9f56aa", + "reference": "34a7699e6f31b1ef4035ee36444407cecf9f56aa", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "~4.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "time": "2017-06-05T06:31:10+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/index.template.html b/index.template.html index 0bd4696935..0d93be3cdd 100644 --- a/index.template.html +++ b/index.template.html @@ -46,6 +46,7 @@ + diff --git a/js/client-topbar.js b/js/client-topbar.js index a430624106..b21e4031b9 100644 --- a/js/client-topbar.js +++ b/js/client-topbar.js @@ -923,14 +923,48 @@ buf += '

Log in:

'; buf += '

'; - buf += '

'; - buf += '

'; + if (data.special === '@gmail') { + buf += '
[loading Google log-in button]
'; + buf += '

'; + } else { + buf += '

'; + buf += '

'; + } buf += '

or

'; buf += '

'; buf += ''; this.$el.html(buf); + + if (data.special === '@gmail') { + var self = this; + window.gapiRenderButton = function () { + gapi.signin2.render('gapi-custom-signin', { // eslint-disable-line no-undef + 'scope': 'email', + 'width': 240, + 'height': 50, + 'longtitle': true, + 'theme': 'dark', + 'onsuccess': function (googleUser) { + var profile = googleUser.getBasicProfile(); + var id_token = googleUser.getAuthResponse().id_token; + self.close(); + app.user.passwordRename(data.username, id_token, data.special); + }, + 'onfailure': function (googleUser) { + alert('sign-in failed'); + } + }); + }; + if (window.gapiLoaded) return setTimeout(window.gapiRenderButton, 100); + window.gapiLoaded = true; + + var script = document.createElement('script'); + script.async = true; + script.src = 'https://apis.google.com/js/platform.js?onload=gapiRenderButton'; + document.getElementsByTagName('head')[0].appendChild(script); + } }, login: function () { this.close(); diff --git a/js/client.js b/js/client.js index e59939f7a8..27a0ae6667 100644 --- a/js/client.js +++ b/js/client.js @@ -229,6 +229,8 @@ } if (assertion === ';') { this.trigger('login:authrequired', name); + } else if (assertion === ';;@gmail') { + this.trigger('login:authrequired', name, '@gmail'); } else if (assertion.substr(0, 2) === ';;') { this.trigger('login:invalidname', name, assertion.substr(2)); } else if (assertion.indexOf('\n') >= 0 || !assertion) { @@ -273,7 +275,7 @@ app.send('/trn ' + name); } }, - passwordRename: function (name, password) { + passwordRename: function (name, password, special) { var self = this; $.post(this.getActionPHP(), { act: 'login', @@ -287,9 +289,15 @@ self.finishRename(name, data.assertion); } else { // wrong password + if (special === '@gmail') { + try { + gapi.auth2.getAuthInstance().signOut(); + } catch (e) {} + } app.addPopup(LoginPasswordPopup, { username: name, - error: 'Wrong password.' + error: 'Wrong password.', + special: special }); } }), 'text'); @@ -482,8 +490,8 @@ self.addPopup(LoginPopup, {name: name, reason: reason}); }); - this.user.on('login:authrequired', function (name) { - self.addPopup(LoginPasswordPopup, {username: name}); + this.user.on('login:authrequired', function (name, special) { + self.addPopup(LoginPasswordPopup, {username: name, special: special}); }); this.on('response:savereplay', this.uploadReplay, this); diff --git a/lib/ntbb-session.lib.php b/lib/ntbb-session.lib.php index e3a8748cfb..94aa450375 100644 --- a/lib/ntbb-session.lib.php +++ b/lib/ntbb-session.lib.php @@ -179,7 +179,7 @@ public function passwordVerify($name, $pass) { } private function passwordVerifyInner($userid, $pass, $user) { - global $psdb; + global $psdb, $psconfig; // throttle $ip = $this->getIp(); @@ -202,6 +202,18 @@ private function passwordVerifyInner($userid, $pass, $user) { } } + if (substr(@$user['email'], -1) === '@') { + require_once dirname(__FILE__).'/../vendor/autoload.php'; + $client = new Google_Client(['client_id' => $psconfig['gapi_clientid']]); + $payload = $client->verifyIdToken($pass); + if (!$payload) return false; + if (strpos($payload['aud'], $psconfig['gapi_clientid']) === false) return false; + if ($payload['email'] === substr($user['email'], 0, -1)) { + return true; + } + return false; + } + $rehash = false; if ($user['passwordhash']) { // new password hashes @@ -489,6 +501,7 @@ function getAssertion($userid, $serverhostname, $user = null, $challengekeyid = if ($row['password'] && $row['nonce']) { return ';;Your username is no longer available.'; } + if (substr($row['email'], -1) === '@') return ';;@gmail'; return ';'; } else { // Unregistered username.