google auth working
This commit is contained in:
parent
a09fabc54b
commit
c2d97b9449
|
@ -46,6 +46,7 @@ exports.strategyFactory = async function (
|
|||
clientID: config.clientID,
|
||||
clientSecret: config.clientSecret,
|
||||
callbackURL: callbackUrl,
|
||||
store: true,
|
||||
},
|
||||
verify
|
||||
)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<script>
|
||||
import { ActionButton } from "@budibase/bbui"
|
||||
import GoogleLogo from "assets/google-logo.png"
|
||||
import { store } from "builderStore"
|
||||
import { auth } from "stores/portal"
|
||||
|
||||
export let preAuthStep
|
||||
|
||||
$: tenantId = $auth.tenantId
|
||||
</script>
|
||||
|
||||
<ActionButton
|
||||
on:click={async () => {
|
||||
// TODO: can probably remove
|
||||
const datasourceId = await preAuthStep()
|
||||
window.open(
|
||||
`/api/global/auth/${tenantId}/google2?datasourceId=${datasourceId}&appId=${$store.appId}`,
|
||||
"_blank"
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div class="inner">
|
||||
<img src={GoogleLogo} alt="google icon" />
|
||||
<p>Sign in with Google</p>
|
||||
</div>
|
||||
</ActionButton>
|
||||
|
||||
<style>
|
||||
.inner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: var(--spacing-xs);
|
||||
padding-bottom: var(--spacing-xs);
|
||||
}
|
||||
.inner img {
|
||||
width: 18px;
|
||||
margin: 3px 10px 3px 3px;
|
||||
}
|
||||
.inner p {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
|
@ -32,6 +32,7 @@
|
|||
plus: selected.plus,
|
||||
config,
|
||||
schema: selected.datasource,
|
||||
auth: selected.auth,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import { datasources, tables } from "stores/backend"
|
||||
import { IntegrationNames } from "constants"
|
||||
import cloneDeep from "lodash/cloneDeepWith"
|
||||
import GoogleButton from "../_components/GoogleButton.svelte"
|
||||
|
||||
export let integration
|
||||
export let modal
|
||||
|
@ -33,11 +34,14 @@
|
|||
|
||||
return datasource
|
||||
}
|
||||
async function saveDatasource() {
|
||||
async function saveDatasource(fetchSchema) {
|
||||
const datasource = prepareData()
|
||||
try {
|
||||
// Create datasource
|
||||
const resp = await datasources.save(datasource, datasource.plus)
|
||||
const resp = await datasources.save(
|
||||
datasource,
|
||||
fetchSchema ?? datasource.plus
|
||||
)
|
||||
|
||||
// update the tables incase data source plus
|
||||
await tables.fetch()
|
||||
|
@ -48,7 +52,7 @@
|
|||
name: resp.name,
|
||||
source: resp.source,
|
||||
})
|
||||
return true
|
||||
return resp._id
|
||||
} catch (err) {
|
||||
notifications.error(`Error saving datasource: ${err}`)
|
||||
return false
|
||||
|
@ -71,8 +75,11 @@
|
|||
>Connect your database to Budibase using the config below.
|
||||
</Body>
|
||||
</Layout>
|
||||
|
||||
{#if config.auth?.type === "google"}
|
||||
<GoogleButton preAuthStep={() => saveDatasource(false)} />
|
||||
{:else}
|
||||
<IntegrationConfigForm schema={config.schema} integration={config.config} />
|
||||
{/if}
|
||||
</ModalContent>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
"download": "8.0.0",
|
||||
"fix-path": "3.0.0",
|
||||
"fs-extra": "8.1.0",
|
||||
"google-auth-library": "^7.11.0",
|
||||
"google-spreadsheet": "^3.2.0",
|
||||
"jimp": "0.16.1",
|
||||
"joi": "17.2.1",
|
||||
|
|
|
@ -75,6 +75,10 @@ exports.DataSourceOperation = {
|
|||
DELETE_TABLE: "DELETE_TABLE",
|
||||
}
|
||||
|
||||
exports.DatasourceAuthTypes = {
|
||||
GOOGLE: "google",
|
||||
}
|
||||
|
||||
exports.SortDirection = {
|
||||
ASCENDING: "ASCENDING",
|
||||
DESCENDING: "DESCENDING",
|
||||
|
|
|
@ -87,6 +87,8 @@ export interface ExtraQueryConfig {
|
|||
export interface Integration {
|
||||
docs: string
|
||||
plus?: boolean
|
||||
// TODO: use a proper type here
|
||||
auth: { type: "google" }
|
||||
description: string
|
||||
friendlyName: string
|
||||
datasource: {}
|
||||
|
|
|
@ -42,6 +42,8 @@ module.exports = {
|
|||
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
||||
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
|
||||
MULTI_TENANCY: process.env.MULTI_TENANCY,
|
||||
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
|
||||
GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
|
||||
// environment
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
JEST_WORKER_ID: process.env.JEST_WORKER_ID,
|
||||
|
|
|
@ -5,21 +5,37 @@ import {
|
|||
QueryTypes,
|
||||
} from "../definitions/datasource"
|
||||
import { IntegrationBase } from "./base/IntegrationBase"
|
||||
import { OAuth2Client } from "google-auth-library"
|
||||
import { GoogleSpreadsheet } from "google-spreadsheet"
|
||||
import { DatasourcePlus } from "./base/datasourcePlus"
|
||||
import { Table } from "../definitions/common"
|
||||
import { buildExternalTableId } from "./utils"
|
||||
import { DataSourceOperation, FieldTypes } from "../constants"
|
||||
import {
|
||||
DataSourceOperation,
|
||||
FieldTypes,
|
||||
DatasourceAuthTypes,
|
||||
} from "../constants"
|
||||
import env from "../environment"
|
||||
import CouchDB from "../db"
|
||||
import { timeStamp } from "console"
|
||||
|
||||
module GoogleSheetsModule {
|
||||
interface GoogleSheetsConfig {
|
||||
spreadsheetId: string
|
||||
clientEmail: string
|
||||
privateKey: string
|
||||
auth: OAuthClientConfig
|
||||
}
|
||||
|
||||
interface OAuthClientConfig {
|
||||
appId: string
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
}
|
||||
|
||||
const SCHEMA: Integration = {
|
||||
plus: true,
|
||||
auth: {
|
||||
type: "google",
|
||||
},
|
||||
docs: "https://developers.google.com/sheets/api/quickstart/nodejs",
|
||||
description:
|
||||
"Create and collaborate on online spreadsheets in real-time and from any device. ",
|
||||
|
@ -29,21 +45,13 @@ module GoogleSheetsModule {
|
|||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
clientEmail: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
privateKey: {
|
||||
type: DatasourceFieldTypes.LONGFORM,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
query: {
|
||||
create: {
|
||||
type: QueryTypes.FIELDS,
|
||||
fields: {
|
||||
sheet: {
|
||||
type: "string",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
row: {
|
||||
|
@ -56,7 +64,7 @@ module GoogleSheetsModule {
|
|||
type: QueryTypes.FIELDS,
|
||||
fields: {
|
||||
sheet: {
|
||||
type: "string",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
@ -65,11 +73,11 @@ module GoogleSheetsModule {
|
|||
type: QueryTypes.FIELDS,
|
||||
fields: {
|
||||
sheet: {
|
||||
type: "string",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
rowIndex: {
|
||||
type: "number",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
row: {
|
||||
|
@ -82,11 +90,11 @@ module GoogleSheetsModule {
|
|||
type: QueryTypes.FIELDS,
|
||||
fields: {
|
||||
sheet: {
|
||||
type: "string",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
rowIndex: {
|
||||
type: "number",
|
||||
type: DatasourceFieldTypes.NUMBER,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
@ -107,12 +115,15 @@ module GoogleSheetsModule {
|
|||
|
||||
async connect() {
|
||||
try {
|
||||
await this.client.useServiceAccountAuth({
|
||||
// env var values are copied from service account credentials generated by google
|
||||
// see "Authentication" section in docs for more info
|
||||
client_email: this.config.clientEmail,
|
||||
private_key: this.config.privateKey,
|
||||
// Initialise oAuth client
|
||||
// TODO: Move this to auth lib
|
||||
const oauthClient = new OAuth2Client({
|
||||
clientId: env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: env.GOOGLE_CLIENT_SECRET,
|
||||
})
|
||||
oauthClient.credentials.access_token = this.config.auth.accessToken
|
||||
oauthClient.credentials.refresh_token = this.config.auth.refreshToken
|
||||
this.client.useOAuth2Client(oauthClient)
|
||||
await this.client.loadInfo()
|
||||
} catch (err) {
|
||||
console.error("Error connecting to google sheets", err)
|
||||
|
@ -178,7 +189,9 @@ module GoogleSheetsModule {
|
|||
}
|
||||
|
||||
if (json.endpoint.operation === DataSourceOperation.DELETE) {
|
||||
return await this.delete({})
|
||||
return await this.delete({
|
||||
// TODO: complete
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -450,7 +450,7 @@ module OracleModule {
|
|||
})
|
||||
return lastRow.rows
|
||||
} else {
|
||||
return [{ [ operation.toLowerCase() ]: true }]
|
||||
return [{ [operation.toLowerCase()]: true }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -952,9 +952,9 @@
|
|||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/auth@^1.0.30":
|
||||
version "1.0.30"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/auth/-/auth-1.0.30.tgz#4ddc72518fc2d2a8e72a84acfd7d141d3b5e21b9"
|
||||
integrity sha512-GbYH/SEqzOZPhxOa8gjy42Pl6b+aDZ/xHkcS4oBTzh1n+T45G53LF7WkQyVhxRZXrzh960VSI4QAWnA+ZeK9Sw==
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/auth/-/auth-1.0.34.tgz#f1daad174d494c5baae29ebfb2d0cf7a26d487bb"
|
||||
integrity sha512-RN5xZVqk4D4GIFoTrm6kv6vxIcAyDgoopsGMYj8dQRCYWb6pvWzCKyDw4o1THXiK8BBD8ctFUE/FhtLXRj8F4w==
|
||||
dependencies:
|
||||
"@techpass/passport-openidconnect" "^0.3.0"
|
||||
aws-sdk "^2.901.0"
|
||||
|
@ -1024,10 +1024,10 @@
|
|||
svelte-flatpickr "^3.2.3"
|
||||
svelte-portal "^1.0.0"
|
||||
|
||||
"@budibase/bbui@^1.0.30":
|
||||
version "1.0.30"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.30.tgz#16b0a66055539709c71564a01253835e874b6ea3"
|
||||
integrity sha512-eYMXuzwZTMJMybbXLVoBz5rQIfVV86hLugog8TaZbkqFeMgPUgyuM8uHfw6wTQBdPazfgVbTeQK0UzkWMnwGOg==
|
||||
"@budibase/bbui@^1.0.34":
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.34.tgz#3eba93984cd0075aecbf4ca8451b301e623c7afa"
|
||||
integrity sha512-9mVzIWx4dQ8LIy4ncJaJBVwuTx2LEMqZl1XRr/NAI3rsTv+HIULe+zCUJSCYM2MGoR3qKSU7geIzIuwnRa8k4Q==
|
||||
dependencies:
|
||||
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
|
||||
"@spectrum-css/actionbutton" "^1.0.1"
|
||||
|
@ -1075,13 +1075,13 @@
|
|||
svelte-portal "^1.0.0"
|
||||
|
||||
"@budibase/client@^1.0.30":
|
||||
version "1.0.30"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.30.tgz#a80e87d15722333a5bcfa96b6a14b024fe8574ee"
|
||||
integrity sha512-Ac63c+uTj7tMbVU4J8T6oFFGiONd6JABaGG/k+W5XKidvytyMxYSeu/Z5xl6jP/sYb2e+Oevt1vv9xB0tlkARw==
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.34.tgz#2bdac2030eabf780659481fa751cd7fecf1b609f"
|
||||
integrity sha512-WGEVjwmKYv+B+J6crbia62BNFCzgKHEggsNAlCN3+IB+w9jxS2oiOJYPpYQnsSM2l4j4/Zbu9W30OhenSiB8kQ==
|
||||
dependencies:
|
||||
"@budibase/bbui" "^1.0.30"
|
||||
"@budibase/bbui" "^1.0.34"
|
||||
"@budibase/standard-components" "^0.9.139"
|
||||
"@budibase/string-templates" "^1.0.30"
|
||||
"@budibase/string-templates" "^1.0.34"
|
||||
regexparam "^1.3.0"
|
||||
shortid "^2.2.15"
|
||||
svelte-spa-router "^3.0.5"
|
||||
|
@ -1131,10 +1131,10 @@
|
|||
svelte-apexcharts "^1.0.2"
|
||||
svelte-flatpickr "^3.1.0"
|
||||
|
||||
"@budibase/string-templates@^1.0.30":
|
||||
version "1.0.30"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.30.tgz#c7206687f4f3c1cecfd3334b89a36920edc2d86f"
|
||||
integrity sha512-C5SyLNSsvfQLxAjoM77Pd03R8R9LFaoAu6CqgyJuO6JmUpAbP5JNBqi+PLmrxZEPJK0tykCHxdSLtaOfIaV+lQ==
|
||||
"@budibase/string-templates@^1.0.30", "@budibase/string-templates@^1.0.34":
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.34.tgz#7e5f80a26db5d04063c0e78cdf37af88cff772c6"
|
||||
integrity sha512-HWqXxQBXqVwBgCh3ptczVFxWOLHVUhuTShXCafRDgKAVY3d+LJzKGwiD40/oR/nUqeNtBbHgYWu8Z4gMQQYZhA==
|
||||
dependencies:
|
||||
"@budibase/handlebars-helpers" "^0.11.7"
|
||||
dayjs "^1.10.4"
|
||||
|
@ -3244,9 +3244,9 @@ aws-sdk@^2.767.0:
|
|||
xml2js "0.4.19"
|
||||
|
||||
aws-sdk@^2.901.0:
|
||||
version "2.1036.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1036.0.tgz#47f0d0a38b5bfbd4a7a382a6756a6aa7af627aad"
|
||||
integrity sha512-K0f4uXL32ZdoPmWiuSQEAC5ae5v7gNmhjzoEB7VonE5E8l2umWsoU0Ahm8WPr14LgsvtkeyBuqBjphbxLz6hIw==
|
||||
version "2.1050.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1050.0.tgz#172e80839a3c1bed82e7c42db2fbe7d46fbb90ca"
|
||||
integrity sha512-xXY3wAZQyh/d6vk5oClyB3ViFENc1OOrsB/HUu/g+wnMzMLp+ea+OpZwRM5+g90mAiJ1eLOxje0Sgnbe7fP2oA==
|
||||
dependencies:
|
||||
buffer "4.9.2"
|
||||
events "1.1.1"
|
||||
|
@ -6063,6 +6063,21 @@ google-auth-library@^6.1.3:
|
|||
jws "^4.0.0"
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
google-auth-library@^7.11.0:
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-7.11.0.tgz#b63699c65037310a424128a854ba7e736704cbdb"
|
||||
integrity sha512-3S5jn2quRumvh9F/Ubf7GFrIq71HZ5a6vqosgdIu105kkk0WtSqc2jGCRqtWWOLRS8SX3AHACMOEDxhyWAQIcg==
|
||||
dependencies:
|
||||
arrify "^2.0.0"
|
||||
base64-js "^1.3.0"
|
||||
ecdsa-sig-formatter "^1.0.11"
|
||||
fast-text-encoding "^1.0.0"
|
||||
gaxios "^4.0.0"
|
||||
gcp-metadata "^4.2.0"
|
||||
gtoken "^5.0.4"
|
||||
jws "^4.0.0"
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
google-auth-library@~0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e"
|
||||
|
@ -6642,9 +6657,9 @@ ioredis@^4.27.0:
|
|||
standard-as-callback "^2.1.0"
|
||||
|
||||
ioredis@^4.27.1:
|
||||
version "4.28.1"
|
||||
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.1.tgz#c2a7038d6a187e020d7045e11d6a677e8b51f785"
|
||||
integrity sha512-7gcrUJEcPHWy+eEyq6wIZpXtfHt8crhbc5+z0sqrnHUkwBblXinygfamj+/jx83Qo+2LW3q87Nj2VsuH6BF2BA==
|
||||
version "4.28.2"
|
||||
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.2.tgz#493ccd5d869fd0ec86c96498192718171f6c9203"
|
||||
integrity sha512-kQ+Iv7+c6HsDdPP2XUHaMv8DhnSeAeKEwMbaoqsXYbO+03dItXt7+5jGQDRyjdRUV2rFJbzg7P4Qt1iX2tqkOg==
|
||||
dependencies:
|
||||
cluster-key-slot "^1.1.0"
|
||||
debug "^4.3.1"
|
||||
|
|
|
@ -21,6 +21,7 @@ const {
|
|||
isMultiTenant,
|
||||
} = require("@budibase/auth/tenancy")
|
||||
const env = require("../../../environment")
|
||||
const CouchDB = require("../../../db")
|
||||
|
||||
const ssoCallbackUrl = async (config, type) => {
|
||||
// incase there is a callback URL from before
|
||||
|
@ -142,6 +143,80 @@ exports.logout = async ctx => {
|
|||
ctx.body = { message: "User logged out." }
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial call that google authentication makes to take you to the google login screen.
|
||||
* On a successful login, you will be redirected to the googleAuth callback route.
|
||||
*/
|
||||
exports.googlePreAuth2 = async (ctx, next) => {
|
||||
const db = getGlobalDB()
|
||||
|
||||
const config = await authPkg.db.getScopedConfig(db, {
|
||||
type: Configs.GOOGLE,
|
||||
workspace: ctx.query.workspace,
|
||||
})
|
||||
// let callbackUrl = await exports.googleCallbackUrl(config)
|
||||
// TODO: Hardcoded - fix
|
||||
let callbackUrl = "http://localhost:10000/api/global/auth/google2/callback"
|
||||
const strategy = await google.strategyFactory(config, callbackUrl)
|
||||
|
||||
// TODO: fix
|
||||
setCookie(
|
||||
ctx,
|
||||
{
|
||||
appId: ctx.query.appId,
|
||||
datasourceId: ctx.query.datasourceId,
|
||||
},
|
||||
"AuthCallback"
|
||||
)
|
||||
|
||||
// TODO: prob update - shouldn't include the google sheets scopes here
|
||||
return passport.authenticate(strategy, {
|
||||
scope: ["profile", "email", "https://www.googleapis.com/auth/spreadsheets"],
|
||||
})(ctx, next)
|
||||
}
|
||||
|
||||
exports.googleAuth2 = async (ctx, next) => {
|
||||
const db = getGlobalDB()
|
||||
|
||||
const config = await authPkg.db.getScopedConfig(db, {
|
||||
type: Configs.GOOGLE,
|
||||
workspace: ctx.query.workspace,
|
||||
})
|
||||
// const callbackUrl = await exports.googleCallbackUrl(config)
|
||||
const authStateCookie = getCookie(ctx, "AuthCallback")
|
||||
|
||||
// TODO: correct callback URL
|
||||
let callbackUrl = "http://localhost:10000/api/global/auth/google2/callback"
|
||||
const strategy = await google.strategyFactory(
|
||||
config,
|
||||
callbackUrl,
|
||||
(accessToken, refreshToken, profile, done) => {
|
||||
clearCookie(ctx, "AuthCallback")
|
||||
done(null, { accessToken, refreshToken })
|
||||
}
|
||||
)
|
||||
|
||||
return passport.authenticate(
|
||||
strategy,
|
||||
{ successRedirect: "/", failureRedirect: "/error" },
|
||||
async (err, tokens) => {
|
||||
// update the DB for the datasource with all the user info
|
||||
const db = new CouchDB(authStateCookie.appId)
|
||||
const datasource = await db.get(authStateCookie.datasourceId)
|
||||
datasource.config = {
|
||||
auth: {
|
||||
type: "google",
|
||||
...tokens,
|
||||
},
|
||||
}
|
||||
await db.put(datasource)
|
||||
ctx.redirect(
|
||||
`/builder/app/${authStateCookie.appId}/data/datasource/${authStateCookie.datasourceId}`
|
||||
)
|
||||
}
|
||||
)(ctx, next)
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial call that google authentication makes to take you to the google login screen.
|
||||
* On a successful login, you will be redirected to the googleAuth callback route.
|
||||
|
|
|
@ -63,8 +63,15 @@ router
|
|||
updateTenant,
|
||||
authController.googlePreAuth
|
||||
)
|
||||
.get(
|
||||
"/api/global/auth/:tenantId/google2",
|
||||
updateTenant,
|
||||
authController.googlePreAuth2
|
||||
)
|
||||
// single tenancy endpoint
|
||||
.get("/api/global/auth/google/callback", authController.googleAuth)
|
||||
// TODO: Remove
|
||||
.get("/api/global/auth/google2/callback", authController.googleAuth2)
|
||||
// multi-tenancy endpoint
|
||||
.get(
|
||||
"/api/global/auth/:tenantId/google/callback",
|
||||
|
|
Loading…
Reference in New Issue