Sync global-info users to fix login + prevent double password hashing
This commit is contained in:
parent
cf8c3629df
commit
3b3f3188ab
|
@ -37,4 +37,8 @@ export const DEFINITIONS: MigrationDefinition[] = [
|
||||||
type: MigrationType.INSTALLATION,
|
type: MigrationType.INSTALLATION,
|
||||||
name: MigrationName.EVENT_INSTALLATION_BACKFILL,
|
name: MigrationName.EVENT_INSTALLATION_BACKFILL,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: MigrationType.GLOBAL,
|
||||||
|
name: MigrationName.GLOBAL_INFO_SYNC_USERS,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -46,6 +46,7 @@ export enum MigrationName {
|
||||||
EVENT_APP_BACKFILL = "event_app_backfill",
|
EVENT_APP_BACKFILL = "event_app_backfill",
|
||||||
EVENT_GLOBAL_BACKFILL = "event_global_backfill",
|
EVENT_GLOBAL_BACKFILL = "event_global_backfill",
|
||||||
EVENT_INSTALLATION_BACKFILL = "event_installation_backfill",
|
EVENT_INSTALLATION_BACKFILL = "event_installation_backfill",
|
||||||
|
GLOBAL_INFO_SYNC_USERS = "global_info_sync_users",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MigrationDefinition {
|
export interface MigrationDefinition {
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
const { migrate, MIGRATIONS } = require("../../../migrations")
|
||||||
|
|
||||||
|
export const runMigrations = async (ctx: any) => {
|
||||||
|
const options = ctx.request.body
|
||||||
|
// don't await as can take a while, just return
|
||||||
|
migrate(options)
|
||||||
|
ctx.status = 200
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchDefinitions = async (ctx: any) => {
|
||||||
|
ctx.body = MIGRATIONS
|
||||||
|
ctx.status = 200
|
||||||
|
}
|
|
@ -106,7 +106,10 @@ router
|
||||||
if (ctx.publicEndpoint) {
|
if (ctx.publicEndpoint) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
if ((!ctx.isAuthenticated || !ctx.user.budibaseAccess) && !ctx.internal) {
|
if (
|
||||||
|
(!ctx.isAuthenticated || (ctx.user && !ctx.user.budibaseAccess)) &&
|
||||||
|
!ctx.internal
|
||||||
|
) {
|
||||||
ctx.throw(403, "Unauthorized - no public worker access")
|
ctx.throw(403, "Unauthorized - no public worker access")
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -12,6 +12,7 @@ const tenantsRoutes = require("./system/tenants")
|
||||||
const statusRoutes = require("./system/status")
|
const statusRoutes = require("./system/status")
|
||||||
const selfRoutes = require("./global/self")
|
const selfRoutes = require("./global/self")
|
||||||
const licenseRoutes = require("./global/license")
|
const licenseRoutes = require("./global/license")
|
||||||
|
const migrationRoutes = require("./system/migrations")
|
||||||
|
|
||||||
let userGroupRoutes = api.groups
|
let userGroupRoutes = api.groups
|
||||||
exports.routes = [
|
exports.routes = [
|
||||||
|
@ -29,4 +30,5 @@ exports.routes = [
|
||||||
selfRoutes,
|
selfRoutes,
|
||||||
licenseRoutes,
|
licenseRoutes,
|
||||||
userGroupRoutes,
|
userGroupRoutes,
|
||||||
|
migrationRoutes,
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import Router from "@koa/router"
|
||||||
|
import * as migrationsController from "../../controllers/system/migrations"
|
||||||
|
import { auth } from "@budibase/backend-core"
|
||||||
|
|
||||||
|
const router = new Router()
|
||||||
|
|
||||||
|
router
|
||||||
|
.post(
|
||||||
|
"/api/system/migrations/run",
|
||||||
|
auth.internalApi,
|
||||||
|
migrationsController.runMigrations
|
||||||
|
)
|
||||||
|
.get(
|
||||||
|
"/api/system/migrations/definitions",
|
||||||
|
auth.internalApi,
|
||||||
|
migrationsController.fetchDefinitions
|
||||||
|
)
|
||||||
|
|
||||||
|
export = router
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { User } from "@budibase/types"
|
||||||
|
import * as sdk from "../../sdk"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date:
|
||||||
|
* Aug 2022
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Re-sync the global-db users to the global-info db users
|
||||||
|
*/
|
||||||
|
export const run = async (globalDb: any) => {
|
||||||
|
const users = (await sdk.users.allUsers()) as User[]
|
||||||
|
const promises = []
|
||||||
|
for (let user of users) {
|
||||||
|
promises.push(
|
||||||
|
sdk.users.addTenant(user.tenantId, user._id as string, user.email)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
await Promise.all(promises)
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { migrations, redis } from "@budibase/backend-core"
|
||||||
|
import { Migration, MigrationOptions, MigrationName } from "@budibase/types"
|
||||||
|
import env from "../environment"
|
||||||
|
|
||||||
|
// migration functions
|
||||||
|
import * as syncUserInfo from "./functions/globalInfoSyncUsers"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the migration function and additional configuration from
|
||||||
|
* the static migration definitions.
|
||||||
|
*/
|
||||||
|
export const buildMigrations = () => {
|
||||||
|
const definitions = migrations.DEFINITIONS
|
||||||
|
const workerMigrations: Migration[] = []
|
||||||
|
|
||||||
|
for (const definition of definitions) {
|
||||||
|
switch (definition.name) {
|
||||||
|
case MigrationName.GLOBAL_INFO_SYNC_USERS: {
|
||||||
|
// only needed in cloud
|
||||||
|
if (!env.SELF_HOSTED) {
|
||||||
|
workerMigrations.push({
|
||||||
|
...definition,
|
||||||
|
fn: syncUserInfo.run,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return workerMigrations
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MIGRATIONS = buildMigrations()
|
||||||
|
|
||||||
|
export const migrate = async (options?: MigrationOptions) => {
|
||||||
|
if (env.SELF_HOSTED) {
|
||||||
|
await migrateWithLock(options)
|
||||||
|
} else {
|
||||||
|
await migrations.runMigrations(MIGRATIONS, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const migrateWithLock = async (options?: MigrationOptions) => {
|
||||||
|
// get a new lock client
|
||||||
|
const redlock = await redis.clients.getMigrationsRedlock()
|
||||||
|
// lock for 15 minutes
|
||||||
|
const ttl = 1000 * 60 * 15
|
||||||
|
|
||||||
|
let migrationLock
|
||||||
|
|
||||||
|
// acquire lock
|
||||||
|
try {
|
||||||
|
migrationLock = await redlock.lock("migrations", ttl)
|
||||||
|
} catch (e: any) {
|
||||||
|
if (e.name === "LockError") {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// run migrations
|
||||||
|
try {
|
||||||
|
await migrations.runMigrations(MIGRATIONS, options)
|
||||||
|
} finally {
|
||||||
|
// release lock
|
||||||
|
try {
|
||||||
|
await migrationLock.unlock()
|
||||||
|
} catch (e) {
|
||||||
|
console.error("unable to release migration lock")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -106,7 +106,6 @@ const buildUser = async (
|
||||||
opts: SaveUserOpts = {
|
opts: SaveUserOpts = {
|
||||||
hashPassword: true,
|
hashPassword: true,
|
||||||
requirePassword: true,
|
requirePassword: true,
|
||||||
bulkCreate: false,
|
|
||||||
},
|
},
|
||||||
tenantId: string,
|
tenantId: string,
|
||||||
dbUser?: any
|
dbUser?: any
|
||||||
|
@ -185,15 +184,7 @@ export const save = async (
|
||||||
dbUser = await db.get(_id)
|
dbUser = await db.get(_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
let builtUser = await buildUser(
|
let builtUser = await buildUser(user, opts, tenantId, dbUser)
|
||||||
user,
|
|
||||||
{
|
|
||||||
hashPassword: true,
|
|
||||||
requirePassword: user.requirePassword,
|
|
||||||
},
|
|
||||||
tenantId,
|
|
||||||
dbUser
|
|
||||||
)
|
|
||||||
|
|
||||||
// make sure we set the _id field for a new user
|
// make sure we set the _id field for a new user
|
||||||
if (!_id) {
|
if (!_id) {
|
||||||
|
@ -298,7 +289,6 @@ export const bulkCreate = async (
|
||||||
{
|
{
|
||||||
hashPassword: true,
|
hashPassword: true,
|
||||||
requirePassword: user.requirePassword,
|
requirePassword: user.requirePassword,
|
||||||
bulkCreate: false,
|
|
||||||
},
|
},
|
||||||
tenantId
|
tenantId
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue