Add developer usage restrictions to SSO user creation
This commit is contained in:
parent
e695a57853
commit
661367333d
|
@ -2,7 +2,8 @@ const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy
|
||||||
|
|
||||||
const { authenticateThirdParty } = require("./third-party-common")
|
const { authenticateThirdParty } = require("./third-party-common")
|
||||||
|
|
||||||
async function authenticate(accessToken, refreshToken, profile, done) {
|
const buildVerifyFn = async saveUserFn => {
|
||||||
|
return (accessToken, refreshToken, profile, done) => {
|
||||||
const thirdPartyUser = {
|
const thirdPartyUser = {
|
||||||
provider: profile.provider, // should always be 'google'
|
provider: profile.provider, // should always be 'google'
|
||||||
providerType: "google",
|
providerType: "google",
|
||||||
|
@ -18,20 +19,18 @@ async function authenticate(accessToken, refreshToken, profile, done) {
|
||||||
return authenticateThirdParty(
|
return authenticateThirdParty(
|
||||||
thirdPartyUser,
|
thirdPartyUser,
|
||||||
true, // require local accounts to exist
|
true, // require local accounts to exist
|
||||||
done
|
done,
|
||||||
|
saveUserFn
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of the google passport strategy. This wrapper fetches the configuration
|
* Create an instance of the google passport strategy. This wrapper fetches the configuration
|
||||||
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
||||||
* @returns Dynamically configured Passport Google Strategy
|
* @returns Dynamically configured Passport Google Strategy
|
||||||
*/
|
*/
|
||||||
exports.strategyFactory = async function (
|
exports.strategyFactory = async function (config, callbackUrl, saveUserFn) {
|
||||||
config,
|
|
||||||
callbackUrl,
|
|
||||||
verify = authenticate
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
const { clientID, clientSecret } = config
|
const { clientID, clientSecret } = config
|
||||||
|
|
||||||
|
@ -41,6 +40,7 @@ exports.strategyFactory = async function (
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const verify = buildVerifyFn(saveUserFn)
|
||||||
return new GoogleStrategy(
|
return new GoogleStrategy(
|
||||||
{
|
{
|
||||||
clientID: config.clientID,
|
clientID: config.clientID,
|
||||||
|
@ -55,4 +55,4 @@ exports.strategyFactory = async function (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// expose for testing
|
// expose for testing
|
||||||
exports.authenticate = authenticate
|
exports.authenticate = buildVerifyFn
|
||||||
|
|
|
@ -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 buildVerifyFn = saveUserFn => {
|
||||||
/**
|
/**
|
||||||
* @param {*} issuer The identity provider base URL
|
* @param {*} issuer The identity provider base URL
|
||||||
* @param {*} sub The user ID
|
* @param {*} sub The user ID
|
||||||
|
@ -13,7 +14,7 @@ const { authenticateThirdParty } = require("./third-party-common")
|
||||||
* @param {*} params The response body from requesting an access_token
|
* @param {*} params The response body from requesting an access_token
|
||||||
* @param {*} done The passport callback: err, user, info
|
* @param {*} done The passport callback: err, user, info
|
||||||
*/
|
*/
|
||||||
async function authenticate(
|
return async (
|
||||||
issuer,
|
issuer,
|
||||||
sub,
|
sub,
|
||||||
profile,
|
profile,
|
||||||
|
@ -23,7 +24,7 @@ async function authenticate(
|
||||||
idToken,
|
idToken,
|
||||||
params,
|
params,
|
||||||
done
|
done
|
||||||
) {
|
) => {
|
||||||
const thirdPartyUser = {
|
const thirdPartyUser = {
|
||||||
// store the issuer info to enable sync in future
|
// store the issuer info to enable sync in future
|
||||||
provider: issuer,
|
provider: issuer,
|
||||||
|
@ -40,9 +41,11 @@ async function authenticate(
|
||||||
return authenticateThirdParty(
|
return authenticateThirdParty(
|
||||||
thirdPartyUser,
|
thirdPartyUser,
|
||||||
false, // don't require local accounts to exist
|
false, // don't require local accounts to exist
|
||||||
done
|
done,
|
||||||
|
saveUserFn
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {*} profile The structured profile created by passport using the user info endpoint
|
* @param {*} profile The structured profile created by passport using the user info endpoint
|
||||||
|
@ -86,7 +89,7 @@ function validEmail(value) {
|
||||||
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
||||||
* @returns Dynamically configured Passport OIDC Strategy
|
* @returns Dynamically configured Passport OIDC Strategy
|
||||||
*/
|
*/
|
||||||
exports.strategyFactory = async function (config, callbackUrl) {
|
exports.strategyFactory = async function (config, callbackUrl, saveUserFn) {
|
||||||
try {
|
try {
|
||||||
const { clientID, clientSecret, configUrl } = config
|
const { clientID, clientSecret, configUrl } = config
|
||||||
|
|
||||||
|
@ -106,6 +109,7 @@ exports.strategyFactory = async function (config, callbackUrl) {
|
||||||
|
|
||||||
const body = await response.json()
|
const body = await response.json()
|
||||||
|
|
||||||
|
const verify = buildVerifyFn(saveUserFn)
|
||||||
return new OIDCStrategy(
|
return new OIDCStrategy(
|
||||||
{
|
{
|
||||||
issuer: body.issuer,
|
issuer: body.issuer,
|
||||||
|
@ -116,7 +120,7 @@ exports.strategyFactory = async function (config, callbackUrl) {
|
||||||
clientSecret: clientSecret,
|
clientSecret: clientSecret,
|
||||||
callbackURL: callbackUrl,
|
callbackURL: callbackUrl,
|
||||||
},
|
},
|
||||||
authenticate
|
verify
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
@ -125,4 +129,4 @@ exports.strategyFactory = async function (config, callbackUrl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// expose for testing
|
// expose for testing
|
||||||
exports.authenticate = authenticate
|
exports.authenticate = buildVerifyFn
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const jwt = require("jsonwebtoken")
|
const jwt = require("jsonwebtoken")
|
||||||
const { generateGlobalUserID } = require("../../db/utils")
|
const { generateGlobalUserID } = require("../../db/utils")
|
||||||
const { saveUser } = require("../../utils")
|
|
||||||
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")
|
||||||
|
@ -16,8 +15,11 @@ exports.authenticateThirdParty = async function (
|
||||||
thirdPartyUser,
|
thirdPartyUser,
|
||||||
requireLocalAccount = true,
|
requireLocalAccount = true,
|
||||||
done,
|
done,
|
||||||
saveUserFn = saveUser
|
saveUserFn
|
||||||
) {
|
) {
|
||||||
|
if (!saveUserFn) {
|
||||||
|
throw new Error("Save user function must be provided")
|
||||||
|
}
|
||||||
if (!thirdPartyUser.provider) {
|
if (!thirdPartyUser.provider) {
|
||||||
return authError(done, "third party user provider required")
|
return authError(done, "third party user provider required")
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,12 +181,6 @@ exports.saveUser = async (
|
||||||
hashPassword = true,
|
hashPassword = true,
|
||||||
requirePassword = true
|
requirePassword = true
|
||||||
) => {
|
) => {
|
||||||
// // new user
|
|
||||||
// // check license restrictions
|
|
||||||
// if (!user._id && user.builder) {
|
|
||||||
// await limits.checkMaxDevelopers()
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (!tenantId) {
|
if (!tenantId) {
|
||||||
throw "No tenancy specified."
|
throw "No tenancy specified."
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const { getAppDB } = require("@budibase/backend-core/context")
|
||||||
import { isTest } from "../../../environment"
|
import { isTest } from "../../../environment"
|
||||||
import { cleanupAttachments } from "../../../utilities/rowProcessor"
|
import { cleanupAttachments } from "../../../utilities/rowProcessor"
|
||||||
import { runStaticFormulaChecks } from "./bulkFormula"
|
import { runStaticFormulaChecks } from "./bulkFormula"
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export async function save(ctx: any) {
|
export async function save(ctx: any) {
|
||||||
const db = getAppDB()
|
const db = getAppDB()
|
||||||
|
@ -120,10 +120,10 @@ export async function destroy(ctx: any) {
|
||||||
await db.bulkDocs(
|
await db.bulkDocs(
|
||||||
rows.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
|
rows.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
|
||||||
)
|
)
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
await quotas.updateUsage(
|
||||||
-rows.rows.length,
|
-rows.rows.length,
|
||||||
Pro.StaticQuotaName.ROWS,
|
StaticQuotaName.ROWS,
|
||||||
Pro.QuotaUsageType.STATIC
|
QuotaUsageType.STATIC
|
||||||
)
|
)
|
||||||
|
|
||||||
// update linked rows
|
// update linked rows
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { getViews, saveView } from "../view/utils"
|
||||||
import viewTemplate from "../view/viewBuilder"
|
import viewTemplate from "../view/viewBuilder"
|
||||||
const { getAppDB } = require("@budibase/backend-core/context")
|
const { getAppDB } = require("@budibase/backend-core/context")
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export async function clearColumns(table: any, columnNames: any) {
|
export async function clearColumns(table: any, columnNames: any) {
|
||||||
const db = getAppDB()
|
const db = getAppDB()
|
||||||
|
@ -117,7 +117,7 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
|
||||||
existingTable: table,
|
existingTable: table,
|
||||||
})
|
})
|
||||||
|
|
||||||
let finalData = []
|
let finalData: any = []
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
let row = data[i]
|
let row = data[i]
|
||||||
row._id = generateRowID(table._id)
|
row._id = generateRowID(table._id)
|
||||||
|
@ -147,19 +147,11 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
|
||||||
finalData.push(row)
|
finalData.push(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
await quotas.tryUpdateUsage(
|
||||||
|
() => db.bulkDocs(finalData),
|
||||||
finalData.length,
|
finalData.length,
|
||||||
Pro.StaticQuotaName.ROWS,
|
StaticQuotaName.ROWS,
|
||||||
Pro.QuotaUsageType.STATIC,
|
QuotaUsageType.STATIC
|
||||||
{
|
|
||||||
dryRun: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await db.bulkDocs(finalData)
|
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
|
||||||
finalData.length,
|
|
||||||
Pro.StaticQuotaName.ROWS,
|
|
||||||
Pro.QuotaUsageType.STATIC
|
|
||||||
)
|
)
|
||||||
let response = await db.put(table)
|
let response = await db.put(table)
|
||||||
table._rev = response._rev
|
table._rev = response._rev
|
||||||
|
|
|
@ -12,7 +12,7 @@ const zlib = require("zlib")
|
||||||
const { mainRoutes, staticRoutes } = require("./routes")
|
const { mainRoutes, staticRoutes } = require("./routes")
|
||||||
const pkg = require("../../package.json")
|
const pkg = require("../../package.json")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const Pro = require("@budibase/pro")
|
const { middleware: pro } = require("@budibase/pro")
|
||||||
|
|
||||||
const router = new Router()
|
const router = new Router()
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ router
|
||||||
.use(currentApp)
|
.use(currentApp)
|
||||||
// this middleware will try to use the app ID to determine the tenancy
|
// this middleware will try to use the app ID to determine the tenancy
|
||||||
.use(buildAppTenancyMiddleware())
|
.use(buildAppTenancyMiddleware())
|
||||||
.use(Pro.Middleware.Licensing())
|
.use(pro.licensing())
|
||||||
.use(auditLog)
|
.use(auditLog)
|
||||||
|
|
||||||
// error handling middleware
|
// error handling middleware
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
import { save } from "../../api/controllers/row"
|
import { save } from "../../api/controllers/row"
|
||||||
import { cleanUpRow, getError } from "../automationUtils"
|
import { cleanUpRow, getError } from "../automationUtils"
|
||||||
import * as Pro from "@budibase/pro"
|
|
||||||
import { buildCtx } from "./utils"
|
import { buildCtx } from "./utils"
|
||||||
|
|
||||||
export const definition = {
|
export const definition = {
|
||||||
|
@ -78,19 +78,11 @@ export async function run({ inputs, appId, emitter }: any) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
inputs.row = await cleanUpRow(inputs.row.tableId, inputs.row)
|
inputs.row = await cleanUpRow(inputs.row.tableId, inputs.row)
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
await quotas.tryUpdateUsage(
|
||||||
|
() => save(ctx),
|
||||||
1,
|
1,
|
||||||
Pro.StaticQuotaName.ROWS,
|
StaticQuotaName.ROWS,
|
||||||
Pro.QuotaUsageType.STATIC,
|
QuotaUsageType.STATIC
|
||||||
{
|
|
||||||
dryRun: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await save(ctx)
|
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
|
||||||
1,
|
|
||||||
Pro.StaticQuotaName.ROWS,
|
|
||||||
Pro.QuotaUsageType.STATIC
|
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
row: inputs.row,
|
row: inputs.row,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { destroy } from "../../api/controllers/row"
|
import { destroy } from "../../api/controllers/row"
|
||||||
import * as Pro from "@budibase/pro"
|
|
||||||
import { buildCtx } from "./utils"
|
import { buildCtx } from "./utils"
|
||||||
import { getError } from "../automationUtils"
|
import { getError } from "../automationUtils"
|
||||||
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export const definition = {
|
export const definition = {
|
||||||
description: "Delete a row from your database",
|
description: "Delete a row from your database",
|
||||||
|
@ -73,11 +73,7 @@ export async function run({ inputs, appId, emitter }: any) {
|
||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
await quotas.updateUsage(-1, StaticQuotaName.ROWS, QuotaUsageType.STATIC)
|
||||||
-1,
|
|
||||||
Pro.StaticQuotaName.ROWS,
|
|
||||||
Pro.QuotaUsageType.STATIC
|
|
||||||
)
|
|
||||||
await destroy(ctx)
|
await destroy(ctx)
|
||||||
return {
|
return {
|
||||||
response: ctx.body,
|
response: ctx.body,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas, StaticQuotaName, QuotaUsageType } from "@budibase/pro"
|
||||||
const { getUniqueRows } = require("../utilities/usageQuota/rows")
|
const { getUniqueRows } = require("../utilities/usageQuota/rows")
|
||||||
const {
|
const {
|
||||||
isExternalTable,
|
isExternalTable,
|
||||||
|
@ -14,12 +14,12 @@ const METHOD_MAP: any = {
|
||||||
|
|
||||||
const DOMAIN_MAP: any = {
|
const DOMAIN_MAP: any = {
|
||||||
rows: {
|
rows: {
|
||||||
name: Pro.StaticQuotaName.ROWS,
|
name: StaticQuotaName.ROWS,
|
||||||
type: Pro.QuotaUsageType.STATIC,
|
type: QuotaUsageType.STATIC,
|
||||||
},
|
},
|
||||||
applications: {
|
applications: {
|
||||||
name: Pro.StaticQuotaName.APPS,
|
name: StaticQuotaName.APPS,
|
||||||
type: Pro.QuotaUsageType.STATIC,
|
type: QuotaUsageType.STATIC,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ function getQuotaInfo(url: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = async (ctx: any, next: any) => {
|
module.exports = async (ctx: any, next: any) => {
|
||||||
if (!Pro.Licensing.Quotas.useQuotas()) {
|
if (!quotas.useQuotas()) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ const performRequest = async (
|
||||||
const usageContext = {
|
const usageContext = {
|
||||||
skipNext: false,
|
skipNext: false,
|
||||||
skipUsage: false,
|
skipUsage: false,
|
||||||
[Pro.StaticQuotaName.APPS]: {},
|
[StaticQuotaName.APPS]: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const quotaName = quotaInfo.name
|
const quotaName = quotaInfo.name
|
||||||
|
@ -96,7 +96,7 @@ const performRequest = async (
|
||||||
|
|
||||||
// run the request
|
// run the request
|
||||||
if (!usageContext.skipNext) {
|
if (!usageContext.skipNext) {
|
||||||
await Pro.Licensing.Quotas.updateUsage(usage, quotaName, quotaInfo.type, {
|
await quotas.updateUsage(usage, quotaName, quotaInfo.type, {
|
||||||
dryRun: true,
|
dryRun: true,
|
||||||
})
|
})
|
||||||
await next()
|
await next()
|
||||||
|
@ -114,7 +114,7 @@ const performRequest = async (
|
||||||
|
|
||||||
// update the usage
|
// update the usage
|
||||||
if (!usageContext.skipUsage) {
|
if (!usageContext.skipUsage) {
|
||||||
await Pro.Licensing.Quotas.updateUsage(usage, quotaName, quotaInfo.type)
|
await quotas.updateUsage(usage, quotaName, quotaInfo.type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,18 +128,18 @@ const appPreDelete = async (ctx: any, usageContext: any) => {
|
||||||
// store the row count to delete
|
// store the row count to delete
|
||||||
const rows = await getUniqueRows([ctx.appId])
|
const rows = await getUniqueRows([ctx.appId])
|
||||||
if (rows.length) {
|
if (rows.length) {
|
||||||
usageContext[Pro.StaticQuotaName.APPS] = { rowCount: rows.length }
|
usageContext[StaticQuotaName.APPS] = { rowCount: rows.length }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const appPostDelete = async (ctx: any, usageContext: any) => {
|
const appPostDelete = async (ctx: any, usageContext: any) => {
|
||||||
// delete the app rows from usage
|
// delete the app rows from usage
|
||||||
const rowCount = usageContext[Pro.StaticQuotaName.APPS].rowCount
|
const rowCount = usageContext[StaticQuotaName.APPS].rowCount
|
||||||
if (rowCount) {
|
if (rowCount) {
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
await quotas.updateUsage(
|
||||||
-rowCount,
|
-rowCount,
|
||||||
Pro.StaticQuotaName.ROWS,
|
StaticQuotaName.ROWS,
|
||||||
Pro.QuotaUsageType.STATIC
|
QuotaUsageType.STATIC
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,24 +149,24 @@ const appPostCreate = async (ctx: any) => {
|
||||||
if (ctx.request.body.useTemplate === "true") {
|
if (ctx.request.body.useTemplate === "true") {
|
||||||
const rows = await getUniqueRows([ctx.response.body.appId])
|
const rows = await getUniqueRows([ctx.response.body.appId])
|
||||||
const rowCount = rows ? rows.length : 0
|
const rowCount = rows ? rows.length : 0
|
||||||
await Pro.Licensing.Quotas.updateUsage(
|
await quotas.updateUsage(
|
||||||
rowCount,
|
rowCount,
|
||||||
Pro.StaticQuotaName.ROWS,
|
StaticQuotaName.ROWS,
|
||||||
Pro.QuotaUsageType.STATIC
|
QuotaUsageType.STATIC
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PRE_DELETE: any = {
|
const PRE_DELETE: any = {
|
||||||
[Pro.StaticQuotaName.APPS]: appPreDelete,
|
[StaticQuotaName.APPS]: appPreDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
const POST_DELETE: any = {
|
const POST_DELETE: any = {
|
||||||
[Pro.StaticQuotaName.APPS]: appPostDelete,
|
[StaticQuotaName.APPS]: appPostDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
const PRE_CREATE: any = {}
|
const PRE_CREATE: any = {}
|
||||||
|
|
||||||
const POST_CREATE: any = {
|
const POST_CREATE: any = {
|
||||||
[Pro.StaticQuotaName.APPS]: appPostCreate,
|
[StaticQuotaName.APPS]: appPostCreate,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
|
|
||||||
export const runQuotaMigration = async (migration: Function) => {
|
export const runQuotaMigration = async (migration: Function) => {
|
||||||
if (!Pro.Licensing.Quotas.useQuotas()) {
|
if (!quotas.useQuotas()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await migration()
|
await migration()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getTenantId } from "@budibase/backend-core/tenancy"
|
import { getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
// get app count
|
// get app count
|
||||||
|
@ -11,9 +11,5 @@ export const run = async () => {
|
||||||
// sync app count
|
// sync app count
|
||||||
const tenantId = getTenantId()
|
const tenantId = getTenantId()
|
||||||
console.log(`[Tenant: ${tenantId}] Syncing app count: ${appCount}`)
|
console.log(`[Tenant: ${tenantId}] Syncing app count: ${appCount}`)
|
||||||
await Pro.Licensing.Quotas.setUsage(
|
await quotas.setUsage(appCount, StaticQuotaName.APPS, QuotaUsageType.STATIC)
|
||||||
appCount,
|
|
||||||
Pro.StaticQuotaName.APPS,
|
|
||||||
Pro.QuotaUsageType.STATIC
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getTenantId } from "@budibase/backend-core/tenancy"
|
import { getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
import { utils } from "@budibase/backend-core"
|
import { utils } from "@budibase/backend-core"
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
// get developer count
|
// get developer count
|
||||||
|
@ -11,9 +11,9 @@ export const run = async () => {
|
||||||
console.log(
|
console.log(
|
||||||
`[Tenant: ${tenantId}] Syncing developer count: ${developerCount}`
|
`[Tenant: ${tenantId}] Syncing developer count: ${developerCount}`
|
||||||
)
|
)
|
||||||
await Pro.Licensing.Quotas.setUsage(
|
await quotas.setUsage(
|
||||||
developerCount,
|
developerCount,
|
||||||
Pro.StaticQuotaName.DEVELOPERS,
|
StaticQuotaName.DEVELOPERS,
|
||||||
Pro.QuotaUsageType.STATIC
|
QuotaUsageType.STATIC
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getTenantId } from "@budibase/backend-core/tenancy"
|
import { getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import * as Pro from "@budibase/pro"
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
// get app count
|
// get app count
|
||||||
|
@ -13,9 +13,9 @@ export const run = async () => {
|
||||||
console.log(
|
console.log(
|
||||||
`[Tenant: ${tenantId}] Syncing published app count: ${prodAppCount}`
|
`[Tenant: ${tenantId}] Syncing published app count: ${prodAppCount}`
|
||||||
)
|
)
|
||||||
await Pro.Licensing.Quotas.setUsage(
|
await quotas.setUsage(
|
||||||
prodAppCount,
|
prodAppCount,
|
||||||
Pro.StaticQuotaName.PUBLISHED_APPS,
|
StaticQuotaName.PUBLISHED_APPS,
|
||||||
Pro.QuotaUsageType.STATIC
|
QuotaUsageType.STATIC
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { getTenantId } from "@budibase/backend-core/tenancy"
|
import { getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import * as Pro from "@budibase/pro"
|
|
||||||
import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
||||||
|
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
// get all rows in all apps
|
// get all rows in all apps
|
||||||
|
@ -15,9 +15,5 @@ export const run = async () => {
|
||||||
// sync row count
|
// sync row count
|
||||||
const tenantId = getTenantId()
|
const tenantId = getTenantId()
|
||||||
console.log(`[Tenant: ${tenantId}] Syncing row count: ${rowCount}`)
|
console.log(`[Tenant: ${tenantId}] Syncing row count: ${rowCount}`)
|
||||||
await Pro.Licensing.Quotas.setUsage(
|
await quotas.setUsage(rowCount, StaticQuotaName.ROWS, QuotaUsageType.STATIC)
|
||||||
rowCount,
|
|
||||||
Pro.StaticQuotaName.ROWS,
|
|
||||||
Pro.QuotaUsageType.STATIC
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import * as pro from "@budibase/pro"
|
|
||||||
|
|
||||||
export const run = () => {
|
|
||||||
if (process.env.PRO) {
|
|
||||||
console.log(pro)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,8 +21,9 @@ const {
|
||||||
isMultiTenant,
|
isMultiTenant,
|
||||||
} = require("@budibase/backend-core/tenancy")
|
} = require("@budibase/backend-core/tenancy")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
|
import { users } from "@budibase/pro"
|
||||||
|
|
||||||
const ssoCallbackUrl = async (config, type) => {
|
const ssoCallbackUrl = async (config: any, type: any) => {
|
||||||
// incase there is a callback URL from before
|
// incase there is a callback URL from before
|
||||||
if (config && config.callbackURL) {
|
if (config && config.callbackURL) {
|
||||||
return config.callbackURL
|
return config.callbackURL
|
||||||
|
@ -42,15 +43,15 @@ const ssoCallbackUrl = async (config, type) => {
|
||||||
return `${publicConfig.platformUrl}${callbackUrl}`
|
return `${publicConfig.platformUrl}${callbackUrl}`
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.googleCallbackUrl = async config => {
|
export const googleCallbackUrl = async (config: any) => {
|
||||||
return ssoCallbackUrl(config, "google")
|
return ssoCallbackUrl(config, "google")
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.oidcCallbackUrl = async config => {
|
export const oidcCallbackUrl = async (config: any) => {
|
||||||
return ssoCallbackUrl(config, "oidc")
|
return ssoCallbackUrl(config, "oidc")
|
||||||
}
|
}
|
||||||
|
|
||||||
async function authInternal(ctx, user, err = null, info = null) {
|
async function authInternal(ctx: any, user: any, err = null, info = null) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Authentication error", err)
|
console.error("Authentication error", err)
|
||||||
return ctx.throw(403, info ? info : "Unauthorized")
|
return ctx.throw(403, info ? info : "Unauthorized")
|
||||||
|
@ -71,27 +72,30 @@ async function authInternal(ctx, user, err = null, info = null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.authenticate = async (ctx, next) => {
|
export const authenticate = async (ctx: any, next: any) => {
|
||||||
return passport.authenticate("local", async (err, user, info) => {
|
return passport.authenticate(
|
||||||
|
"local",
|
||||||
|
async (err: any, user: any, info: any) => {
|
||||||
await authInternal(ctx, user, err, info)
|
await authInternal(ctx, user, err, info)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
})(ctx, next)
|
}
|
||||||
|
)(ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.setInitInfo = ctx => {
|
export const setInitInfo = (ctx: any) => {
|
||||||
const initInfo = ctx.request.body
|
const initInfo = ctx.request.body
|
||||||
setCookie(ctx, initInfo, Cookies.Init)
|
setCookie(ctx, initInfo, Cookies.Init)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getInitInfo = ctx => {
|
export const getInitInfo = (ctx: any) => {
|
||||||
ctx.body = getCookie(ctx, Cookies.Init) || {}
|
ctx.body = getCookie(ctx, Cookies.Init) || {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the user password, used as part of a forgotten password flow.
|
* Reset the user password, used as part of a forgotten password flow.
|
||||||
*/
|
*/
|
||||||
exports.reset = async ctx => {
|
export const reset = async (ctx: any) => {
|
||||||
const { email } = ctx.request.body
|
const { email } = ctx.request.body
|
||||||
const configured = await isEmailConfigured()
|
const configured = await isEmailConfigured()
|
||||||
if (!configured) {
|
if (!configured) {
|
||||||
|
@ -121,7 +125,7 @@ exports.reset = async ctx => {
|
||||||
/**
|
/**
|
||||||
* Perform the user password update if the provided reset code is valid.
|
* Perform the user password update if the provided reset code is valid.
|
||||||
*/
|
*/
|
||||||
exports.resetUpdate = async ctx => {
|
export const resetUpdate = async (ctx: any) => {
|
||||||
const { resetCode, password } = ctx.request.body
|
const { resetCode, password } = ctx.request.body
|
||||||
try {
|
try {
|
||||||
const { userId } = await checkResetPasswordCode(resetCode)
|
const { userId } = await checkResetPasswordCode(resetCode)
|
||||||
|
@ -137,14 +141,14 @@ exports.resetUpdate = async ctx => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.logout = async ctx => {
|
export const logout = async (ctx: any) => {
|
||||||
if (ctx.user && ctx.user._id) {
|
if (ctx.user && ctx.user._id) {
|
||||||
await platformLogout({ ctx, userId: ctx.user._id })
|
await platformLogout({ ctx, userId: ctx.user._id })
|
||||||
}
|
}
|
||||||
ctx.body = { message: "User logged out." }
|
ctx.body = { message: "User logged out." }
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.datasourcePreAuth = async (ctx, next) => {
|
export const datasourcePreAuth = async (ctx: any, next: any) => {
|
||||||
const provider = ctx.params.provider
|
const provider = ctx.params.provider
|
||||||
const middleware = require(`@budibase/backend-core/middleware`)
|
const middleware = require(`@budibase/backend-core/middleware`)
|
||||||
const handler = middleware.datasource[provider]
|
const handler = middleware.datasource[provider]
|
||||||
|
@ -162,7 +166,7 @@ exports.datasourcePreAuth = async (ctx, next) => {
|
||||||
return handler.preAuth(passport, ctx, next)
|
return handler.preAuth(passport, ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.datasourceAuth = async (ctx, next) => {
|
export const datasourceAuth = async (ctx: any, next: any) => {
|
||||||
const authStateCookie = getCookie(ctx, Cookies.DatasourceAuth)
|
const authStateCookie = getCookie(ctx, Cookies.DatasourceAuth)
|
||||||
const provider = authStateCookie.provider
|
const provider = authStateCookie.provider
|
||||||
const middleware = require(`@budibase/backend-core/middleware`)
|
const middleware = require(`@budibase/backend-core/middleware`)
|
||||||
|
@ -174,7 +178,7 @@ exports.datasourceAuth = async (ctx, next) => {
|
||||||
* The initial call that google authentication makes to take you to the google login screen.
|
* 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.
|
* On a successful login, you will be redirected to the googleAuth callback route.
|
||||||
*/
|
*/
|
||||||
exports.googlePreAuth = async (ctx, next) => {
|
export const googlePreAuth = async (ctx: any, next: any) => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
|
@ -182,14 +186,14 @@ exports.googlePreAuth = async (ctx, next) => {
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
let callbackUrl = await exports.googleCallbackUrl(config)
|
let callbackUrl = await exports.googleCallbackUrl(config)
|
||||||
const strategy = await google.strategyFactory(config, callbackUrl)
|
const strategy = await google.strategyFactory(config, callbackUrl, users.save)
|
||||||
|
|
||||||
return passport.authenticate(strategy, {
|
return passport.authenticate(strategy, {
|
||||||
scope: ["profile", "email"],
|
scope: ["profile", "email"],
|
||||||
})(ctx, next)
|
})(ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.googleAuth = async (ctx, next) => {
|
export const googleAuth = async (ctx: any, next: any) => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
|
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
|
@ -197,12 +201,12 @@ exports.googleAuth = async (ctx, next) => {
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
const callbackUrl = await exports.googleCallbackUrl(config)
|
const callbackUrl = await exports.googleCallbackUrl(config)
|
||||||
const strategy = await google.strategyFactory(config, callbackUrl)
|
const strategy = await google.strategyFactory(config, callbackUrl, users.save)
|
||||||
|
|
||||||
return passport.authenticate(
|
return passport.authenticate(
|
||||||
strategy,
|
strategy,
|
||||||
{ successRedirect: "/", failureRedirect: "/error" },
|
{ successRedirect: "/", failureRedirect: "/error" },
|
||||||
async (err, user, info) => {
|
async (err: any, user: any, info: any) => {
|
||||||
await authInternal(ctx, user, err, info)
|
await authInternal(ctx, user, err, info)
|
||||||
|
|
||||||
ctx.redirect("/")
|
ctx.redirect("/")
|
||||||
|
@ -210,14 +214,14 @@ exports.googleAuth = async (ctx, next) => {
|
||||||
)(ctx, next)
|
)(ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function oidcStrategyFactory(ctx, configId) {
|
async function oidcStrategyFactory(ctx: any, configId: any) {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
const config = await core.db.getScopedConfig(db, {
|
const config = await core.db.getScopedConfig(db, {
|
||||||
type: Configs.OIDC,
|
type: Configs.OIDC,
|
||||||
group: ctx.query.group,
|
group: ctx.query.group,
|
||||||
})
|
})
|
||||||
|
|
||||||
const chosenConfig = config.configs.filter(c => c.uuid === configId)[0]
|
const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0]
|
||||||
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
|
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
|
||||||
|
|
||||||
return oidc.strategyFactory(chosenConfig, callbackUrl)
|
return oidc.strategyFactory(chosenConfig, callbackUrl)
|
||||||
|
@ -227,7 +231,7 @@ async function oidcStrategyFactory(ctx, configId) {
|
||||||
* The initial call that OIDC authentication makes to take you to the configured OIDC login screen.
|
* The initial call that OIDC authentication makes to take you to the configured OIDC login screen.
|
||||||
* On a successful login, you will be redirected to the oidcAuth callback route.
|
* On a successful login, you will be redirected to the oidcAuth callback route.
|
||||||
*/
|
*/
|
||||||
exports.oidcPreAuth = async (ctx, next) => {
|
export const oidcPreAuth = async (ctx: any, next: any) => {
|
||||||
const { configId } = ctx.params
|
const { configId } = ctx.params
|
||||||
const strategy = await oidcStrategyFactory(ctx, configId)
|
const strategy = await oidcStrategyFactory(ctx, configId)
|
||||||
|
|
||||||
|
@ -239,14 +243,14 @@ exports.oidcPreAuth = async (ctx, next) => {
|
||||||
})(ctx, next)
|
})(ctx, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.oidcAuth = async (ctx, next) => {
|
export const oidcAuth = async (ctx: any, next: any) => {
|
||||||
const configId = getCookie(ctx, Cookies.OIDC_CONFIG)
|
const configId = getCookie(ctx, Cookies.OIDC_CONFIG)
|
||||||
const strategy = await oidcStrategyFactory(ctx, configId)
|
const strategy = await oidcStrategyFactory(ctx, configId)
|
||||||
|
|
||||||
return passport.authenticate(
|
return passport.authenticate(
|
||||||
strategy,
|
strategy,
|
||||||
{ successRedirect: "/", failureRedirect: "/error" },
|
{ successRedirect: "/", failureRedirect: "/error" },
|
||||||
async (err, user, info) => {
|
async (err: any, user: any, info: any) => {
|
||||||
await authInternal(ctx, user, err, info)
|
await authInternal(ctx, user, err, info)
|
||||||
|
|
||||||
ctx.redirect("/")
|
ctx.redirect("/")
|
|
@ -1,4 +1,4 @@
|
||||||
import * as Pro from "@budibase/pro"
|
import { licensing, quotas } from "@budibase/pro"
|
||||||
|
|
||||||
export const activate = async (ctx: any) => {
|
export const activate = async (ctx: any) => {
|
||||||
const { licenseKey } = ctx.request.body
|
const { licenseKey } = ctx.request.body
|
||||||
|
@ -6,17 +6,17 @@ export const activate = async (ctx: any) => {
|
||||||
ctx.throw(400, "licenseKey is required")
|
ctx.throw(400, "licenseKey is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
await Pro.Licensing.activateLicenseKey(licenseKey)
|
await licensing.activateLicenseKey(licenseKey)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export const refresh = async (ctx: any) => {
|
export const refresh = async (ctx: any) => {
|
||||||
await Pro.Licensing.Cache.refresh()
|
await licensing.cache.refresh()
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getInfo = async (ctx: any) => {
|
export const getInfo = async (ctx: any) => {
|
||||||
const licenseInfo = await Pro.Licensing.getLicenseInfo()
|
const licenseInfo = await licensing.getLicenseInfo()
|
||||||
if (licenseInfo) {
|
if (licenseInfo) {
|
||||||
licenseInfo.licenseKey = "*"
|
licenseInfo.licenseKey = "*"
|
||||||
ctx.body = licenseInfo
|
ctx.body = licenseInfo
|
||||||
|
@ -25,6 +25,6 @@ export const getInfo = async (ctx: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getQuotaUsage = async (ctx: any) => {
|
export const getQuotaUsage = async (ctx: any) => {
|
||||||
const usage = await Pro.Licensing.Quotas.getQuotaUsage()
|
const usage = await quotas.getQuotaUsage()
|
||||||
ctx.body = usage
|
ctx.body = usage
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ const {
|
||||||
const {
|
const {
|
||||||
hash,
|
hash,
|
||||||
getGlobalUserByEmail,
|
getGlobalUserByEmail,
|
||||||
saveUser,
|
|
||||||
platformLogout,
|
platformLogout,
|
||||||
} = require("@budibase/backend-core/utils")
|
} = require("@budibase/backend-core/utils")
|
||||||
import { EmailTemplatePurpose } from "../../../constants"
|
import { EmailTemplatePurpose } from "../../../constants"
|
||||||
|
@ -23,8 +22,8 @@ const {
|
||||||
const { removeUserFromInfoDB } = require("@budibase/backend-core/deprovision")
|
const { removeUserFromInfoDB } = require("@budibase/backend-core/deprovision")
|
||||||
import env from "../../../environment"
|
import env from "../../../environment"
|
||||||
import { syncUserInApps } from "../../../utilities/appService"
|
import { syncUserInApps } from "../../../utilities/appService"
|
||||||
|
import { quotas, users } from "@budibase/pro"
|
||||||
const { errors } = require("@budibase/backend-core")
|
const { errors } = require("@budibase/backend-core")
|
||||||
import * as Pro from "@budibase/pro"
|
|
||||||
|
|
||||||
const allUsers = async () => {
|
const allUsers = async () => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
|
@ -38,7 +37,7 @@ const allUsers = async () => {
|
||||||
|
|
||||||
export const save = async (ctx: any) => {
|
export const save = async (ctx: any) => {
|
||||||
try {
|
try {
|
||||||
const user = await saveUser(ctx.request.body, getTenantId())
|
const user = await users.save(ctx.request.body, getTenantId())
|
||||||
// let server know to sync user
|
// let server know to sync user
|
||||||
await syncUserInApps(user._id)
|
await syncUserInApps(user._id)
|
||||||
ctx.body = user
|
ctx.body = user
|
||||||
|
@ -81,7 +80,7 @@ export const adminUser = async (ctx: any) => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// don't worry about errors
|
// don't worry about errors
|
||||||
}
|
}
|
||||||
await db.put(Pro.Licensing.Quotas.generateNewQuotaUsage())
|
await db.put(quotas.generateNewQuotaUsage())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.rows.some((row: any) => row.doc.admin)) {
|
if (response.rows.some((row: any) => row.doc.admin)) {
|
||||||
|
@ -105,7 +104,7 @@ export const adminUser = async (ctx: any) => {
|
||||||
tenantId,
|
tenantId,
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ctx.body = await saveUser(user, tenantId, hashPassword, requirePassword)
|
ctx.body = await users.save(user, tenantId, hashPassword, requirePassword)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
ctx.throw(err.status || 400, err)
|
ctx.throw(err.status || 400, err)
|
||||||
}
|
}
|
||||||
|
@ -286,7 +285,7 @@ export const inviteAccept = async (ctx: any) => {
|
||||||
try {
|
try {
|
||||||
// info is an extension of the user object that was stored by global
|
// info is an extension of the user object that was stored by global
|
||||||
const { email, info }: any = await checkInviteCode(inviteCode)
|
const { email, info }: any = await checkInviteCode(inviteCode)
|
||||||
ctx.body = await saveUser(
|
ctx.body = await users.save(
|
||||||
{
|
{
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
|
|
|
@ -8,7 +8,7 @@ const {
|
||||||
buildTenancyMiddleware,
|
buildTenancyMiddleware,
|
||||||
buildCsrfMiddleware,
|
buildCsrfMiddleware,
|
||||||
} = require("@budibase/backend-core/auth")
|
} = require("@budibase/backend-core/auth")
|
||||||
const Pro = require("@budibase/pro")
|
const { middleware: pro } = require("@budibase/pro")
|
||||||
const { errors } = require("@budibase/backend-core")
|
const { errors } = require("@budibase/backend-core")
|
||||||
|
|
||||||
const PUBLIC_ENDPOINTS = [
|
const PUBLIC_ENDPOINTS = [
|
||||||
|
@ -93,7 +93,7 @@ router
|
||||||
.use(buildAuthMiddleware(PUBLIC_ENDPOINTS))
|
.use(buildAuthMiddleware(PUBLIC_ENDPOINTS))
|
||||||
.use(buildTenancyMiddleware(PUBLIC_ENDPOINTS, NO_TENANCY_ENDPOINTS))
|
.use(buildTenancyMiddleware(PUBLIC_ENDPOINTS, NO_TENANCY_ENDPOINTS))
|
||||||
.use(buildCsrfMiddleware({ noCsrfPatterns: NO_CSRF_ENDPOINTS }))
|
.use(buildCsrfMiddleware({ noCsrfPatterns: NO_CSRF_ENDPOINTS }))
|
||||||
.use(Pro.Middleware.Licensing())
|
.use(pro.licensing())
|
||||||
// for now no public access is allowed to worker (bar health check)
|
// for now no public access is allowed to worker (bar health check)
|
||||||
.use((ctx, next) => {
|
.use((ctx, next) => {
|
||||||
if (ctx.publicEndpoint) {
|
if (ctx.publicEndpoint) {
|
||||||
|
|
Loading…
Reference in New Issue