From a360037bb01308154fb6d98cbe8f032684cae04d Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 11 Mar 2021 17:56:23 +0100 Subject: [PATCH 1/4] Save youtube refresh token in config for re-use --- nodecg-io-youtube/extension/index.ts | 41 ++++++++++++++++++++++----- nodecg-io-youtube/youtube-schema.json | 4 +++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/nodecg-io-youtube/extension/index.ts b/nodecg-io-youtube/extension/index.ts index ec64cc495..9dfc89a97 100644 --- a/nodecg-io-youtube/extension/index.ts +++ b/nodecg-io-youtube/extension/index.ts @@ -1,12 +1,15 @@ import { NodeCG } from "nodecg/types/server"; import { Result, emptySuccess, success, error, ServiceBundle } from "nodecg-io-core"; import { google, youtube_v3 } from "googleapis"; +import type { Credentials } from "google-auth-library/build/src/auth/credentials"; +import type { OAuth2Client } from "google-auth-library/build/src/auth/oauth2client"; import * as express from "express"; import opn = require("open"); interface YoutubeServiceConfig { clientID: string; clientSecret: string; + refreshToken?: string; } export type YoutubeServiceClient = youtube_v3.Youtube; @@ -26,6 +29,36 @@ class YoutubeService extends ServiceBundle { + if (tokens.refresh_token) { + config.refreshToken = tokens.refresh_token; + } + }); + + const client = new youtube_v3.Youtube({ auth }); + return success(client); + } + + stopClient(_client: YoutubeServiceClient): void { + // Cannot stop client + } + + private initialAuth(auth: OAuth2Client): Promise { const authUrl = auth.generateAuthUrl({ access_type: "offline", scope: "https://www.googleapis.com/auth/youtube", @@ -41,9 +74,7 @@ class YoutubeService extends ServiceBundlewindow.close()"); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const { tokens } = await auth.getToken(params.code!.toString()); - auth.credentials = tokens; - const client = new youtube_v3.Youtube({ auth }); - resolve(success(client)); + resolve(tokens); } catch (e) { reject(error(e)); } @@ -53,8 +84,4 @@ class YoutubeService extends ServiceBundle cp.unref()); }); } - - stopClient(_client: YoutubeServiceClient): void { - // Cannot stop client - } } diff --git a/nodecg-io-youtube/youtube-schema.json b/nodecg-io-youtube/youtube-schema.json index 66cc8c516..3cc2be27a 100644 --- a/nodecg-io-youtube/youtube-schema.json +++ b/nodecg-io-youtube/youtube-schema.json @@ -10,6 +10,10 @@ "clientSecret": { "type": "string", "description": "The oauth client secret https://console.cloud.google.com/apis/credentials/oauthclient" + }, + "refreshToken": { + "type": "string", + "description": "Token that allows the client to refresh access tokens. This is set automatically after first login, you don't need to set it." } }, "required": ["clientID", "clientSecret"] From c329429ffff76e739b9ebd869e0c5810fcefbb33 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 11 Mar 2021 17:57:46 +0100 Subject: [PATCH 2/4] Additionally save config when shutting down --- nodecg-io-core/extension/index.ts | 10 ++++++++-- nodecg-io-core/extension/persistenceManager.ts | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/nodecg-io-core/extension/index.ts b/nodecg-io-core/extension/index.ts index 3ec9b6d5f..2bebe8fa1 100644 --- a/nodecg-io-core/extension/index.ts +++ b/nodecg-io-core/extension/index.ts @@ -32,7 +32,7 @@ module.exports = (nodecg: NodeCG): NodeCGIOCore => { persistenceManager, ).registerMessageHandlers(); - registerExitHandlers(nodecg, bundleManager, instanceManager, serviceManager); + registerExitHandlers(nodecg, bundleManager, instanceManager, serviceManager, persistenceManager); // We use a extra object instead of returning a object containing all the managers and so on, because // any loaded bundle would be able to call any (public or private) of the managers which is not intended. @@ -62,7 +62,12 @@ function onExit( bundleManager: BundleManager, instanceManager: InstanceManager, serviceManager: ServiceManager, + persistenceManager: PersistenceManager, ): void { + // Save everything + // This is especially important if some services update some configs (e.g. updated tokens) and they haven't been saved yet. + persistenceManager.save(); + // Unset all service instances in all bundles const bundles = bundleManager.getBundleDependencies(); for (const bundleName in bundles) { @@ -99,9 +104,10 @@ function registerExitHandlers( bundleManager: BundleManager, instanceManager: InstanceManager, serviceManager: ServiceManager, + persistenceManager: PersistenceManager, ): void { const handler = () => { - onExit(nodecg, bundleManager, instanceManager, serviceManager); + onExit(nodecg, bundleManager, instanceManager, serviceManager, persistenceManager); }; // Normal exit diff --git a/nodecg-io-core/extension/persistenceManager.ts b/nodecg-io-core/extension/persistenceManager.ts index 56543909a..283d4137e 100644 --- a/nodecg-io-core/extension/persistenceManager.ts +++ b/nodecg-io-core/extension/persistenceManager.ts @@ -208,7 +208,7 @@ export class PersistenceManager { /** * Encrypts and saves current state to the persistent replicant. */ - private save() { + save() { // Check if we have a password to encrypt the data with. if (this.password === undefined) { return; From 7d2e833cd05c3a34dc584fd2c9184726646c08f9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 11 Mar 2021 18:02:07 +0100 Subject: [PATCH 3/4] Add text after succesfully youtube authentication --- nodecg-io-spotify/extension/index.ts | 2 +- nodecg-io-youtube/extension/index.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nodecg-io-spotify/extension/index.ts b/nodecg-io-spotify/extension/index.ts index cb11562ef..11092a893 100644 --- a/nodecg-io-spotify/extension/index.ts +++ b/nodecg-io-spotify/extension/index.ts @@ -95,7 +95,7 @@ class SpotifyService extends ServiceBundleSpotify connection successful! You may close this window now."; + "Spotify connection successful! You may close this window now."; res.send(callbackWebsite); }); diff --git a/nodecg-io-youtube/extension/index.ts b/nodecg-io-youtube/extension/index.ts index 9dfc89a97..757e6c5fd 100644 --- a/nodecg-io-youtube/extension/index.ts +++ b/nodecg-io-youtube/extension/index.ts @@ -71,7 +71,11 @@ class YoutubeService extends ServiceBundle { try { const params = req.query; - res.end(""); + + const callbackWebsite = + "YouTube connection successful! You may close this window now."; + res.send(callbackWebsite); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const { tokens } = await auth.getToken(params.code!.toString()); resolve(tokens); From 56a8c6f297b724a1691b77655f4918c44c39953f Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 11 Mar 2021 18:06:30 +0100 Subject: [PATCH 4/4] Fix linter warning in persistance manager --- nodecg-io-core/extension/persistenceManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodecg-io-core/extension/persistenceManager.ts b/nodecg-io-core/extension/persistenceManager.ts index 283d4137e..c709baba4 100644 --- a/nodecg-io-core/extension/persistenceManager.ts +++ b/nodecg-io-core/extension/persistenceManager.ts @@ -208,7 +208,7 @@ export class PersistenceManager { /** * Encrypts and saves current state to the persistent replicant. */ - save() { + save(): void { // Check if we have a password to encrypt the data with. if (this.password === undefined) { return;