forked from tsai/budibase
49 changed files with 470 additions and 179 deletions
@ -0,0 +1,14 @@ |
|||||
|
const env = require("../environment") |
||||
|
const { Headers } = require("../constants") |
||||
|
|
||||
|
/** |
||||
|
* API Key only endpoint. |
||||
|
*/ |
||||
|
module.exports = async (ctx, next) => { |
||||
|
const apiKey = ctx.request.headers[Headers.API_KEY] |
||||
|
if (apiKey !== env.INTERNAL_API_KEY) { |
||||
|
ctx.throw(403, "Unauthorized") |
||||
|
} |
||||
|
|
||||
|
return next() |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
const { migrate, MIGRATIONS } = require("../../migrations") |
||||
|
|
||||
|
exports.migrate = async ctx => { |
||||
|
const options = ctx.request.body |
||||
|
// don't await as can take a while, just return
|
||||
|
migrate(options) |
||||
|
ctx.status = 200 |
||||
|
} |
||||
|
|
||||
|
exports.fetchDefinitions = async ctx => { |
||||
|
ctx.body = MIGRATIONS |
||||
|
ctx.status = 200 |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
const Router = require("@koa/router") |
||||
|
const migrationsController = require("../controllers/migrations") |
||||
|
const router = Router() |
||||
|
const { internalApi } = require("@budibase/backend-core/auth") |
||||
|
|
||||
|
router |
||||
|
.post("/api/migrations/run", internalApi, migrationsController.migrate) |
||||
|
.get( |
||||
|
"/api/migrations/definitions", |
||||
|
internalApi, |
||||
|
migrationsController.fetchDefinitions |
||||
|
) |
||||
|
|
||||
|
module.exports = router |
||||
@ -0,0 +1,25 @@ |
|||||
|
const { DocumentTypes } = require("@budibase/backend-core/db") |
||||
|
import { getAppUrl } from "../../api/controllers/application" |
||||
|
|
||||
|
/** |
||||
|
* Date: |
||||
|
* January 2022 |
||||
|
* |
||||
|
* Description: |
||||
|
* Add the url to the app metadata if it doesn't exist |
||||
|
*/ |
||||
|
export const run = async (appDb: any) => { |
||||
|
const metadata = await appDb.get(DocumentTypes.APP_METADATA) |
||||
|
if (!metadata.url) { |
||||
|
const context = { |
||||
|
request: { |
||||
|
body: { |
||||
|
name: metadata.name, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
metadata.url = getAppUrl(context) |
||||
|
console.log(`Adding url to app: ${metadata.url}`) |
||||
|
} |
||||
|
await appDb.put(metadata) |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
import { runQuotaMigration } from "./usageQuotas" |
||||
|
import * as syncApps from "./usageQuotas/syncApps" |
||||
|
import * as syncRows from "./usageQuotas/syncRows" |
||||
|
|
||||
|
/** |
||||
|
* Date: |
||||
|
* January 2022 |
||||
|
* |
||||
|
* Description: |
||||
|
* Synchronise the app and row quotas to the state of the db after it was |
||||
|
* discovered that the quota resets were still in place and the row quotas |
||||
|
* weren't being decremented correctly. |
||||
|
*/ |
||||
|
|
||||
|
export const run = async () => { |
||||
|
await runQuotaMigration(async () => { |
||||
|
await syncApps.run() |
||||
|
await syncRows.run() |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
const { DocumentTypes } = require("@budibase/backend-core/db") |
||||
|
const env = require("../../../environment") |
||||
|
const TestConfig = require("../../../tests/utilities/TestConfiguration") |
||||
|
|
||||
|
const migration = require("../appUrls") |
||||
|
|
||||
|
describe("run", () => { |
||||
|
let config = new TestConfig(false) |
||||
|
const CouchDB = config.getCouch() |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await config.init() |
||||
|
}) |
||||
|
|
||||
|
afterAll(config.end) |
||||
|
|
||||
|
it("runs successfully", async () => { |
||||
|
const app = await config.createApp("testApp") |
||||
|
const appDb = new CouchDB(app.appId) |
||||
|
let metadata = await appDb.get(DocumentTypes.APP_METADATA) |
||||
|
delete metadata.url |
||||
|
await appDb.put(metadata) |
||||
|
|
||||
|
await migration.run(appDb) |
||||
|
|
||||
|
metadata = await appDb.get(DocumentTypes.APP_METADATA) |
||||
|
expect(metadata.url).toEqual("/testapp") |
||||
|
}) |
||||
|
}) |
||||
@ -0,0 +1,25 @@ |
|||||
|
const TestConfig = require("../../../tests/utilities/TestConfiguration") |
||||
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy") |
||||
|
|
||||
|
// mock email view creation
|
||||
|
const coreDb = require("@budibase/backend-core/db") |
||||
|
const createUserEmailView = jest.fn() |
||||
|
coreDb.createUserEmailView = createUserEmailView |
||||
|
|
||||
|
const migration = require("../userEmailViewCasing") |
||||
|
|
||||
|
describe("run", () => { |
||||
|
let config = new TestConfig(false) |
||||
|
const globalDb = getGlobalDB() |
||||
|
|
||||
|
beforeEach(async () => { |
||||
|
await config.init() |
||||
|
}) |
||||
|
|
||||
|
afterAll(config.end) |
||||
|
|
||||
|
it("runs successfully", async () => { |
||||
|
await migration.run(globalDb) |
||||
|
expect(createUserEmailView).toHaveBeenCalledTimes(1) |
||||
|
}) |
||||
|
}) |
||||
@ -0,0 +1,8 @@ |
|||||
|
const { useQuotas } = require("../../../utilities/usageQuota") |
||||
|
|
||||
|
export const runQuotaMigration = async (migration: Function) => { |
||||
|
if (!useQuotas()) { |
||||
|
return |
||||
|
} |
||||
|
await migration() |
||||
|
} |
||||
@ -1,8 +1,10 @@ |
|||||
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy") |
// @ts-ignore
|
||||
const { getAllApps } = require("@budibase/backend-core/db") |
import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy" |
||||
const { getUsageQuotaDoc } = require("../../utilities/usageQuota") |
// @ts-ignore
|
||||
|
import { getAllApps } from "@budibase/backend-core/db" |
||||
|
import { getUsageQuotaDoc } from "../../../utilities/usageQuota" |
||||
|
|
||||
exports.run = async () => { |
export const run = async () => { |
||||
const db = getGlobalDB() |
const db = getGlobalDB() |
||||
// get app count
|
// get app count
|
||||
const devApps = await getAllApps({ dev: true }) |
const devApps = await getAllApps({ dev: true }) |
||||
@ -1,13 +1,15 @@ |
|||||
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy") |
// @ts-ignore
|
||||
const { getAllApps } = require("@budibase/backend-core/db") |
import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy" |
||||
const { getUsageQuotaDoc } = require("../../utilities/usageQuota") |
// @ts-ignore
|
||||
const { getUniqueRows } = require("../../utilities/usageQuota/rows") |
import { getAllApps } from "@budibase/backend-core/db" |
||||
|
import { getUsageQuotaDoc } from "../../../utilities/usageQuota" |
||||
|
import { getUniqueRows } from "../../../utilities/usageQuota/rows" |
||||
|
|
||||
exports.run = async () => { |
export const run = async () => { |
||||
const db = getGlobalDB() |
const db = getGlobalDB() |
||||
// get all rows in all apps
|
// get all rows in all apps
|
||||
const allApps = await getAllApps({ all: true }) |
const allApps = await getAllApps({ all: true }) |
||||
const appIds = allApps ? allApps.map(app => app.appId) : [] |
const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : [] |
||||
const rows = await getUniqueRows(appIds) |
const rows = await getUniqueRows(appIds) |
||||
const rowCount = rows ? rows.length : 0 |
const rowCount = rows ? rows.length : 0 |
||||
|
|
||||
@ -1,8 +1,8 @@ |
|||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy") |
const { getGlobalDB } = require("@budibase/backend-core/tenancy") |
||||
const TestConfig = require("../../../tests/utilities/TestConfiguration") |
const TestConfig = require("../../../../tests/utilities/TestConfiguration") |
||||
const { getUsageQuotaDoc, update, Properties } = require("../../../utilities/usageQuota") |
const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota") |
||||
const syncApps = require("../../usageQuotas/syncApps") |
const syncApps = require("../syncApps") |
||||
const env = require("../../../environment") |
const env = require("../../../../environment") |
||||
|
|
||||
describe("syncApps", () => { |
describe("syncApps", () => { |
||||
let config = new TestConfig(false) |
let config = new TestConfig(false) |
||||
@ -1,8 +1,8 @@ |
|||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy") |
const { getGlobalDB } = require("@budibase/backend-core/tenancy") |
||||
const TestConfig = require("../../../tests/utilities/TestConfiguration") |
const TestConfig = require("../../../../tests/utilities/TestConfiguration") |
||||
const { getUsageQuotaDoc, update, Properties } = require("../../../utilities/usageQuota") |
const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota") |
||||
const syncRows = require("../../usageQuotas/syncRows") |
const syncRows = require("../syncRows") |
||||
const env = require("../../../environment") |
const env = require("../../../../environment") |
||||
|
|
||||
describe("syncRows", () => { |
describe("syncRows", () => { |
||||
let config = new TestConfig(false) |
let config = new TestConfig(false) |
||||
@ -0,0 +1,13 @@ |
|||||
|
const { createUserEmailView } = require("@budibase/backend-core/db") |
||||
|
|
||||
|
/** |
||||
|
* Date: |
||||
|
* October 2021 |
||||
|
* |
||||
|
* Description: |
||||
|
* Recreate the user email view to include latest changes i.e. lower casing the email address |
||||
|
*/ |
||||
|
|
||||
|
export const run = async (db: any) => { |
||||
|
await createUserEmailView(db) |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
import CouchDB from "../db" |
||||
|
const { |
||||
|
MIGRATION_TYPES, |
||||
|
runMigrations, |
||||
|
} = require("@budibase/backend-core/migrations") |
||||
|
|
||||
|
// migration functions
|
||||
|
import * as userEmailViewCasing from "./functions/userEmailViewCasing" |
||||
|
import * as quota1 from "./functions/quotas1" |
||||
|
import * as appUrls from "./functions/appUrls" |
||||
|
|
||||
|
export interface Migration { |
||||
|
type: string |
||||
|
name: string |
||||
|
opts?: object |
||||
|
fn: Function |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* e.g. |
||||
|
* { |
||||
|
* tenantIds: ['bb'], |
||||
|
* force: { |
||||
|
* global: ['quota_1'] |
||||
|
* } |
||||
|
* } |
||||
|
*/ |
||||
|
export interface MigrationOptions { |
||||
|
tenantIds?: string[] |
||||
|
forced?: { |
||||
|
[type: string]: string[] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export const MIGRATIONS: Migration[] = [ |
||||
|
{ |
||||
|
type: MIGRATION_TYPES.GLOBAL, |
||||
|
name: "user_email_view_casing", |
||||
|
fn: userEmailViewCasing.run, |
||||
|
}, |
||||
|
{ |
||||
|
type: MIGRATION_TYPES.GLOBAL, |
||||
|
name: "quotas_1", |
||||
|
fn: quota1.run, |
||||
|
}, |
||||
|
{ |
||||
|
type: MIGRATION_TYPES.APP, |
||||
|
name: "app_urls", |
||||
|
opts: { all: true }, |
||||
|
fn: appUrls.run, |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
export const migrate = async (options?: MigrationOptions) => { |
||||
|
await runMigrations(CouchDB, MIGRATIONS, options) |
||||
|
} |
||||
@ -1,24 +0,0 @@ |
|||||
const { |
|
||||
MIGRATIONS, |
|
||||
MIGRATION_DBS, |
|
||||
migrateIfRequired, |
|
||||
} = require("@budibase/backend-core/migrations") |
|
||||
const { useQuotas } = require("../../utilities/usageQuota") |
|
||||
const syncApps = require("./syncApps") |
|
||||
const syncRows = require("./syncRows") |
|
||||
|
|
||||
exports.run = async () => { |
|
||||
if (!useQuotas()) { |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// Jan 2022
|
|
||||
await migrateIfRequired( |
|
||||
MIGRATION_DBS.GLOBAL_DB, |
|
||||
MIGRATIONS.QUOTAS_1, |
|
||||
async () => { |
|
||||
await syncApps.run() |
|
||||
await syncRows.run() |
|
||||
} |
|
||||
) |
|
||||
} |
|
||||
Loading…
Reference in new issue