diff --git a/README.md b/README.md
index 80de688..fc20d48 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,8 @@
-# Generic Google API Client for Node-RED
+# Generic Google API Client for Node-RED using OAuth2
-Node-RED node for Google APIs.
+Node-RED node for Google APIs.
-## Work in Progress
-
-Changes are coming.
-
-Configuration node name was changed at v.0.1.0: _google conn_ -> _google-conn_
+This Node is based on the implementation by [74Labs](https://github.com/74Labs/node-red-contrib-google). It has been updated to use the latest version of the __googleapis__. Further the authorization workflows has been changed to __OAuth2__.
## Features
@@ -14,25 +10,27 @@ This node is a wrapper for official Google APIs Node.js Client: [google-api-node
List of available APIs are delivered online via [Google API Discovery Service](https://developers.google.com/discovery/).
-Package contains two nodes. There is configuration node made for maintaining connection to Google API Services (_google-conn_) and regular node providing posibility to call any method of any API exposed via official Google's Node.js Client.
+Package contains two nodes. There is configuration node made for maintaining connection to Google API Services (_google-credentials_) and regular node providing posibility to call any method of any API exposed via official Google's Node.js Client.
## How to Install
Run the following command in the root directory of your Node-RED install
```
-npm install node-red-contrib-google
+npm install node-red-contrib-google-oauth2
```
or for a global installation
```
-npm install -g node-red-contrib-google
+npm install -g node-red-contrib-google-oauth2
```
## Configuration
-1. Generate service account key at [Google API Console](https://console.developers.google.com/apis/credentials/serviceaccountkey).
+1. Generate OAuth credentials at [Google API Console](https://console.developers.google.com/apis/credentials/oauthclient).
+
+ * Choose Web Application.
+ * As `Authorized JavaScript origins` enter your Node-RED IP (_e.g. `http://localhost:1880`_)
+ * As `Authorized redirect URIs` enter your Node-RED IP plus `/google-credentials/auth/callback` (_e.g. `http://localhost:1880/google-credentials/auth/callback`_)
- * Choose JSON type and save service key file.
- * Paste content of that file into JSON Key field of your _google-conn_ node.
-
+2. Copy the `Client ID` and `Client secret` and paste them into the Config Node
diff --git a/google-auth.html b/google-auth.html
new file mode 100644
index 0000000..43d99b5
--- /dev/null
+++ b/google-auth.html
@@ -0,0 +1,137 @@
+
+
+
diff --git a/google-auth.js b/google-auth.js
new file mode 100644
index 0000000..09457a6
--- /dev/null
+++ b/google-auth.js
@@ -0,0 +1,98 @@
+module.exports = function(RED) {
+ "use strict";
+ const crypto = require("crypto");
+ const url = require('url');
+ const { google } = require('googleapis');
+
+ function GoogleNode(n) {
+ RED.nodes.createNode(this,n);
+ this.displayName = n.displayName;
+ this.scopes = n.scopes;
+ }
+ RED.nodes.registerType("google-credentials",GoogleNode,{
+ credentials: {
+ displayName: {type:"text"},
+ clientId: {type:"text"},
+ clientSecret: {type:"password"},
+ accessToken: {type:"password"},
+ refreshToken: {type:"password"},
+ expireTime: {type:"password"}
+ }
+ });
+
+ RED.httpAdmin.get('/google-credentials/auth', function(req, res){
+ console.log('google-credentials/auth');
+ if (!req.query.clientId || !req.query.clientSecret ||
+ !req.query.id || !req.query.callback) {
+ res.send(400);
+ return;
+ }
+ const node_id = req.query.id;
+ const callback = req.query.callback;
+ const credentials = {
+ clientId: req.query.clientId,
+ clientSecret: req.query.clientSecret
+ };
+ const scopes = req.query.scopes;
+
+ const csrfToken = crypto.randomBytes(18).toString('base64').replace(/\//g, '-').replace(/\+/g, '_');
+ credentials.csrfToken = csrfToken;
+ credentials.callback = callback;
+ res.cookie('csrf', csrfToken);
+ res.redirect(url.format({
+ protocol: 'https',
+ hostname: 'accounts.google.com',
+ pathname: '/o/oauth2/auth',
+ query: {
+ access_type: 'offline',
+ approval_prompt: 'force',
+ scope: scopes,
+ response_type: 'code',
+ client_id: credentials.clientId,
+ redirect_uri: callback,
+ state: node_id + ":" + csrfToken,
+ }
+ }));
+ RED.nodes.addCredentials(node_id, credentials);
+ });
+
+ RED.httpAdmin.get('/google-credentials/auth/callback', function(req, res) {
+ console.log('google-credentials/auth/callback');
+ if (req.query.error) {
+ return res.send("google.error.error", {error: req.query.error, description: req.query.error_description});
+ }
+ var state = req.query.state.split(':');
+ var node_id = state[0];
+ var credentials = RED.nodes.getCredentials(node_id);
+ if (!credentials || !credentials.clientId || !credentials.clientSecret) {
+ console.log("credentials not present?");
+ return res.send("google.error.no-credentials");
+ }
+ if (state[1] !== credentials.csrfToken) {
+ return res.status(401).send("google.error.token-mismatch");
+ }
+
+ const oauth2Client = new google.auth.OAuth2(
+ credentials.clientId,
+ credentials.clientSecret,
+ credentials.callback
+ );
+
+ oauth2Client.getToken(req.query.code)
+ .then((value) => {
+ credentials.accessToken = value.tokens.access_token;
+ credentials.refreshToken = value.tokens.refresh_token;
+ credentials.expireTime = value.tokens.expiry_date;
+ credentials.tokenType = value.tokens.token_type;
+ credentials.displayName = value.tokens.scope.substr(0, 40);
+
+ delete credentials.csrfToken;
+ delete credentials.callback;
+ RED.nodes.addCredentials(node_id, credentials);
+ res.send('Authorized');
+ })
+ .catch((error) => {
+ return res.send('Could not receive tokens');
+ });
+ });
+};
\ No newline at end of file
diff --git a/google.html b/google.html
index da484d7..994033b 100644
--- a/google.html
+++ b/google.html
@@ -1,49 +1,3 @@
-
-
-
-