Refresh the OAuth tokens automatically when making rest calls. Fix to remove the password from the api token authentication.
This commit is contained in:
parent
9972ec403d
commit
1e6845d5cb
|
@ -37,53 +37,118 @@ passport.deserializeUser(async (user, done) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
//requestAccessStrategy
|
async function refreshOIDCAccessToken(db, chosenConfig, refreshToken) {
|
||||||
//refreshOAuthAccessToken
|
const callbackUrl = await oidc.getCallbackUrl(db, chosenConfig)
|
||||||
|
let enrichedConfig
|
||||||
//configId for google and OIDC??
|
let strategy
|
||||||
async function reUpToken(refreshToken, configId) {
|
|
||||||
const db = getGlobalDB()
|
|
||||||
console.log(refreshToken, configId)
|
|
||||||
const config = await getScopedConfig(db, {
|
|
||||||
type: Configs.OIDC,
|
|
||||||
group: {}, //ctx.query.group, this was an empty object when authentication initially
|
|
||||||
})
|
|
||||||
|
|
||||||
const chosenConfig = config.configs[0] //.filter((c) => c.uuid === configId)[0]
|
|
||||||
let callbackUrl = await oidc.oidcCallbackUrl(db, chosenConfig)
|
|
||||||
|
|
||||||
//Remote Config
|
|
||||||
const enrichedConfig = await oidc.fetchOIDCStrategyConfig(
|
|
||||||
chosenConfig,
|
|
||||||
callbackUrl
|
|
||||||
)
|
|
||||||
|
|
||||||
const strategy = await oidc.strategyFactory(enrichedConfig, () => {
|
|
||||||
console.log("saveFn RETURN ARGS", JSON.stringify(arguments))
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
enrichedConfig = await oidc.fetchStrategyConfig(chosenConfig, callbackUrl)
|
||||||
|
if (!enrichedConfig) {
|
||||||
|
throw new Error("OIDC Config contents invalid")
|
||||||
|
}
|
||||||
|
strategy = await oidc.strategyFactory(enrichedConfig)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
throw new Error("Could not refresh OAuth Token")
|
||||||
|
}
|
||||||
|
|
||||||
refresh.use(strategy, {
|
refresh.use(strategy, {
|
||||||
setRefreshOAuth2() {
|
setRefreshOAuth2() {
|
||||||
return strategy._getOAuth2Client(enrichedConfig)
|
return strategy._getOAuth2Client(enrichedConfig)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
console.log("Testing")
|
|
||||||
|
|
||||||
// By default, the strat calls itself "openidconnect"
|
return new Promise(resolve => {
|
||||||
|
refresh.requestNewAccessToken(
|
||||||
|
Configs.OIDC,
|
||||||
|
refreshToken,
|
||||||
|
(err, accessToken, refreshToken, params) => {
|
||||||
|
resolve({ err, accessToken, refreshToken, params })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// refresh.requestNewAccessToken(
|
async function refreshGoogleAccessToken(db, config, refreshToken) {
|
||||||
// 'openidconnect',
|
let callbackUrl = await google.getCallbackUrl(db, config)
|
||||||
// refToken,
|
const googleConfig = await google.fetchStrategyConfig(config)
|
||||||
// (err, accessToken, refreshToken) => {
|
|
||||||
// console.log("REAUTH CB", err, accessToken, refreshToken);
|
let strategy
|
||||||
// })
|
try {
|
||||||
|
strategy = await google.strategyFactory(googleConfig, callbackUrl)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
throw new Error("Error constructing OIDC refresh strategy", err)
|
throw new Error("Error constructing OIDC refresh strategy", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("end")
|
refresh.use(strategy)
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
refresh.requestNewAccessToken(
|
||||||
|
Configs.GOOGLE,
|
||||||
|
refreshToken,
|
||||||
|
(err, accessToken, refreshToken, params) => {
|
||||||
|
resolve({ err, accessToken, refreshToken, params })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshOAuthToken(refreshToken, configType, configId) {
|
||||||
|
const db = getGlobalDB()
|
||||||
|
|
||||||
|
const config = await getScopedConfig(db, {
|
||||||
|
type: configType,
|
||||||
|
group: {},
|
||||||
|
})
|
||||||
|
|
||||||
|
let chosenConfig = {}
|
||||||
|
let refreshResponse
|
||||||
|
if (configType === Configs.OIDC) {
|
||||||
|
// configId - retrieved from cookie.
|
||||||
|
chosenConfig = config.configs.filter(c => c.uuid === configId)[0]
|
||||||
|
if (!chosenConfig) {
|
||||||
|
throw new Error("Invalid OIDC configuration")
|
||||||
|
}
|
||||||
|
refreshResponse = await refreshOIDCAccessToken(
|
||||||
|
db,
|
||||||
|
chosenConfig,
|
||||||
|
refreshToken
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
chosenConfig = config
|
||||||
|
refreshResponse = await refreshGoogleAccessToken(
|
||||||
|
db,
|
||||||
|
chosenConfig,
|
||||||
|
refreshToken
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(JSON.stringify(refreshResponse))
|
||||||
|
return refreshResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateUserOAuth(userId, oAuthConfig) {
|
||||||
|
const details = { ...oAuthConfig }
|
||||||
|
try {
|
||||||
|
const db = getGlobalDB()
|
||||||
|
const dbUser = db.get(userId)
|
||||||
|
|
||||||
|
//Do not overwrite the refresh token if a valid one is not provided.
|
||||||
|
if (typeof details.refreshToken !== "string") {
|
||||||
|
delete details.refreshToken
|
||||||
|
}
|
||||||
|
|
||||||
|
dbUser.oAuth2 = {
|
||||||
|
...dbUser.oAuth2,
|
||||||
|
...details,
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.put(dbUser)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Could not update OAuth details for current user", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -98,5 +163,6 @@ module.exports = {
|
||||||
authError,
|
authError,
|
||||||
buildCsrfMiddleware: csrf,
|
buildCsrfMiddleware: csrf,
|
||||||
internalApi,
|
internalApi,
|
||||||
reUpToken,
|
refreshOAuthToken,
|
||||||
|
updateUserOAuth,
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,8 @@ module.exports = (
|
||||||
}
|
}
|
||||||
if (!user && tenantId) {
|
if (!user && tenantId) {
|
||||||
user = { tenantId }
|
user = { tenantId }
|
||||||
|
} else {
|
||||||
|
delete user.password
|
||||||
}
|
}
|
||||||
// be explicit
|
// be explicit
|
||||||
if (authenticated !== true) {
|
if (authenticated !== true) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
||||||
|
const { ssoCallbackUrl } = require("./utils")
|
||||||
const { authenticateThirdParty } = require("./third-party-common")
|
const { authenticateThirdParty } = require("./third-party-common")
|
||||||
|
const { Configs } = require("../../../constants")
|
||||||
|
const environment = require("../../environment")
|
||||||
|
|
||||||
const buildVerifyFn = saveUserFn => {
|
const buildVerifyFn = saveUserFn => {
|
||||||
return (accessToken, refreshToken, profile, done) => {
|
return (accessToken, refreshToken, profile, done) => {
|
||||||
|
@ -57,5 +59,19 @@ exports.strategyFactory = async function (config, callbackUrl, saveUserFn) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.fetchStrategyConfig = async function (googleConfig) {
|
||||||
|
return (
|
||||||
|
googleConfig || {
|
||||||
|
clientID: environment.GOOGLE_CLIENT_ID,
|
||||||
|
clientSecret: environment.GOOGLE_CLIENT_SECRET,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getCallbackUrl = async function (db, config) {
|
||||||
|
return ssoCallbackUrl(db, config, Configs.GOOGLE)
|
||||||
|
}
|
||||||
|
|
||||||
// expose for testing
|
// expose for testing
|
||||||
exports.buildVerifyFn = buildVerifyFn
|
exports.buildVerifyFn = buildVerifyFn
|
||||||
|
|
|
@ -6,7 +6,7 @@ const users = require("../../users")
|
||||||
const { authError } = require("./utils")
|
const { authError } = require("./utils")
|
||||||
const { newid } = require("../../hashing")
|
const { newid } = require("../../hashing")
|
||||||
const { createASession } = require("../../security/sessions")
|
const { createASession } = require("../../security/sessions")
|
||||||
const { getTenantId } = require("../../tenancy")
|
const { getTenantId, getGlobalDB } = require("../../tenancy")
|
||||||
|
|
||||||
const INVALID_ERR = "Invalid credentials"
|
const INVALID_ERR = "Invalid credentials"
|
||||||
const SSO_NO_PASSWORD = "SSO user does not have a password set"
|
const SSO_NO_PASSWORD = "SSO user does not have a password set"
|
||||||
|
@ -55,6 +55,20 @@ exports.authenticate = async function (ctx, email, password, done) {
|
||||||
if (await compare(password, dbUser.password)) {
|
if (await compare(password, dbUser.password)) {
|
||||||
const sessionId = newid()
|
const sessionId = newid()
|
||||||
const tenantId = getTenantId()
|
const tenantId = getTenantId()
|
||||||
|
|
||||||
|
if (dbUser.provider || dbUser.providerType || dbUser.pictureUrl) {
|
||||||
|
delete dbUser.provider
|
||||||
|
delete dbUser.providerType
|
||||||
|
delete dbUser.pictureUrl
|
||||||
|
|
||||||
|
try {
|
||||||
|
const db = getGlobalDB()
|
||||||
|
await db.put(dbUser)
|
||||||
|
} catch (err) {
|
||||||
|
console.error("OAuth elements could not be purged")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await createASession(dbUser._id, { sessionId, tenantId })
|
await createASession(dbUser._id, { sessionId, tenantId })
|
||||||
|
|
||||||
dbUser.token = jwt.sign(
|
dbUser.token = jwt.sign(
|
||||||
|
|
|
@ -2,6 +2,7 @@ const fetch = require("node-fetch")
|
||||||
const OIDCStrategy = require("@techpass/passport-openidconnect").Strategy
|
const OIDCStrategy = require("@techpass/passport-openidconnect").Strategy
|
||||||
const { authenticateThirdParty } = require("./third-party-common")
|
const { authenticateThirdParty } = require("./third-party-common")
|
||||||
const { ssoCallbackUrl } = require("./utils")
|
const { ssoCallbackUrl } = require("./utils")
|
||||||
|
const { Configs } = require("../../../constants")
|
||||||
|
|
||||||
const buildVerifyFn = saveUserFn => {
|
const buildVerifyFn = saveUserFn => {
|
||||||
/**
|
/**
|
||||||
|
@ -93,14 +94,16 @@ function validEmail(value) {
|
||||||
exports.strategyFactory = async function (config, saveUserFn) {
|
exports.strategyFactory = async function (config, saveUserFn) {
|
||||||
try {
|
try {
|
||||||
const verify = buildVerifyFn(saveUserFn)
|
const verify = buildVerifyFn(saveUserFn)
|
||||||
return new OIDCStrategy(config, verify)
|
const strategy = new OIDCStrategy(config, verify)
|
||||||
|
strategy.name = "oidc"
|
||||||
|
return strategy
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
throw new Error("Error constructing OIDC authentication strategy", err)
|
throw new Error("Error constructing OIDC authentication strategy", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchOIDCStrategyConfig = async (config, callbackUrl) => {
|
exports.fetchStrategyConfig = async function (config, callbackUrl) {
|
||||||
try {
|
try {
|
||||||
const { clientID, clientSecret, configUrl } = config
|
const { clientID, clientSecret, configUrl } = config
|
||||||
|
|
||||||
|
@ -136,8 +139,8 @@ export const fetchOIDCStrategyConfig = async (config, callbackUrl) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const oidcCallbackUrl = async (db, config) => {
|
exports.getCallbackUrl = async function (db, config) {
|
||||||
return ssoCallbackUrl(db, config, "oidc")
|
return ssoCallbackUrl(db, config, Configs.OIDC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// expose for testing
|
// expose for testing
|
||||||
|
|
|
@ -85,11 +85,11 @@ filterTests(['all'], () => {
|
||||||
cy.get(interact.APP_TABLE_APP_NAME).click({ force: true })
|
cy.get(interact.APP_TABLE_APP_NAME).click({ force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get(interact.DEPLOYMENT_TOP_NAV).click()
|
cy.get(interact.DEPLOYMENT_TOP_GLOBE).should("exist").click({ force: true })
|
||||||
cy.get(interact.PUBLISH_POPOVER_ACTION).click({ force: true })
|
|
||||||
cy.get(interact.UNPUBLISH_MODAL)
|
cy.get("[data-cy='publish-popover-menu']")
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(interact.CONFIRM_WRAP_BUTTON).click({ force: true })
|
cy.get(interact.PUBLISH_POPOVER_ACTION).click({ force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
cy.get(interact.UNPUBLISH_MODAL).should("be.visible")
|
cy.get(interact.UNPUBLISH_MODAL).should("be.visible")
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { getAppDB } from "@budibase/backend-core/context"
|
||||||
import { quotas } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
import { events } from "@budibase/backend-core"
|
import { events } from "@budibase/backend-core"
|
||||||
import { getCookie } from "@budibase/backend-core/utils"
|
import { getCookie } from "@budibase/backend-core/utils"
|
||||||
import { Cookies } from "@budibase/backend-core/constants"
|
import { Cookies, Configs } from "@budibase/backend-core/constants"
|
||||||
|
|
||||||
const Runner = new Thread(ThreadType.QUERY, {
|
const Runner = new Thread(ThreadType.QUERY, {
|
||||||
timeoutMs: QUERY_THREAD_TIMEOUT || 10000,
|
timeoutMs: QUERY_THREAD_TIMEOUT || 10000,
|
||||||
|
@ -112,6 +112,21 @@ export async function find(ctx: any) {
|
||||||
ctx.body = query
|
ctx.body = query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Required to discern between OIDC OAuth config entries
|
||||||
|
function getOAuthConfigCookieId(ctx: any) {
|
||||||
|
if (ctx.user.providerType === Configs.OIDC) {
|
||||||
|
return getCookie(ctx, Cookies.OIDC_CONFIG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAuthConfig(ctx: any) {
|
||||||
|
const authCookie = getCookie(ctx, Cookies.Auth)
|
||||||
|
let authConfigCtx: any = {}
|
||||||
|
authConfigCtx["configId"] = getOAuthConfigCookieId(ctx)
|
||||||
|
authConfigCtx["sessionId"] = authCookie ? authCookie.sessionId : null
|
||||||
|
return authConfigCtx
|
||||||
|
}
|
||||||
|
|
||||||
export async function preview(ctx: any) {
|
export async function preview(ctx: any) {
|
||||||
const db = getAppDB()
|
const db = getAppDB()
|
||||||
|
|
||||||
|
@ -121,9 +136,7 @@ export async function preview(ctx: any) {
|
||||||
// this stops dynamic variables from calling the same query
|
// this stops dynamic variables from calling the same query
|
||||||
const { fields, parameters, queryVerb, transformer, queryId } = query
|
const { fields, parameters, queryVerb, transformer, queryId } = query
|
||||||
|
|
||||||
//check for oAuth elements here?
|
const authConfigCtx: any = getAuthConfig(ctx)
|
||||||
const configId = getCookie(ctx, Cookies.OIDC_CONFIG)
|
|
||||||
console.log(configId)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const runFn = () =>
|
const runFn = () =>
|
||||||
|
@ -135,6 +148,10 @@ export async function preview(ctx: any) {
|
||||||
parameters,
|
parameters,
|
||||||
transformer,
|
transformer,
|
||||||
queryId,
|
queryId,
|
||||||
|
ctx: {
|
||||||
|
user: ctx.user,
|
||||||
|
auth: { ...authConfigCtx },
|
||||||
|
},
|
||||||
})
|
})
|
||||||
const { rows, keys, info, extra } = await quotas.addQuery(runFn)
|
const { rows, keys, info, extra } = await quotas.addQuery(runFn)
|
||||||
await events.query.previewed(datasource, query)
|
await events.query.previewed(datasource, query)
|
||||||
|
@ -177,6 +194,9 @@ async function execute(ctx: any, opts = { rowsOnly: false }) {
|
||||||
parameters: enrichedParameters,
|
parameters: enrichedParameters,
|
||||||
transformer: query.transformer,
|
transformer: query.transformer,
|
||||||
queryId: ctx.params.queryId,
|
queryId: ctx.params.queryId,
|
||||||
|
ctx: {
|
||||||
|
user: ctx.user,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const { rows, pagination, extra } = await quotas.addQuery(runFn)
|
const { rows, pagination, extra } = await quotas.addQuery(runFn)
|
||||||
|
|
|
@ -8,3 +8,4 @@ declare module "@budibase/backend-core/constants"
|
||||||
declare module "@budibase/backend-core/auth"
|
declare module "@budibase/backend-core/auth"
|
||||||
declare module "@budibase/backend-core/sessions"
|
declare module "@budibase/backend-core/sessions"
|
||||||
declare module "@budibase/backend-core/encryption"
|
declare module "@budibase/backend-core/encryption"
|
||||||
|
declare module "@budibase/backend-core/utils"
|
||||||
|
|
|
@ -4,7 +4,12 @@ const ScriptRunner = require("../utilities/scriptRunner")
|
||||||
const { integrations } = require("../integrations")
|
const { integrations } = require("../integrations")
|
||||||
const { processStringSync } = require("@budibase/string-templates")
|
const { processStringSync } = require("@budibase/string-templates")
|
||||||
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
||||||
// const { reUpToken } = require("@budibase/backend-core/auth")
|
const {
|
||||||
|
refreshOAuthToken,
|
||||||
|
updateUserOAuth,
|
||||||
|
} = require("@budibase/backend-core/auth")
|
||||||
|
const { getGlobalIDFromUserMetadataID } = require("../db/utils")
|
||||||
|
|
||||||
const { isSQL } = require("../integrations/utils")
|
const { isSQL } = require("../integrations/utils")
|
||||||
const {
|
const {
|
||||||
enrichQueryFields,
|
enrichQueryFields,
|
||||||
|
@ -22,20 +27,19 @@ class QueryRunner {
|
||||||
this.queryId = input.queryId
|
this.queryId = input.queryId
|
||||||
this.noRecursiveQuery = flags.noRecursiveQuery
|
this.noRecursiveQuery = flags.noRecursiveQuery
|
||||||
this.cachedVariables = []
|
this.cachedVariables = []
|
||||||
|
// Additional context items for enrichment
|
||||||
|
this.ctx = input.ctx
|
||||||
// allows the response from a query to be stored throughout this
|
// allows the response from a query to be stored throughout this
|
||||||
// execution so that if it needs to be re-used for another variable
|
// execution so that if it needs to be re-used for another variable
|
||||||
// it can be
|
// it can be
|
||||||
this.queryResponse = {}
|
this.queryResponse = {}
|
||||||
this.hasRerun = false
|
this.hasRerun = false
|
||||||
|
this.hasRefreshedOAuth = false
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute() {
|
async execute() {
|
||||||
let { datasource, fields, queryVerb, transformer } = this
|
let { datasource, fields, queryVerb, transformer } = this
|
||||||
|
|
||||||
// if(this.ctx.user.oauth2?.refreshToken){
|
|
||||||
// reUpToken(this.ctx.user.oauth2?.refreshToken)
|
|
||||||
// }
|
|
||||||
|
|
||||||
const Integration = integrations[datasource.source]
|
const Integration = integrations[datasource.source]
|
||||||
if (!Integration) {
|
if (!Integration) {
|
||||||
throw "Integration type does not exist."
|
throw "Integration type does not exist."
|
||||||
|
@ -79,15 +83,24 @@ class QueryRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the request fails we retry once, invalidating the cached value
|
// if the request fails we retry once, invalidating the cached value
|
||||||
|
if (info && info.code >= 400 && !this.hasRerun) {
|
||||||
if (
|
if (
|
||||||
info &&
|
this.ctx.user?.provider &&
|
||||||
info.code >= 400 &&
|
info.code === 401 &&
|
||||||
this.cachedVariables.length > 0 &&
|
!this.hasRefreshedOAuth
|
||||||
!this.hasRerun
|
|
||||||
) {
|
) {
|
||||||
// return { info }
|
// Attempt to refresh the access token from the provider
|
||||||
|
this.hasRefreshedOAuth = true
|
||||||
|
const authResponse = await this.refreshOAuth2(this.ctx)
|
||||||
|
|
||||||
|
if (!authResponse || authResponse.err) {
|
||||||
|
// In this event the user may have oAuth issues that
|
||||||
|
// could require re-authenticating with their provider.
|
||||||
|
throw new Error("OAuth2 access token could not be refreshed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.hasRerun = true
|
this.hasRerun = true
|
||||||
// invalidate the cache value
|
|
||||||
await threadUtils.invalidateDynamicVariables(this.cachedVariables)
|
await threadUtils.invalidateDynamicVariables(this.cachedVariables)
|
||||||
return this.execute()
|
return this.execute()
|
||||||
}
|
}
|
||||||
|
@ -133,6 +146,31 @@ class QueryRunner {
|
||||||
).execute()
|
).execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async refreshOAuth2(ctx) {
|
||||||
|
const { oauth2, providerType, _id } = ctx.user
|
||||||
|
const { configId } = ctx.auth
|
||||||
|
|
||||||
|
if (!providerType || !oauth2?.refreshToken) {
|
||||||
|
console.error("No refresh token found for authenticated user")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await refreshOAuthToken(
|
||||||
|
oauth2.refreshToken,
|
||||||
|
providerType,
|
||||||
|
configId
|
||||||
|
)
|
||||||
|
|
||||||
|
// Refresh session flow. Should be in same location as refreshOAuthToken
|
||||||
|
// There are several other properties available in 'resp'
|
||||||
|
if (!resp.error) {
|
||||||
|
const globalUserId = getGlobalIDFromUserMetadataID(_id)
|
||||||
|
await updateUserOAuth(globalUserId, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
async getDynamicVariable(variable) {
|
async getDynamicVariable(variable) {
|
||||||
let { parameters } = this
|
let { parameters } = this
|
||||||
const queryId = variable.queryId,
|
const queryId = variable.queryId,
|
||||||
|
|
|
@ -70,7 +70,7 @@ async function authInternal(ctx: any, user: any, err = null, info = null) {
|
||||||
export const authenticate = async (ctx: any, next: any) => {
|
export const authenticate = async (ctx: any, next: any) => {
|
||||||
return passport.authenticate(
|
return passport.authenticate(
|
||||||
"local",
|
"local",
|
||||||
async (err: any, user: User, info: any) => {
|
async (err: any, user: any, info: any) => {
|
||||||
await authInternal(ctx, user, err, info)
|
await authInternal(ctx, user, err, info)
|
||||||
await context.identity.doInUserContext(user, async () => {
|
await context.identity.doInUserContext(user, async () => {
|
||||||
await events.auth.login("local")
|
await events.auth.login("local")
|
||||||
|
@ -197,7 +197,9 @@ export const googlePreAuth = async (ctx: any, next: any) => {
|
||||||
const strategy = await google.strategyFactory(config, callbackUrl, users.save)
|
const strategy = await google.strategyFactory(config, callbackUrl, users.save)
|
||||||
|
|
||||||
return passport.authenticate(strategy, {
|
return passport.authenticate(strategy, {
|
||||||
scope: ["profile", "email"],
|
scope: ["profile", "email", "https://www.googleapis.com/auth/spreadsheets"],
|
||||||
|
accessType: "offline",
|
||||||
|
prompt: "consent",
|
||||||
})(ctx, next)
|
})(ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +237,7 @@ export const oidcStrategyFactory = async (ctx: any, configId: any) => {
|
||||||
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
|
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
|
||||||
|
|
||||||
//Remote Config
|
//Remote Config
|
||||||
const enrichedConfig = await oidc.fetchOIDCStrategyConfig(
|
const enrichedConfig = await oidc.fetchStrategyConfig(
|
||||||
chosenConfig,
|
chosenConfig,
|
||||||
callbackUrl
|
callbackUrl
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue