Merge pull request #5561 from Budibase/gsheets-updates

Gsheets updates
This commit is contained in:
Martin McKeaveney 2022-04-25 11:43:56 +01:00 committed by GitHub
commit 73abd8aa9d
4 changed files with 63 additions and 17 deletions

View File

@ -445,3 +445,4 @@ exports.getConfigParams = getConfigParams
exports.getScopedFullConfig = getScopedFullConfig exports.getScopedFullConfig = getScopedFullConfig
exports.generateNewUsageQuotaDoc = generateNewUsageQuotaDoc exports.generateNewUsageQuotaDoc = generateNewUsageQuotaDoc
exports.generateDevInfoID = generateDevInfoID exports.generateDevInfoID = generateDevInfoID
exports.getPlatformUrl = getPlatformUrl

View File

@ -1,8 +1,8 @@
const google = require("../google") const google = require("../google")
const { Cookies, Configs } = require("../../../constants") const { Cookies, Configs } = require("../../../constants")
const { clearCookie, getCookie } = require("../../../utils") const { clearCookie, getCookie } = require("../../../utils")
const { getScopedConfig, getPlatformUrl } = require("../../../db/utils")
const { doWithDB } = require("../../../db") const { doWithDB } = require("../../../db")
const { getScopedConfig } = require("../../../db/utils")
const environment = require("../../../environment") const environment = require("../../../environment")
const { getGlobalDB } = require("../../../tenancy") const { getGlobalDB } = require("../../../tenancy")
@ -21,10 +21,20 @@ async function fetchGoogleCreds() {
) )
} }
async function platformUrl() {
const db = getGlobalDB()
const publicConfig = await getScopedConfig(db, {
type: Configs.SETTINGS,
})
return getPlatformUrl(publicConfig)
}
async function preAuth(passport, ctx, next) { async function preAuth(passport, ctx, next) {
// get the relevant config // get the relevant config
const googleConfig = await fetchGoogleCreds() const googleConfig = await fetchGoogleCreds()
let callbackUrl = `${environment.PLATFORM_URL}/api/global/auth/datasource/google/callback` const platUrl = await platformUrl()
let callbackUrl = `${platUrl}/api/global/auth/datasource/google/callback`
const strategy = await google.strategyFactory(googleConfig, callbackUrl) const strategy = await google.strategyFactory(googleConfig, callbackUrl)
if (!ctx.query.appId || !ctx.query.datasourceId) { if (!ctx.query.appId || !ctx.query.datasourceId) {
@ -41,14 +51,15 @@ async function preAuth(passport, ctx, next) {
async function postAuth(passport, ctx, next) { async function postAuth(passport, ctx, next) {
// get the relevant config // get the relevant config
const config = await fetchGoogleCreds() const config = await fetchGoogleCreds()
const platUrl = await platformUrl()
let callbackUrl = `${environment.PLATFORM_URL}/api/global/auth/datasource/google/callback` let callbackUrl = `${platUrl}/api/global/auth/datasource/google/callback`
const strategy = await google.strategyFactory( const strategy = await google.strategyFactory(
config, config,
callbackUrl, callbackUrl,
(accessToken, refreshToken, profile, done) => { (accessToken, refreshToken, profile, done) => {
clearCookie(ctx, Cookies.DatasourceAuth) clearCookie(ctx, Cookies.DatasourceAuth)
done(null, { accessToken, refreshToken }) done(null, { refreshToken })
} }
) )

View File

@ -15,7 +15,6 @@
import ArrayRenderer from "components/common/renderers/ArrayRenderer.svelte" import ArrayRenderer from "components/common/renderers/ArrayRenderer.svelte"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import GoogleButton from "../_components/GoogleButton.svelte"
export let datasource export let datasource
export let save export let save
@ -161,11 +160,6 @@
Fetch tables Fetch tables
</Button> </Button>
<Button cta icon="Add" on:click={createNewTable}>New table</Button> <Button cta icon="Add" on:click={createNewTable}>New table</Button>
{#if integration.auth}
{#if integration.auth.type === "google"}
<GoogleButton {datasource} />
{/if}
{/if}
</div> </div>
</div> </div>
<Body> <Body>

View File

@ -16,6 +16,7 @@ module GoogleSheetsModule {
const { getGlobalDB } = require("@budibase/backend-core/tenancy") const { getGlobalDB } = require("@budibase/backend-core/tenancy")
const { getScopedConfig } = require("@budibase/backend-core/db") const { getScopedConfig } = require("@budibase/backend-core/db")
const { Configs } = require("@budibase/backend-core/constants") const { Configs } = require("@budibase/backend-core/constants")
const fetch = require("node-fetch")
interface GoogleSheetsConfig { interface GoogleSheetsConfig {
spreadsheetId: string spreadsheetId: string
@ -28,6 +29,16 @@ module GoogleSheetsModule {
refreshToken: string refreshToken: string
} }
interface AuthTokenRequest {
client_id: string
client_secret: string
refresh_token: string
}
interface AuthTokenResponse {
access_token: string
}
const SCHEMA: Integration = { const SCHEMA: Integration = {
plus: true, plus: true,
auth: { auth: {
@ -40,6 +51,7 @@ module GoogleSheetsModule {
friendlyName: "Google Sheets", friendlyName: "Google Sheets",
datasource: { datasource: {
spreadsheetId: { spreadsheetId: {
display: "Google Sheet URL",
type: DatasourceFieldTypes.STRING, type: DatasourceFieldTypes.STRING,
required: true, required: true,
}, },
@ -135,6 +147,30 @@ module GoogleSheetsModule {
return parts.length > 5 ? parts[5] : spreadsheetId return parts.length > 5 ? parts[5] : spreadsheetId
} }
async fetchAccessToken(
payload: AuthTokenRequest
): Promise<AuthTokenResponse> {
const response = await fetch(
"https://www.googleapis.com/oauth2/v4/token",
{
method: "POST",
body: JSON.stringify({
...payload,
grant_type: "refresh_token",
}),
headers: {
"Content-Type": "application/json",
},
}
)
if (response.status !== 200) {
throw new Error("Error authenticating with google sheets.")
}
return response.json()
}
async connect() { async connect() {
try { try {
// Initialise oAuth client // Initialise oAuth client
@ -154,14 +190,18 @@ module GoogleSheetsModule {
clientId: googleConfig.clientID, clientId: googleConfig.clientID,
clientSecret: googleConfig.clientSecret, clientSecret: googleConfig.clientSecret,
}) })
oauthClient.on("tokens", tokens => {
const tokenResponse = await this.fetchAccessToken({
client_id: googleConfig.clientID,
client_secret: googleConfig.clientSecret,
refresh_token: this.config.auth.refreshToken,
})
oauthClient.setCredentials({ oauthClient.setCredentials({
refresh_token: googleConfig.refreshToken, refresh_token: this.config.auth.refreshToken,
access_token: tokens.access_token, access_token: tokenResponse.access_token,
}) })
})
oauthClient.credentials.access_token = this.config.auth.accessToken
oauthClient.credentials.refresh_token = this.config.auth.refreshToken
this.client.useOAuth2Client(oauthClient) this.client.useOAuth2Client(oauthClient)
await this.client.loadInfo() await this.client.loadInfo()
} catch (err) { } catch (err) {