diff --git a/lerna.json b/lerna.json index 055b5c3ce7..5e0bc09825 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "3.2.28", + "version": "3.2.29", "npmClient": "yarn", "concurrency": 20, "command": { diff --git a/packages/bbui/src/Layout/Page.svelte b/packages/bbui/src/Layout/Page.svelte index 62dd9cc909..e469927e60 100644 --- a/packages/bbui/src/Layout/Page.svelte +++ b/packages/bbui/src/Layout/Page.svelte @@ -43,12 +43,11 @@ flex-direction: row; justify-content: flex-start; align-items: stretch; - overflow-y: scroll !important; flex: 1 1 auto; overflow-x: hidden; } .main { - overflow: auto; + overflow-y: scroll; } .content { display: flex; diff --git a/packages/builder/src/global.css b/packages/builder/src/global.css index adf4a47070..a13d491416 100644 --- a/packages/builder/src/global.css +++ b/packages/builder/src/global.css @@ -61,7 +61,7 @@ a { height: 8px; } ::-webkit-scrollbar-track { - background: var(--spectrum-alias-background-color-default); + background: transparent; } ::-webkit-scrollbar-thumb { background-color: var(--spectrum-global-color-gray-400); @@ -71,6 +71,5 @@ a { background: var(--spectrum-alias-background-color-default); } html * { - scrollbar-color: var(--spectrum-global-color-gray-400) - var(--spectrum-alias-background-color-default); + scrollbar-color: var(--spectrum-global-color-gray-400) transparent; } diff --git a/packages/pro b/packages/pro index e7c9f08aeb..7fc699463b 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit e7c9f08aeb0498a20594f3c912afedcfdc220a6a +Subproject commit 7fc699463b3957eb050351b983edef0d25a531ae diff --git a/packages/server/src/api/controllers/analytics.ts b/packages/server/src/api/controllers/analytics.ts index 8c87af7251..27c981036a 100644 --- a/packages/server/src/api/controllers/analytics.ts +++ b/packages/server/src/api/controllers/analytics.ts @@ -1,10 +1,11 @@ -import { events, context } from "@budibase/backend-core" +import { context, events } from "@budibase/backend-core" import { - AnalyticsPingRequest, - App, - PingSource, - Ctx, AnalyticsEnabledResponse, + AnalyticsPingRequest, + AnalyticsPingResponse, + App, + Ctx, + PingSource, } from "@budibase/types" import { DocumentType, isDevAppID } from "../../db/utils" @@ -15,9 +16,12 @@ export const isEnabled = async (ctx: Ctx) => { } } -export const ping = async (ctx: Ctx) => { +export const ping = async ( + ctx: Ctx +) => { const body = ctx.request.body + let pingType: PingSource | undefined switch (body.source) { case PingSource.APP: { const db = context.getAppDB({ skip_setup: true }) @@ -29,13 +33,18 @@ export const ping = async (ctx: Ctx) => { } else { await events.serve.servedApp(appInfo, body.timezone, body.embedded) } + pingType = PingSource.APP break } case PingSource.BUILDER: { await events.serve.servedBuilder(body.timezone) + pingType = PingSource.BUILDER break } } - ctx.status = 200 + ctx.body = { + message: "pong", + source: pingType, + } } diff --git a/packages/server/src/api/controllers/application.ts b/packages/server/src/api/controllers/application.ts index d032f14150..4169087a63 100644 --- a/packages/server/src/api/controllers/application.ts +++ b/packages/server/src/api/controllers/application.ts @@ -68,6 +68,9 @@ import { ImportToUpdateAppRequest, ImportToUpdateAppResponse, SetRevertableAppVersionRequest, + AddAppSampleDataResponse, + UnpublishAppResponse, + SetRevertableAppVersionResponse, } from "@budibase/types" import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts" import sdk from "../../sdk" @@ -175,7 +178,9 @@ async function createInstance(appId: string, template: AppTemplate) { return { _id: appId } } -export const addSampleData = async (ctx: UserCtx) => { +export const addSampleData = async ( + ctx: UserCtx +) => { const db = context.getAppDB() try { @@ -188,7 +193,7 @@ export const addSampleData = async (ctx: UserCtx) => { await db.bulkDocs([...defaultDbDocs]) } - ctx.status = 200 + ctx.body = { message: "Sample tables added." } } export async function fetch(ctx: UserCtx) { @@ -528,7 +533,6 @@ export async function create( await appPostCreate(ctx, newApplication) await cache.bustCache(cache.CacheKey.CHECKLIST) ctx.body = newApplication - ctx.status = 200 } // This endpoint currently operates as a PATCH rather than a PUT @@ -551,7 +555,6 @@ export async function update( const app = await updateAppPackage(ctx.request.body, ctx.params.appId) await events.app.updated(app) - ctx.status = 200 ctx.body = app builderSocket?.emitAppMetadataUpdate(ctx, { theme: app.theme, @@ -592,7 +595,6 @@ export async function updateClient( } const app = await updateAppPackage(appPackageUpdates, ctx.params.appId) await events.app.versionUpdated(app, currentVersion, updatedToVersion) - ctx.status = 200 ctx.body = app } @@ -624,7 +626,6 @@ export async function revertClient( } const app = await updateAppPackage(appPackageUpdates, ctx.params.appId) await events.app.versionReverted(app, currentVersion, revertedToVersion) - ctx.status = 200 ctx.body = app } @@ -689,11 +690,10 @@ export async function destroy(ctx: UserCtx) { await preDestroyApp(ctx) const result = await destroyApp(ctx) await postDestroyApp(ctx) - ctx.status = 200 ctx.body = result } -export async function unpublish(ctx: UserCtx) { +export async function unpublish(ctx: UserCtx) { const prodAppId = dbCore.getProdAppID(ctx.params.appId) const dbExists = await dbCore.dbExists(prodAppId) @@ -705,8 +705,8 @@ export async function unpublish(ctx: UserCtx) { await preDestroyApp(ctx) await unpublishApp(ctx) await postDestroyApp(ctx) - ctx.status = 204 builderSocket?.emitAppUnpublish(ctx) + ctx.body = { message: "App unpublished." } } export async function sync(ctx: UserCtx) { @@ -802,7 +802,6 @@ export async function duplicateApp( duplicateAppId: newApplication?.appId, sourceAppId, } - ctx.status = 200 } export async function updateAppPackage( @@ -830,7 +829,7 @@ export async function updateAppPackage( } export async function setRevertableVersion( - ctx: UserCtx + ctx: UserCtx ) { if (!env.isDev()) { ctx.status = 403 @@ -840,8 +839,7 @@ export async function setRevertableVersion( const app = await sdk.applications.metadata.get() app.revertableVersion = ctx.request.body.revertableVersion await db.put(app) - - ctx.status = 200 + ctx.body = { message: "Revertable version updated." } } async function migrateAppNavigation() { diff --git a/packages/server/src/api/controllers/automation.ts b/packages/server/src/api/controllers/automation.ts index c843dca89b..abc0e492c0 100644 --- a/packages/server/src/api/controllers/automation.ts +++ b/packages/server/src/api/controllers/automation.ts @@ -62,7 +62,6 @@ export async function create( const createdAutomation = await sdk.automations.create(automation) - ctx.status = 200 ctx.body = { message: "Automation created successfully", automation: createdAutomation, @@ -84,7 +83,6 @@ export async function update( const updatedAutomation = await sdk.automations.update(automation) - ctx.status = 200 ctx.body = { message: `Automation ${automation._id} updated successfully.`, automation: updatedAutomation, diff --git a/packages/server/src/api/controllers/datasource.ts b/packages/server/src/api/controllers/datasource.ts index 7180f5f765..8a3d5cf2ca 100644 --- a/packages/server/src/api/controllers/datasource.ts +++ b/packages/server/src/api/controllers/datasource.ts @@ -182,7 +182,6 @@ export async function update( } } - ctx.status = 200 ctx.message = "Datasource saved successfully." ctx.body = { datasource: await sdk.datasources.removeSecretSingle(datasource), @@ -290,8 +289,7 @@ export async function destroy(ctx: UserCtx) { await db.remove(datasourceId, ctx.params.revId) await events.datasource.deleted(datasource) - ctx.message = `Datasource deleted.` - ctx.status = 200 + ctx.body = { message: `Datasource deleted.` } builderSocket?.emitDatasourceDeletion(ctx, datasourceId) } diff --git a/packages/server/src/api/controllers/layout.ts b/packages/server/src/api/controllers/layout.ts index a0eee000aa..4c996dde35 100644 --- a/packages/server/src/api/controllers/layout.ts +++ b/packages/server/src/api/controllers/layout.ts @@ -29,7 +29,6 @@ export async function save( layout._rev = response.rev ctx.body = layout - ctx.status = 200 } export async function destroy(ctx: UserCtx) { @@ -51,5 +50,4 @@ export async function destroy(ctx: UserCtx) { await db.remove(layoutId, layoutRev) await events.layout.deleted(layoutId) ctx.body = { message: "Layout deleted successfully" } - ctx.status = 200 } diff --git a/packages/server/src/api/controllers/migrations.ts b/packages/server/src/api/controllers/migrations.ts index a3ff0c5810..edf4ec6f51 100644 --- a/packages/server/src/api/controllers/migrations.ts +++ b/packages/server/src/api/controllers/migrations.ts @@ -4,6 +4,7 @@ import { Ctx, FetchOldMigrationResponse, GetOldMigrationStatus, + RuneOldMigrationResponse, RunOldMigrationRequest, } from "@budibase/types" import { @@ -11,18 +12,19 @@ import { getLatestEnabledMigrationId, } from "../../appMigrations" -export async function migrate(ctx: Ctx) { +export async function migrate( + ctx: Ctx +) { const options = ctx.request.body // don't await as can take a while, just return migrationImpl(options) - ctx.status = 200 + ctx.body = { message: "Migration started." } } export async function fetchDefinitions( ctx: Ctx ) { ctx.body = MIGRATIONS - ctx.status = 200 } export async function getMigrationStatus( @@ -41,5 +43,4 @@ export async function getMigrationStatus( !latestMigrationId || latestAppliedMigration >= latestMigrationId ctx.body = { migrated } - ctx.status = 200 } diff --git a/packages/server/src/api/controllers/permission.ts b/packages/server/src/api/controllers/permission.ts index e38c736c20..d1522ca292 100644 --- a/packages/server/src/api/controllers/permission.ts +++ b/packages/server/src/api/controllers/permission.ts @@ -99,7 +99,7 @@ export async function getDependantResources( export async function addPermission(ctx: UserCtx) { const params: AddPermissionRequest = ctx.params await sdk.permissions.updatePermissionOnRole(params, PermissionUpdateType.ADD) - ctx.status = 200 + ctx.body = { message: "Permission added." } } export async function removePermission( @@ -110,5 +110,5 @@ export async function removePermission( params, PermissionUpdateType.REMOVE ) - ctx.status = 200 + ctx.body = { message: "Permission removed." } } diff --git a/packages/server/src/api/controllers/query/index.ts b/packages/server/src/api/controllers/query/index.ts index d73bb8c024..7084d065fa 100644 --- a/packages/server/src/api/controllers/query/index.ts +++ b/packages/server/src/api/controllers/query/index.ts @@ -104,7 +104,6 @@ const _import = async ( ...importResult, datasourceId, } - ctx.status = 200 } export { _import as import } @@ -455,6 +454,5 @@ export async function destroy(ctx: UserCtx) { const datasource = await sdk.datasources.get(query.datasourceId) await db.remove(ctx.params.queryId, ctx.params.revId) ctx.body = { message: `Query deleted.` } - ctx.status = 200 await events.query.deleted(datasource, query) } diff --git a/packages/server/src/api/controllers/role.ts b/packages/server/src/api/controllers/role.ts index 30ca70b505..ae1d535a7c 100644 --- a/packages/server/src/api/controllers/role.ts +++ b/packages/server/src/api/controllers/role.ts @@ -234,8 +234,7 @@ export async function destroy(ctx: UserCtx) { // clean up inherits await removeRoleFromOthers(roleId) - ctx.message = `Role ${ctx.params.roleId} deleted successfully` - ctx.status = 200 + ctx.body = { message: `Role ${ctx.params.roleId} deleted successfully` } builderSocket?.emitRoleDeletion(ctx, role) } diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index 77c05abb95..8f4629a5b0 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -71,7 +71,6 @@ export async function patch( if (!row) { ctx.throw(404, "Row not found") } - ctx.status = 200 ctx.eventEmitter?.emitRow({ eventName: EventType.ROW_UPDATE, @@ -110,7 +109,6 @@ export const save = async (ctx: UserCtx) => { : await quotas.addRow(() => sdk.rows.save(sourceId, ctx.request.body, ctx.user?._id) ) - ctx.status = 200 ctx.eventEmitter?.emitRow({ eventName: EventType.ROW_SAVE, @@ -223,7 +221,6 @@ async function deleteRow(ctx: UserCtx) { export async function destroy(ctx: UserCtx) { let response, row - ctx.status = 200 if (isDeleteRows(ctx.request.body)) { response = await deleteRows(ctx) @@ -275,7 +272,6 @@ export async function search(ctx: Ctx) { rows: undefined, } - ctx.status = 200 ctx.body = await sdk.rows.search(searchParams) } diff --git a/packages/server/src/api/controllers/rowAction/run.ts b/packages/server/src/api/controllers/rowAction/run.ts index 05bdb7bace..069e38b86a 100644 --- a/packages/server/src/api/controllers/rowAction/run.ts +++ b/packages/server/src/api/controllers/rowAction/run.ts @@ -1,10 +1,16 @@ -import { RowActionTriggerRequest, Ctx } from "@budibase/types" +import { + RowActionTriggerRequest, + Ctx, + RowActionTriggerResponse, +} from "@budibase/types" import sdk from "../../../sdk" -export async function run(ctx: Ctx) { +export async function run( + ctx: Ctx +) { const { tableId, actionId } = ctx.params const { rowId } = ctx.request.body await sdk.rowActions.run(tableId, actionId, rowId, ctx.user) - ctx.status = 200 + ctx.body = { message: "Row action triggered." } } diff --git a/packages/server/src/api/controllers/screen.ts b/packages/server/src/api/controllers/screen.ts index cccc0c4d77..ad000871fe 100644 --- a/packages/server/src/api/controllers/screen.ts +++ b/packages/server/src/api/controllers/screen.ts @@ -123,7 +123,6 @@ export async function destroy(ctx: UserCtx) { ctx.body = { message: "Screen deleted successfully", } - ctx.status = 200 builderSocket?.emitScreenDeletion(ctx, id) } diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index 96599824c5..02134f0317 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -136,7 +136,6 @@ export async function save(ctx: UserCtx) { if (isImport) { await events.table.imported(savedTable) } - ctx.status = 200 ctx.message = `Table ${table.name} saved successfully.` ctx.eventEmitter?.emitTable(EventType.TABLE_SAVE, appId, { ...savedTable }) ctx.body = savedTable @@ -153,7 +152,6 @@ export async function destroy(ctx: UserCtx) { await events.table.deleted(deletedTable) ctx.eventEmitter?.emitTable(EventType.TABLE_DELETE, appId, deletedTable) - ctx.status = 200 ctx.table = deletedTable ctx.body = { message: `Table ${tableId} deleted.` } builderSocket?.emitTableDeletion(ctx, deletedTable) @@ -169,7 +167,6 @@ export async function bulkImport( // can only be done in the builder, but in the future we may need to // think about events for bulk items - ctx.status = 200 ctx.body = { message: `Bulk rows created.` } } @@ -180,7 +177,6 @@ export async function csvToJson( const result = await jsonFromCsvString(csvString) - ctx.status = 200 ctx.body = result } @@ -190,7 +186,6 @@ export async function validateNewTableImport( const { rows, schema } = ctx.request.body if (isRows(rows) && isSchema(schema)) { - ctx.status = 200 ctx.body = validateSchema(rows, schema, PROTECTED_INTERNAL_COLUMNS) } else { ctx.status = 422 @@ -224,7 +219,6 @@ export async function validateExistingTableImport( } if (tableId && isRows(rows) && isSchema(schema)) { - ctx.status = 200 ctx.body = validateSchema(rows, schema, protectedColumnNames) } else { ctx.status = 422 @@ -245,6 +239,5 @@ export async function migrate( }) } - ctx.status = 200 ctx.body = { message: `Column ${oldColumn} migrated.` } } diff --git a/packages/server/src/automations/steps/createRow.ts b/packages/server/src/automations/steps/createRow.ts index 4b9010dd01..e71b1e4556 100644 --- a/packages/server/src/automations/steps/createRow.ts +++ b/packages/server/src/automations/steps/createRow.ts @@ -112,7 +112,7 @@ export async function run({ response: ctx.body, id: ctx.body._id, revision: ctx.body._rev, - success: ctx.status === 200, + success: !!ctx.body._id, } } catch (err) { return { diff --git a/packages/server/src/automations/steps/deleteRow.ts b/packages/server/src/automations/steps/deleteRow.ts index c4c42d8200..8c61d256d1 100644 --- a/packages/server/src/automations/steps/deleteRow.ts +++ b/packages/server/src/automations/steps/deleteRow.ts @@ -94,7 +94,7 @@ export async function run({ return { response: ctx.body, row: ctx.row, - success: ctx.status === 200, + success: ctx.body.ok, } } catch (err) { return { diff --git a/packages/server/src/automations/steps/queryRows.ts b/packages/server/src/automations/steps/queryRows.ts index dc4dda4482..93ca8a3f33 100644 --- a/packages/server/src/automations/steps/queryRows.ts +++ b/packages/server/src/automations/steps/queryRows.ts @@ -152,7 +152,7 @@ export async function run({ return { rows, - success: ctx.status === 200, + success: true, } } catch (err) { return { diff --git a/packages/server/src/automations/steps/updateRow.ts b/packages/server/src/automations/steps/updateRow.ts index 65b9bf93d3..ecdbdc68c8 100644 --- a/packages/server/src/automations/steps/updateRow.ts +++ b/packages/server/src/automations/steps/updateRow.ts @@ -166,7 +166,7 @@ export async function run({ response: ctx.message, id: ctx.body._id, revision: ctx.body._rev, - success: ctx.status === 200, + success: !!ctx.body._id, } } catch (err) { return { diff --git a/packages/server/src/automations/tests/queryRows.spec.ts b/packages/server/src/automations/tests/queryRows.spec.ts index 18d2e2d6cd..21e28673f3 100644 --- a/packages/server/src/automations/tests/queryRows.spec.ts +++ b/packages/server/src/automations/tests/queryRows.spec.ts @@ -96,7 +96,7 @@ describe("Test a query step automation", () => { ) .run() - expect(result.steps[0].outputs.success).toBe(false) + expect(result.steps[0].outputs.success).toBe(true) expect(result.steps[0].outputs.rows).toBeDefined() expect(result.steps[0].outputs.rows.length).toBe(0) }) @@ -125,7 +125,7 @@ describe("Test a query step automation", () => { ) .run() - expect(result.steps[0].outputs.success).toBe(false) + expect(result.steps[0].outputs.success).toBe(true) expect(result.steps[0].outputs.rows).toBeDefined() expect(result.steps[0].outputs.rows.length).toBe(0) }) diff --git a/packages/server/src/tests/utilities/api/application.ts b/packages/server/src/tests/utilities/api/application.ts index 9dabc8cfe8..1fe9840c1d 100644 --- a/packages/server/src/tests/utilities/api/application.ts +++ b/packages/server/src/tests/utilities/api/application.ts @@ -48,7 +48,7 @@ export class ApplicationAPI extends TestAPI { unpublish = async (appId: string): Promise => { await this._post(`/api/applications/${appId}/unpublish`, { - expectations: { status: 204 }, + expectations: { status: 200 }, }) } diff --git a/packages/server/src/websockets/grid.ts b/packages/server/src/websockets/grid.ts index 661d47cb6d..205c2896a3 100644 --- a/packages/server/src/websockets/grid.ts +++ b/packages/server/src/websockets/grid.ts @@ -1,7 +1,7 @@ import authorized from "../middleware/authorized" import currentApp from "../middleware/currentapp" import { BaseSocket } from "./websocket" -import { auth, permissions } from "@budibase/backend-core" +import { auth, permissions, context } from "@budibase/backend-core" import http from "http" import Koa from "koa" import { getSourceId } from "../api/controllers/row/utils" @@ -10,6 +10,12 @@ import { Socket } from "socket.io" import { GridSocketEvent } from "@budibase/shared-core" import { userAgent } from "koa-useragent" import { createContext, runMiddlewares } from "./middleware" +import sdk from "../sdk" +import { + findHBSBlocks, + isJSBinding, + decodeJSBinding, +} from "@budibase/string-templates" const { PermissionType, PermissionLevel } = permissions @@ -18,15 +24,46 @@ export default class GridSocket extends BaseSocket { super(app, server, "/socket/grid") } + // Checks if a view's query contains any current user bindings + containsCurrentUserBinding(view: ViewV2): boolean { + return findHBSBlocks(JSON.stringify(view.query)) + .map(binding => { + const sanitizedBinding = binding.replace(/\\"/g, '"') + if (isJSBinding(sanitizedBinding)) { + return decodeJSBinding(sanitizedBinding) + } else { + return sanitizedBinding + } + }) + .some(binding => binding?.includes("[user]")) + } + async onConnect(socket: Socket) { // Initial identification of connected spreadsheet socket.on(GridSocketEvent.SelectDatasource, async (payload, callback) => { const ds = payload.datasource const appId = payload.appId const resourceId = ds?.type === "table" ? ds?.tableId : ds?.id + let valid = true - // Ignore if no table or app specified + // Validate datasource if (!resourceId || !appId) { + // Ignore if no table or app specified + valid = false + } else if (ds.type === "viewV2") { + // If this is a view filtered by current user, don't sync changes + try { + await context.doInAppContext(appId, async () => { + const view = await sdk.views.get(ds.id) + if (this.containsCurrentUserBinding(view)) { + valid = false + } + }) + } catch (err) { + valid = false + } + } + if (!valid) { socket.disconnect(true) return } diff --git a/packages/types/src/api/web/analytics.ts b/packages/types/src/api/web/analytics.ts index 2585964f94..3195da5df4 100644 --- a/packages/types/src/api/web/analytics.ts +++ b/packages/types/src/api/web/analytics.ts @@ -12,3 +12,7 @@ export interface AnalyticsPingRequest { timezone: string embedded?: boolean } +export interface AnalyticsPingResponse { + message: string + source?: PingSource +} diff --git a/packages/types/src/api/web/app/application.ts b/packages/types/src/api/web/app/application.ts index bc00ade217..a0f53a6ba4 100644 --- a/packages/types/src/api/web/app/application.ts +++ b/packages/types/src/api/web/app/application.ts @@ -44,6 +44,10 @@ export interface FetchAppPackageResponse { hasLock: boolean } +export interface AddAppSampleDataResponse { + message: string +} + export type FetchAppsResponse = App[] export interface PublishResponse { @@ -61,6 +65,10 @@ export interface DeleteAppResponse { ok: boolean } +export interface UnpublishAppResponse { + message: string +} + export interface ImportToUpdateAppRequest { encryptionPassword?: string } @@ -71,6 +79,9 @@ export interface ImportToUpdateAppResponse { export interface SetRevertableAppVersionRequest { revertableVersion: string } +export interface SetRevertableAppVersionResponse { + message: string +} export interface ExportAppDumpRequest { excludeRows: boolean diff --git a/packages/types/src/api/web/app/permission.ts b/packages/types/src/api/web/app/permission.ts index 407dc2be86..b449516eed 100644 --- a/packages/types/src/api/web/app/permission.ts +++ b/packages/types/src/api/web/app/permission.ts @@ -29,7 +29,9 @@ export interface AddedPermission { reason?: string } -export interface AddPermissionResponse {} +export interface AddPermissionResponse { + message: string +} export interface AddPermissionRequest { roleId: string @@ -38,4 +40,6 @@ export interface AddPermissionRequest { } export interface RemovePermissionRequest extends AddPermissionRequest {} -export interface RemovePermissionResponse {} +export interface RemovePermissionResponse { + message: string +} diff --git a/packages/types/src/api/web/app/rowAction.ts b/packages/types/src/api/web/app/rowAction.ts index 84e4e529ed..b4ff5538b5 100644 --- a/packages/types/src/api/web/app/rowAction.ts +++ b/packages/types/src/api/web/app/rowAction.ts @@ -21,6 +21,9 @@ export interface RowActionsResponse { export interface RowActionTriggerRequest { rowId: string } +export interface RowActionTriggerResponse { + message: string +} export interface RowActionPermissionsResponse extends RowActionPermissionsData {} diff --git a/packages/types/src/api/web/auth.ts b/packages/types/src/api/web/auth.ts index 0964d71576..5ef6169086 100644 --- a/packages/types/src/api/web/auth.ts +++ b/packages/types/src/api/web/auth.ts @@ -2,12 +2,19 @@ export interface LoginRequest { username: string password: string } +export interface LoginResponse { + message: string + userId?: string +} export interface LogoutResponse { message: string } export interface SetInitInfoRequest extends Record {} +export interface SetInitInfoResponse { + message: string +} export interface GetInitInfoResponse extends Record {} diff --git a/packages/types/src/api/web/global/environmentVariables.ts b/packages/types/src/api/web/global/environmentVariables.ts index 6f339eb821..b9399e246b 100644 --- a/packages/types/src/api/web/global/environmentVariables.ts +++ b/packages/types/src/api/web/global/environmentVariables.ts @@ -7,12 +7,22 @@ export interface CreateEnvironmentVariableRequest { production: string development: string } +export interface CreateEnvironmentVariableResponse { + message: string +} export interface UpdateEnvironmentVariableRequest { production: string development: string } +export interface UpdateEnvironmentVariableResponse { + message: string +} export interface GetEnvironmentVariablesResponse { variables: string[] } + +export interface DeleteEnvironmentVariablesResponse { + message: string +} diff --git a/packages/types/src/api/web/global/events.ts b/packages/types/src/api/web/global/events.ts index 907cfc74aa..e55808bd32 100644 --- a/packages/types/src/api/web/global/events.ts +++ b/packages/types/src/api/web/global/events.ts @@ -5,3 +5,6 @@ export enum EventPublishType { export interface PostEventPublishRequest { type: EventPublishType } +export interface PostEventPublishResponse { + message: string +} diff --git a/packages/types/src/api/web/global/license.ts b/packages/types/src/api/web/global/license.ts index 344ab829c2..d108880f93 100644 --- a/packages/types/src/api/web/global/license.ts +++ b/packages/types/src/api/web/global/license.ts @@ -5,6 +5,9 @@ import { QuotaUsage } from "../../../documents" export interface ActivateLicenseKeyRequest { licenseKey: string } +export interface ActivateLicenseKeyResponse { + message: string +} export interface GetLicenseKeyResponse { licenseKey: string @@ -15,11 +18,20 @@ export interface GetLicenseKeyResponse { export interface ActivateOfflineLicenseTokenRequest { offlineLicenseToken: string } +export interface ActivateOfflineLicenseTokenResponse { + message: string +} export interface GetOfflineLicenseTokenResponse { offlineLicenseToken: string } +// REFRESH + +export interface RefreshOfflineLicenseResponse { + message: string +} + // IDENTIFIER export interface GetOfflineIdentifierResponse { diff --git a/packages/types/src/api/web/global/oldMigration.ts b/packages/types/src/api/web/global/oldMigration.ts index 4b8ce9cc8d..812ee1e593 100644 --- a/packages/types/src/api/web/global/oldMigration.ts +++ b/packages/types/src/api/web/global/oldMigration.ts @@ -1,6 +1,9 @@ import { Migration, MigrationOptions } from "../../../sdk" export interface RunOldMigrationRequest extends MigrationOptions {} +export interface RuneOldMigrationResponse { + message: string +} export type FetchOldMigrationResponse = Migration[] diff --git a/packages/types/src/api/web/system/migration.ts b/packages/types/src/api/web/system/migration.ts index f9f6eac48a..a18112744c 100644 --- a/packages/types/src/api/web/system/migration.ts +++ b/packages/types/src/api/web/system/migration.ts @@ -1,5 +1,8 @@ import { MigrationDefinition, MigrationOptions } from "../../../sdk" export interface RunGlobalMigrationRequest extends MigrationOptions {} +export interface RunGlobalMigrationResponse { + message: string +} export type FetchMigrationDefinitionsResponse = MigrationDefinition[] diff --git a/packages/types/src/api/web/user.ts b/packages/types/src/api/web/user.ts index 2f83f012b3..a42449d550 100644 --- a/packages/types/src/api/web/user.ts +++ b/packages/types/src/api/web/user.ts @@ -110,6 +110,9 @@ export interface AddSSoUserRequest { ssoId: string email: string } +export interface AddSSoUserResponse { + message: string +} export interface CreateAdminUserResponse { _id: string diff --git a/packages/worker/src/api/controllers/global/auth.ts b/packages/worker/src/api/controllers/global/auth.ts index 1e6b0d3aab..0d49515700 100644 --- a/packages/worker/src/api/controllers/global/auth.ts +++ b/packages/worker/src/api/controllers/global/auth.ts @@ -22,6 +22,8 @@ import { GetInitInfoResponse, PasswordResetResponse, PasswordResetUpdateResponse, + SetInitInfoResponse, + LoginResponse, } from "@budibase/types" import env from "../../../environment" import { Next } from "koa" @@ -59,7 +61,10 @@ async function passportCallback( ctx.set(Header.TOKEN, token) } -export const login = async (ctx: Ctx, next: Next) => { +export const login = async ( + ctx: Ctx, + next: Next +) => { const email = ctx.request.body.username const user = await userSdk.db.getUserByEmail(email) @@ -74,7 +79,10 @@ export const login = async (ctx: Ctx, next: Next) => { await context.identity.doInUserContext(user, ctx, async () => { await events.auth.login("local", user.email) }) - ctx.status = 200 + ctx.body = { + message: "Login successful", + userId: user.userId, + } } )(ctx, next) } @@ -88,10 +96,14 @@ export const logout = async (ctx: UserCtx) => { // INIT -export const setInitInfo = (ctx: UserCtx) => { +export const setInitInfo = ( + ctx: UserCtx +) => { const initInfo = ctx.request.body setCookie(ctx, initInfo, Cookie.Init) - ctx.status = 200 + ctx.body = { + message: "Init info updated.", + } } export const getInitInfo = (ctx: UserCtx) => { diff --git a/packages/worker/src/api/controllers/global/events.ts b/packages/worker/src/api/controllers/global/events.ts index 758fb41b54..3d7ff4c29e 100644 --- a/packages/worker/src/api/controllers/global/events.ts +++ b/packages/worker/src/api/controllers/global/events.ts @@ -2,10 +2,13 @@ import { UserCtx, PostEventPublishRequest, EventPublishType, + PostEventPublishResponse, } from "@budibase/types" import { events } from "@budibase/backend-core" -export async function publish(ctx: UserCtx) { +export async function publish( + ctx: UserCtx +) { switch (ctx.request.body.type) { case EventPublishType.ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED: await events.environmentVariable.upgradePanelOpened(ctx.user._id!) @@ -13,5 +16,5 @@ export async function publish(ctx: UserCtx) { default: ctx.throw(400, "Invalid publish event type.") } - ctx.status = 200 + ctx.body = { message: "Event published." } } diff --git a/packages/worker/src/api/controllers/global/license.ts b/packages/worker/src/api/controllers/global/license.ts index 04f76a6593..014b01d87c 100644 --- a/packages/worker/src/api/controllers/global/license.ts +++ b/packages/worker/src/api/controllers/global/license.ts @@ -1,29 +1,33 @@ import { licensing, quotas } from "@budibase/pro" import { ActivateLicenseKeyRequest, + ActivateLicenseKeyResponse, ActivateOfflineLicenseTokenRequest, + ActivateOfflineLicenseTokenResponse, GetLicenseKeyResponse, GetOfflineIdentifierResponse, GetOfflineLicenseTokenResponse, GetQuotaUsageResponse, + RefreshOfflineLicenseResponse, UserCtx, } from "@budibase/types" // LICENSE KEY export async function activateLicenseKey( - ctx: UserCtx + ctx: UserCtx ) { const { licenseKey } = ctx.request.body await licensing.keys.activateLicenseKey(licenseKey) - ctx.status = 200 + ctx.body = { + message: "License activated.", + } } export async function getLicenseKey(ctx: UserCtx) { const licenseKey = await licensing.keys.getLicenseKey() if (licenseKey) { ctx.body = { licenseKey: "*" } - ctx.status = 200 } else { ctx.status = 404 } @@ -37,11 +41,16 @@ export async function deleteLicenseKey(ctx: UserCtx) { // OFFLINE LICENSE export async function activateOfflineLicenseToken( - ctx: UserCtx + ctx: UserCtx< + ActivateOfflineLicenseTokenRequest, + ActivateOfflineLicenseTokenResponse + > ) { const { offlineLicenseToken } = ctx.request.body await licensing.offline.activateOfflineLicenseToken(offlineLicenseToken) - ctx.status = 200 + ctx.body = { + message: "License token activated.", + } } export async function getOfflineLicenseToken( @@ -50,7 +59,6 @@ export async function getOfflineLicenseToken( const offlineLicenseToken = await licensing.offline.getOfflineLicenseToken() if (offlineLicenseToken) { ctx.body = { offlineLicenseToken: "*" } - ctx.status = 200 } else { ctx.status = 404 } @@ -66,14 +74,17 @@ export async function getOfflineLicenseIdentifier( ) { const identifierBase64 = await licensing.offline.getIdentifierBase64() ctx.body = { identifierBase64 } - ctx.status = 200 } // LICENSES -export const refresh = async (ctx: UserCtx) => { +export const refresh = async ( + ctx: UserCtx +) => { await licensing.cache.refresh() - ctx.status = 200 + ctx.body = { + message: "License refreshed.", + } } // USAGE @@ -82,5 +93,4 @@ export const getQuotaUsage = async ( ctx: UserCtx ) => { ctx.body = await quotas.getQuotaUsage() - ctx.status = 200 } diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts index 1d36dd524c..a028f4fd33 100644 --- a/packages/worker/src/api/controllers/global/users.ts +++ b/packages/worker/src/api/controllers/global/users.ts @@ -4,6 +4,7 @@ import { AcceptUserInviteRequest, AcceptUserInviteResponse, AddSSoUserRequest, + AddSSoUserResponse, BulkUserRequest, BulkUserResponse, CheckInviteResponse, @@ -93,7 +94,9 @@ export const save = async (ctx: UserCtx) => { } } -export const addSsoSupport = async (ctx: Ctx) => { +export const addSsoSupport = async ( + ctx: Ctx +) => { const { email, ssoId } = ctx.request.body try { // Status is changed to 404 from getUserDoc if user is not found @@ -113,7 +116,7 @@ export const addSsoSupport = async (ctx: Ctx) => { email, ssoId, }) - ctx.status = 200 + ctx.body = { message: "SSO support added." } } catch (err: any) { ctx.throw(err.status || 400, err) } diff --git a/packages/worker/src/api/controllers/system/accounts.ts b/packages/worker/src/api/controllers/system/accounts.ts index e02c3f046d..e3fd9f2627 100644 --- a/packages/worker/src/api/controllers/system/accounts.ts +++ b/packages/worker/src/api/controllers/system/accounts.ts @@ -19,7 +19,6 @@ export const save = async ( metadata = await accounts.metadata.saveMetadata(metadata) ctx.body = metadata - ctx.status = 200 } export const destroy = async (ctx: Ctx) => { diff --git a/packages/worker/src/api/controllers/system/migrations.ts b/packages/worker/src/api/controllers/system/migrations.ts index dc66412e42..fc253d839d 100644 --- a/packages/worker/src/api/controllers/system/migrations.ts +++ b/packages/worker/src/api/controllers/system/migrations.ts @@ -1,23 +1,23 @@ import { FetchMigrationDefinitionsResponse, RunGlobalMigrationRequest, + RunGlobalMigrationResponse, UserCtx, } from "@budibase/types" const { migrate, MIGRATIONS } = require("../../../migrations") export const runMigrations = async ( - ctx: UserCtx + ctx: UserCtx ) => { const options = ctx.request.body // don't await as can take a while, just return migrate(options) - ctx.status = 200 + ctx.body = { message: "Migration started." } } export const fetchDefinitions = async ( ctx: UserCtx ) => { ctx.body = MIGRATIONS - ctx.status = 200 } diff --git a/packages/worker/src/api/routes/system/tests/migrations.spec.ts b/packages/worker/src/api/routes/system/tests/migrations.spec.ts index 4198d65ee9..fe91a1070c 100644 --- a/packages/worker/src/api/routes/system/tests/migrations.spec.ts +++ b/packages/worker/src/api/routes/system/tests/migrations.spec.ts @@ -36,7 +36,7 @@ describe("/api/system/migrations", () => { it("runs migrations", async () => { const res = await config.api.migrations.runMigrations() - expect(res.text).toBe("OK") + expect(res.body.message).toBeDefined() expect(migrateFn).toHaveBeenCalledTimes(1) }) })