From 8c8a973c91ca9ca2f8baf062c98ac2ba718f9454 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 4 Dec 2024 18:34:16 +0000 Subject: [PATCH 01/14] Auth API typing. --- packages/types/src/api/web/auth.ts | 14 +++++++ .../worker/src/api/controllers/global/auth.ts | 38 +++++++++++++------ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/packages/types/src/api/web/auth.ts b/packages/types/src/api/web/auth.ts index d631762b302..0964d71576a 100644 --- a/packages/types/src/api/web/auth.ts +++ b/packages/types/src/api/web/auth.ts @@ -3,14 +3,28 @@ export interface LoginRequest { password: string } +export interface LogoutResponse { + message: string +} + +export interface SetInitInfoRequest extends Record {} + +export interface GetInitInfoResponse extends Record {} + export interface PasswordResetRequest { email: string } +export interface PasswordResetResponse { + message: string +} export interface PasswordResetUpdateRequest { resetCode: string password: string } +export interface PasswordResetUpdateResponse { + message: string +} export interface UpdateSelfRequest { firstName?: string diff --git a/packages/worker/src/api/controllers/global/auth.ts b/packages/worker/src/api/controllers/global/auth.ts index 530a1df1025..1e6b0d3aab4 100644 --- a/packages/worker/src/api/controllers/global/auth.ts +++ b/packages/worker/src/api/controllers/global/auth.ts @@ -16,8 +16,15 @@ import { PasswordResetUpdateRequest, GoogleInnerConfig, DatasourceAuthCookie, + LogoutResponse, + UserCtx, + SetInitInfoRequest, + GetInitInfoResponse, + PasswordResetResponse, + PasswordResetUpdateResponse, } from "@budibase/types" import env from "../../../environment" +import { Next } from "koa" import * as authSdk from "../../../sdk/auth" import * as userSdk from "../../../sdk/users" @@ -52,7 +59,7 @@ async function passportCallback( ctx.set(Header.TOKEN, token) } -export const login = async (ctx: Ctx, next: any) => { +export const login = async (ctx: Ctx, next: Next) => { const email = ctx.request.body.username const user = await userSdk.db.getUserByEmail(email) @@ -72,7 +79,7 @@ export const login = async (ctx: Ctx, next: any) => { )(ctx, next) } -export const logout = async (ctx: any) => { +export const logout = async (ctx: UserCtx) => { if (ctx.user && ctx.user._id) { await authSdk.logout({ ctx, userId: ctx.user._id }) } @@ -81,13 +88,13 @@ export const logout = async (ctx: any) => { // INIT -export const setInitInfo = (ctx: any) => { +export const setInitInfo = (ctx: UserCtx) => { const initInfo = ctx.request.body setCookie(ctx, initInfo, Cookie.Init) ctx.status = 200 } -export const getInitInfo = (ctx: any) => { +export const getInitInfo = (ctx: UserCtx) => { try { ctx.body = getCookie(ctx, Cookie.Init) || {} } catch (err) { @@ -101,7 +108,9 @@ export const getInitInfo = (ctx: any) => { /** * Reset the user password, used as part of a forgotten password flow. */ -export const reset = async (ctx: Ctx) => { +export const reset = async ( + ctx: Ctx +) => { const { email } = ctx.request.body await authSdk.reset(email) @@ -114,7 +123,9 @@ export const reset = async (ctx: Ctx) => { /** * Perform the user password update if the provided reset code is valid. */ -export const resetUpdate = async (ctx: Ctx) => { +export const resetUpdate = async ( + ctx: Ctx +) => { const { resetCode, password } = ctx.request.body try { await authSdk.resetUpdate(resetCode, password) @@ -130,7 +141,10 @@ export const resetUpdate = async (ctx: Ctx) => { // DATASOURCE -export const datasourcePreAuth = async (ctx: any, next: any) => { +export const datasourcePreAuth = async ( + ctx: UserCtx, + next: Next +) => { const provider = ctx.params.provider const { middleware } = require(`@budibase/backend-core`) const handler = middleware.datasource[provider] @@ -147,7 +161,7 @@ export const datasourcePreAuth = async (ctx: any, next: any) => { return handler.preAuth(passport, ctx, next) } -export const datasourceAuth = async (ctx: any, next: any) => { +export const datasourceAuth = async (ctx: UserCtx, next: Next) => { const authStateCookie = getCookie( ctx, Cookie.DatasourceAuth @@ -171,7 +185,7 @@ export async function googleCallbackUrl(config?: GoogleInnerConfig) { * 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. */ -export const googlePreAuth = async (ctx: any, next: any) => { +export const googlePreAuth = async (ctx: Ctx, next: Next) => { const config = await configs.getGoogleConfig() if (!config) { return ctx.throw(400, "Google config not found") @@ -190,7 +204,7 @@ export const googlePreAuth = async (ctx: any, next: any) => { })(ctx, next) } -export const googleCallback = async (ctx: any, next: any) => { +export const googleCallback = async (ctx: Ctx, next: Next) => { const config = await configs.getGoogleConfig() if (!config) { return ctx.throw(400, "Google config not found") @@ -241,7 +255,7 @@ export const oidcStrategyFactory = async (ctx: any) => { * 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. */ -export const oidcPreAuth = async (ctx: Ctx, next: any) => { +export const oidcPreAuth = async (ctx: Ctx, next: Next) => { const { configId } = ctx.params if (!configId) { ctx.throw(400, "OIDC config id is required") @@ -266,7 +280,7 @@ export const oidcPreAuth = async (ctx: Ctx, next: any) => { })(ctx, next) } -export const oidcCallback = async (ctx: any, next: any) => { +export const oidcCallback = async (ctx: Ctx, next: Next) => { const strategy = await oidcStrategyFactory(ctx) return passport.authenticate( From 60e4d3f0e6dedb16cc5e9f9dd53ec8bf62231c92 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 5 Dec 2024 14:50:50 +0000 Subject: [PATCH 02/14] Config API typing. --- packages/types/src/api/web/global/configs.ts | 39 ++++++++++++++++++- .../src/api/controllers/global/configs.ts | 20 +++++++--- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/types/src/api/web/global/configs.ts b/packages/types/src/api/web/global/configs.ts index b36d974904b..e16ed3c27f7 100644 --- a/packages/types/src/api/web/global/configs.ts +++ b/packages/types/src/api/web/global/configs.ts @@ -1,4 +1,10 @@ -import { SettingsConfig, SettingsInnerConfig } from "../../../documents" +import { + Config, + ConfigType, + SettingsBrandingConfig, + SettingsConfig, + SettingsInnerConfig, +} from "../../../documents" /** * Settings that aren't stored in the database - enriched at runtime. @@ -22,3 +28,34 @@ export interface PublicOIDCConfig { } export type GetPublicOIDCConfigResponse = PublicOIDCConfig[] + +export interface SaveConfigRequest extends Config {} +export interface SaveConfigResponse { + type: ConfigType + _id: string + _rev: string +} + +export interface DeleteConfigResponse { + message: string +} + +interface ChecklistItem { + checked: boolean + label: string + link: string +} +export interface ConfigChecklistResponse { + apps: ChecklistItem + smtp: ChecklistItem + adminUser: ChecklistItem + sso: ChecklistItem + branding: SettingsBrandingConfig +} + +export type FindConfigResponse = Config | {} + +export interface UploadConfigFileResponse { + message: string + url: string +} diff --git a/packages/worker/src/api/controllers/global/configs.ts b/packages/worker/src/api/controllers/global/configs.ts index b3f02a44c65..a10fce35f6d 100644 --- a/packages/worker/src/api/controllers/global/configs.ts +++ b/packages/worker/src/api/controllers/global/configs.ts @@ -15,8 +15,11 @@ import { AIConfig, AIInnerConfig, Config, + ConfigChecklistResponse, ConfigType, Ctx, + DeleteConfigResponse, + FindConfigResponse, GetPublicOIDCConfigResponse, GetPublicSettingsResponse, GoogleInnerConfig, @@ -29,11 +32,14 @@ import { OIDCLogosConfig, PASSWORD_REPLACEMENT, QuotaUsageType, + SaveConfigRequest, + SaveConfigResponse, SettingsBrandingConfig, SettingsInnerConfig, SSOConfig, SSOConfigType, StaticQuotaName, + UploadConfigFileResponse, UserCtx, } from "@budibase/types" import * as pro from "@budibase/pro" @@ -225,7 +231,9 @@ export async function verifyAIConfig( } } -export async function save(ctx: UserCtx) { +export async function save( + ctx: UserCtx +) { const body = ctx.request.body const type = body.type const config = body.config @@ -337,7 +345,7 @@ function enrichOIDCLogos(oidcLogos: OIDCLogosConfig) { ) } -export async function find(ctx: UserCtx) { +export async function find(ctx: UserCtx) { try { // Find the config with the most granular scope based on context const type = ctx.params.type @@ -473,7 +481,7 @@ export async function publicSettings( } } -export async function upload(ctx: UserCtx) { +export async function upload(ctx: UserCtx) { if (ctx.request.files == null || Array.isArray(ctx.request.files.file)) { ctx.throw(400, "One file must be uploaded.") } @@ -518,7 +526,7 @@ export async function upload(ctx: UserCtx) { } } -export async function destroy(ctx: UserCtx) { +export async function destroy(ctx: UserCtx) { const db = tenancy.getGlobalDB() const { id, rev } = ctx.params try { @@ -537,14 +545,14 @@ export async function destroy(ctx: UserCtx) { } } -export async function configChecklist(ctx: Ctx) { +export async function configChecklist(ctx: Ctx) { const tenantId = tenancy.getTenantId() try { ctx.body = await cache.withCache( cache.CacheKey.CHECKLIST, env.CHECKLIST_CACHE_TTL, - async () => { + async (): Promise => { let apps = [] if (!env.MULTI_TENANCY || tenantId) { // Apps exist From cbab77ea240228d86dc86f63669f18d5108256ff Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 5 Dec 2024 14:59:15 +0000 Subject: [PATCH 03/14] Email API typing. --- packages/types/src/api/web/global/email.ts | 28 +++++++++++++++++++ packages/types/src/api/web/global/index.ts | 1 + .../src/api/controllers/global/email.ts | 11 ++++++-- .../worker/src/api/routes/global/email.ts | 2 +- .../src/api/routes/global/tests/email.spec.ts | 2 +- .../api/routes/global/tests/realEmail.spec.ts | 3 +- .../api/routes/global/tests/templates.spec.ts | 7 ++--- packages/worker/src/constants/index.ts | 10 +------ .../worker/src/constants/templates/index.ts | 9 ++---- packages/worker/src/sdk/auth/auth.ts | 3 +- packages/worker/src/sdk/users/users.ts | 2 +- packages/worker/src/utilities/email.ts | 9 ++++-- packages/worker/src/utilities/templates.ts | 7 ++--- 13 files changed, 57 insertions(+), 37 deletions(-) create mode 100644 packages/types/src/api/web/global/email.ts diff --git a/packages/types/src/api/web/global/email.ts b/packages/types/src/api/web/global/email.ts new file mode 100644 index 00000000000..a0ca0e84859 --- /dev/null +++ b/packages/types/src/api/web/global/email.ts @@ -0,0 +1,28 @@ +import { EmailAttachment, EmailInvite } from "../../../documents" + +export enum EmailTemplatePurpose { + CORE = "core", + BASE = "base", + PASSWORD_RECOVERY = "password_recovery", + INVITATION = "invitation", + WELCOME = "welcome", + CUSTOM = "custom", +} + +export interface SendEmailRequest { + workspaceId?: string + email: string + userId: string + purpose: EmailTemplatePurpose + contents?: string + from?: string + subject: string + cc?: boolean + bcc?: boolean + automation?: boolean + invite?: EmailInvite + attachments?: EmailAttachment[] +} +export interface SendEmailResponse extends Record { + message: string +} diff --git a/packages/types/src/api/web/global/index.ts b/packages/types/src/api/web/global/index.ts index c43f2928d86..0cabb979744 100644 --- a/packages/types/src/api/web/global/index.ts +++ b/packages/types/src/api/web/global/index.ts @@ -5,3 +5,4 @@ export * from "./configs" export * from "./scim" export * from "./license" export * from "./oldMigration" +export * from "./email" diff --git a/packages/worker/src/api/controllers/global/email.ts b/packages/worker/src/api/controllers/global/email.ts index 74a811376a9..ad0fc3fa32a 100644 --- a/packages/worker/src/api/controllers/global/email.ts +++ b/packages/worker/src/api/controllers/global/email.ts @@ -1,8 +1,15 @@ import { sendEmail as sendEmailFn } from "../../../utilities/email" import { tenancy } from "@budibase/backend-core" -import { BBContext, User } from "@budibase/types" +import { + UserCtx, + User, + SendEmailRequest, + SendEmailResponse, +} from "@budibase/types" -export async function sendEmail(ctx: BBContext) { +export async function sendEmail( + ctx: UserCtx +) { let { workspaceId, email, diff --git a/packages/worker/src/api/routes/global/email.ts b/packages/worker/src/api/routes/global/email.ts index 94e6b9bce5f..6b60da47b5c 100644 --- a/packages/worker/src/api/routes/global/email.ts +++ b/packages/worker/src/api/routes/global/email.ts @@ -1,7 +1,7 @@ import Router from "@koa/router" import * as controller from "../../controllers/global/email" -import { EmailTemplatePurpose } from "../../../constants" import { auth } from "@budibase/backend-core" +import { EmailTemplatePurpose } from "@budibase/types" import Joi from "joi" const router: Router = new Router() diff --git a/packages/worker/src/api/routes/global/tests/email.spec.ts b/packages/worker/src/api/routes/global/tests/email.spec.ts index 49d7c3bbeb0..eb46c501d96 100644 --- a/packages/worker/src/api/routes/global/tests/email.spec.ts +++ b/packages/worker/src/api/routes/global/tests/email.spec.ts @@ -1,8 +1,8 @@ jest.mock("nodemailer") +import { EmailTemplatePurpose } from "@budibase/types" import { TestConfiguration, mocks } from "../../../../tests" const sendMailMock = mocks.email.mock() -import { EmailTemplatePurpose } from "../../../../constants" describe("/api/global/email", () => { const config = new TestConfiguration() diff --git a/packages/worker/src/api/routes/global/tests/realEmail.spec.ts b/packages/worker/src/api/routes/global/tests/realEmail.spec.ts index 99dfb7f8249..bf5ed7b4ee4 100644 --- a/packages/worker/src/api/routes/global/tests/realEmail.spec.ts +++ b/packages/worker/src/api/routes/global/tests/realEmail.spec.ts @@ -1,11 +1,10 @@ jest.unmock("node-fetch") import { TestConfiguration } from "../../../../tests" -import { EmailTemplatePurpose } from "../../../../constants" import { objectStore } from "@budibase/backend-core" import { helpers } from "@budibase/shared-core" import tk from "timekeeper" -import { EmailAttachment } from "@budibase/types" +import { EmailAttachment, EmailTemplatePurpose } from "@budibase/types" const fetch = require("node-fetch") diff --git a/packages/worker/src/api/routes/global/tests/templates.spec.ts b/packages/worker/src/api/routes/global/tests/templates.spec.ts index 982cae28b53..786023101e4 100644 --- a/packages/worker/src/api/routes/global/tests/templates.spec.ts +++ b/packages/worker/src/api/routes/global/tests/templates.spec.ts @@ -1,9 +1,6 @@ -import { - EmailTemplatePurpose, - TemplateMetadata, - TemplateType, -} from "../../../../constants" +import { TemplateMetadata, TemplateType } from "../../../../constants" import { TestConfiguration } from "../../../../tests" +import { EmailTemplatePurpose } from "@budibase/types" // TODO diff --git a/packages/worker/src/constants/index.ts b/packages/worker/src/constants/index.ts index 17fce666db7..309fdeebc1a 100644 --- a/packages/worker/src/constants/index.ts +++ b/packages/worker/src/constants/index.ts @@ -1,4 +1,5 @@ import { constants } from "@budibase/backend-core" +import { EmailTemplatePurpose } from "@budibase/types" export const LOGO_URL = "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg" @@ -19,15 +20,6 @@ export enum TemplateType { EMAIL = "email", } -export enum EmailTemplatePurpose { - CORE = "core", - BASE = "base", - PASSWORD_RECOVERY = "password_recovery", - INVITATION = "invitation", - WELCOME = "welcome", - CUSTOM = "custom", -} - export enum TemplateMetadataNames { BASE = "Base format", PASSWORD_RECOVERY = "Password recovery", diff --git a/packages/worker/src/constants/templates/index.ts b/packages/worker/src/constants/templates/index.ts index 6dd3f556a6b..43c5b0870fc 100644 --- a/packages/worker/src/constants/templates/index.ts +++ b/packages/worker/src/constants/templates/index.ts @@ -1,13 +1,8 @@ import { readStaticFile } from "../../utilities/fileSystem" -import { - EmailTemplatePurpose, - TemplateType, - TemplatePurpose, - GLOBAL_OWNER, -} from "../index" +import { TemplateType, TemplatePurpose, GLOBAL_OWNER } from "../index" import { join } from "path" import { db as dbCore, tenancy } from "@budibase/backend-core" -import { Template } from "@budibase/types" +import { Template, EmailTemplatePurpose } from "@budibase/types" export const EmailTemplates = { [EmailTemplatePurpose.PASSWORD_RECOVERY]: readStaticFile( diff --git a/packages/worker/src/sdk/auth/auth.ts b/packages/worker/src/sdk/auth/auth.ts index 078ac441e96..82602f58aa7 100644 --- a/packages/worker/src/sdk/auth/auth.ts +++ b/packages/worker/src/sdk/auth/auth.ts @@ -8,11 +8,10 @@ import { utils as coreUtils, cache, } from "@budibase/backend-core" -import { PlatformLogoutOpts, User } from "@budibase/types" +import { PlatformLogoutOpts, User, EmailTemplatePurpose } from "@budibase/types" import jwt from "jsonwebtoken" import * as userSdk from "../users" import * as emails from "../../utilities/email" -import { EmailTemplatePurpose } from "../../constants" // LOGIN / LOGOUT diff --git a/packages/worker/src/sdk/users/users.ts b/packages/worker/src/sdk/users/users.ts index 9dc1bac0e91..343108cbeb2 100644 --- a/packages/worker/src/sdk/users/users.ts +++ b/packages/worker/src/sdk/users/users.ts @@ -3,9 +3,9 @@ import { InviteUserRequest, InviteUsersRequest, InviteUsersResponse, + EmailTemplatePurpose, } from "@budibase/types" import { sendEmail } from "../../utilities/email" -import { EmailTemplatePurpose } from "../../constants" export async function invite( users: InviteUsersRequest diff --git a/packages/worker/src/utilities/email.ts b/packages/worker/src/utilities/email.ts index bf686f647c8..fa9dd7a6fad 100644 --- a/packages/worker/src/utilities/email.ts +++ b/packages/worker/src/utilities/email.ts @@ -1,9 +1,14 @@ import env from "../environment" -import { EmailTemplatePurpose, TemplateType } from "../constants" +import { TemplateType } from "../constants" import { getTemplateByPurpose, EmailTemplates } from "../constants/templates" import { getSettingsTemplateContext } from "./templates" import { processString } from "@budibase/string-templates" -import { User, SendEmailOpts, SMTPInnerConfig } from "@budibase/types" +import { + User, + SendEmailOpts, + SMTPInnerConfig, + EmailTemplatePurpose, +} from "@budibase/types" import { configs, cache, objectStore } from "@budibase/backend-core" import ical from "ical-generator" import _ from "lodash" diff --git a/packages/worker/src/utilities/templates.ts b/packages/worker/src/utilities/templates.ts index c9e86ae4f9a..cdfbb9b0ff6 100644 --- a/packages/worker/src/utilities/templates.ts +++ b/packages/worker/src/utilities/templates.ts @@ -1,9 +1,6 @@ import { tenancy, configs } from "@budibase/backend-core" -import { - InternalTemplateBinding, - LOGO_URL, - EmailTemplatePurpose, -} from "../constants" +import { EmailTemplatePurpose } from "@budibase/types" +import { InternalTemplateBinding, LOGO_URL } from "../constants" import { checkSlashesInUrl } from "./index" const BASE_COMPANY = "Budibase" From c0df3e67b38528a89b3c81bf9bb9037d4439f7b5 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 5 Dec 2024 15:01:48 +0000 Subject: [PATCH 04/14] Licensing API typing. --- packages/types/src/api/web/global/license.ts | 4 ++++ packages/worker/src/api/controllers/global/license.ts | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/types/src/api/web/global/license.ts b/packages/types/src/api/web/global/license.ts index 21d88764125..344ab829c2b 100644 --- a/packages/types/src/api/web/global/license.ts +++ b/packages/types/src/api/web/global/license.ts @@ -1,5 +1,7 @@ // LICENSE KEY +import { QuotaUsage } from "../../../documents" + export interface ActivateLicenseKeyRequest { licenseKey: string } @@ -23,3 +25,5 @@ export interface GetOfflineLicenseTokenResponse { export interface GetOfflineIdentifierResponse { identifierBase64: string } + +export interface GetQuotaUsageResponse extends QuotaUsage {} diff --git a/packages/worker/src/api/controllers/global/license.ts b/packages/worker/src/api/controllers/global/license.ts index 111cb5cea32..04f76a65938 100644 --- a/packages/worker/src/api/controllers/global/license.ts +++ b/packages/worker/src/api/controllers/global/license.ts @@ -5,6 +5,7 @@ import { GetLicenseKeyResponse, GetOfflineIdentifierResponse, GetOfflineLicenseTokenResponse, + GetQuotaUsageResponse, UserCtx, } from "@budibase/types" @@ -36,7 +37,7 @@ export async function deleteLicenseKey(ctx: UserCtx) { // OFFLINE LICENSE export async function activateOfflineLicenseToken( - ctx: UserCtx + ctx: UserCtx ) { const { offlineLicenseToken } = ctx.request.body await licensing.offline.activateOfflineLicenseToken(offlineLicenseToken) @@ -70,14 +71,16 @@ export async function getOfflineLicenseIdentifier( // LICENSES -export const refresh = async (ctx: any) => { +export const refresh = async (ctx: UserCtx) => { await licensing.cache.refresh() ctx.status = 200 } // USAGE -export const getQuotaUsage = async (ctx: any) => { +export const getQuotaUsage = async ( + ctx: UserCtx +) => { ctx.body = await quotas.getQuotaUsage() ctx.status = 200 } From 54c11e33c5f649f52389e39a77b343d84cec1a62 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 5 Dec 2024 15:56:04 +0000 Subject: [PATCH 05/14] Role API typing. --- packages/types/src/api/web/global/index.ts | 1 + packages/types/src/api/web/global/role.ts | 17 +++++++++++++++++ .../worker/src/api/controllers/global/roles.ts | 14 ++++++++++---- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 packages/types/src/api/web/global/role.ts diff --git a/packages/types/src/api/web/global/index.ts b/packages/types/src/api/web/global/index.ts index 0cabb979744..e0c585a9325 100644 --- a/packages/types/src/api/web/global/index.ts +++ b/packages/types/src/api/web/global/index.ts @@ -6,3 +6,4 @@ export * from "./scim" export * from "./license" export * from "./oldMigration" export * from "./email" +export * from "./role" diff --git a/packages/types/src/api/web/global/role.ts b/packages/types/src/api/web/global/role.ts new file mode 100644 index 00000000000..1d45995fd2d --- /dev/null +++ b/packages/types/src/api/web/global/role.ts @@ -0,0 +1,17 @@ +import { Role } from "../../../documents" + +interface GlobalRoleResponse { + roles: Role[] + name: string + version: string + url?: string +} + +export interface FetchGlobalRolesResponse + extends Record {} + +export interface FindGlobalRoleResponse extends GlobalRoleResponse {} + +export interface RemoveAppRoleResponse { + message: string +} diff --git a/packages/worker/src/api/controllers/global/roles.ts b/packages/worker/src/api/controllers/global/roles.ts index e1a3130924d..fb93ab504ca 100644 --- a/packages/worker/src/api/controllers/global/roles.ts +++ b/packages/worker/src/api/controllers/global/roles.ts @@ -6,9 +6,15 @@ import { tenancy, } from "@budibase/backend-core" import sdk from "../../../sdk" -import { Ctx, App } from "@budibase/types" +import { + Ctx, + App, + FetchGlobalRolesResponse, + FindGlobalRoleResponse, + RemoveAppRoleResponse, +} from "@budibase/types" -export async function fetch(ctx: Ctx) { +export async function fetch(ctx: Ctx) { const tenantId = ctx.user!.tenantId // always use the dev apps as they'll be most up to date (true) const apps = (await dbCore.getAllApps({ tenantId, all: true })) as App[] @@ -31,7 +37,7 @@ export async function fetch(ctx: Ctx) { ctx.body = response } -export async function find(ctx: Ctx) { +export async function find(ctx: Ctx) { const appId = ctx.params.appId await context.doInAppContext(dbCore.getDevAppID(appId), async () => { const db = context.getAppDB() @@ -45,7 +51,7 @@ export async function find(ctx: Ctx) { }) } -export async function removeAppRole(ctx: Ctx) { +export async function removeAppRole(ctx: Ctx) { const { appId } = ctx.params const db = tenancy.getGlobalDB() const users = await sdk.users.db.allUsers() From cdabe324ad928304bdb745a1e10c271a80eec944 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 5 Dec 2024 16:07:16 +0000 Subject: [PATCH 06/14] Self API typing. --- packages/types/src/api/web/global/index.ts | 1 + packages/types/src/api/web/global/self.ts | 12 ++++++++++ .../types/src/documents/global/devInfo.ts | 6 +++++ packages/types/src/documents/global/index.ts | 1 + .../worker/src/api/controllers/global/self.ts | 24 ++++++++++++------- 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 packages/types/src/api/web/global/self.ts create mode 100644 packages/types/src/documents/global/devInfo.ts diff --git a/packages/types/src/api/web/global/index.ts b/packages/types/src/api/web/global/index.ts index e0c585a9325..8359d8cd1a2 100644 --- a/packages/types/src/api/web/global/index.ts +++ b/packages/types/src/api/web/global/index.ts @@ -7,3 +7,4 @@ export * from "./license" export * from "./oldMigration" export * from "./email" export * from "./role" +export * from "./self" diff --git a/packages/types/src/api/web/global/self.ts b/packages/types/src/api/web/global/self.ts new file mode 100644 index 00000000000..4ba51d2cd55 --- /dev/null +++ b/packages/types/src/api/web/global/self.ts @@ -0,0 +1,12 @@ +import { DevInfo, User } from "../../../documents" + +export interface GenerateAPIKeyRequest { + userId: string +} +export interface GenerateAPIKeyResponse extends DevInfo {} + +export interface FetchAPIKeyResponse extends DevInfo {} + +export interface GetGlobalSelfResponse extends User { + flags?: Record +} diff --git a/packages/types/src/documents/global/devInfo.ts b/packages/types/src/documents/global/devInfo.ts new file mode 100644 index 00000000000..f993fc5df6d --- /dev/null +++ b/packages/types/src/documents/global/devInfo.ts @@ -0,0 +1,6 @@ +import { Document } from "../document" + +export interface DevInfo extends Document { + userId: string + apiKey?: string +} diff --git a/packages/types/src/documents/global/index.ts b/packages/types/src/documents/global/index.ts index 7d2f5a767cd..9bf24f078d7 100644 --- a/packages/types/src/documents/global/index.ts +++ b/packages/types/src/documents/global/index.ts @@ -8,3 +8,4 @@ export * from "./templates" export * from "./environmentVariables" export * from "./auditLogs" export * from "./apikeys" +export * from "./devInfo" diff --git a/packages/worker/src/api/controllers/global/self.ts b/packages/worker/src/api/controllers/global/self.ts index 14a2ce8c73a..7f2a1391060 100644 --- a/packages/worker/src/api/controllers/global/self.ts +++ b/packages/worker/src/api/controllers/global/self.ts @@ -10,6 +10,12 @@ import { import env from "../../../environment" import { groups } from "@budibase/pro" import { + Ctx, + DevInfo, + FetchAPIKeyResponse, + GenerateAPIKeyRequest, + GenerateAPIKeyResponse, + GetGlobalSelfResponse, UpdateSelfRequest, UpdateSelfResponse, User, @@ -35,22 +41,24 @@ function cleanupDevInfo(info: any) { return info } -export async function generateAPIKey(ctx: any) { +export async function generateAPIKey( + ctx: UserCtx +) { let userId let apiKey if (env.isTest() && ctx.request.body.userId) { userId = ctx.request.body.userId apiKey = newTestApiKey() } else { - userId = ctx.user._id + userId = ctx.user._id! apiKey = newApiKey() } const db = tenancy.getGlobalDB() const id = dbCore.generateDevInfoID(userId) - let devInfo + let devInfo: DevInfo try { - devInfo = await db.get(id) + devInfo = await db.get(id) } catch (err) { devInfo = { _id: id, userId } } @@ -59,9 +67,9 @@ export async function generateAPIKey(ctx: any) { ctx.body = cleanupDevInfo(devInfo) } -export async function fetchAPIKey(ctx: any) { +export async function fetchAPIKey(ctx: UserCtx) { const db = tenancy.getGlobalDB() - const id = dbCore.generateDevInfoID(ctx.user._id) + const id = dbCore.generateDevInfoID(ctx.user._id!) let devInfo try { devInfo = await db.get(id) @@ -87,11 +95,11 @@ const addSessionAttributesToUser = (ctx: any) => { ctx.body.csrfToken = ctx.user.csrfToken } -export async function getSelf(ctx: any) { +export async function getSelf(ctx: UserCtx) { if (!ctx.user) { ctx.throw(403, "User not logged in") } - const userId = ctx.user._id + const userId = ctx.user._id! ctx.params = { id: userId, } From 30717dae6c05fc386b0cfaf5a9678989af77c72e Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 5 Dec 2024 16:26:57 +0000 Subject: [PATCH 07/14] Template API typing. --- packages/types/src/api/web/global/index.ts | 1 + packages/types/src/api/web/global/template.ts | 30 +++++++++++ .../src/api/controllers/global/templates.ts | 50 ++++++++++++------- .../worker/src/constants/templates/index.ts | 23 ++++++--- 4 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 packages/types/src/api/web/global/template.ts diff --git a/packages/types/src/api/web/global/index.ts b/packages/types/src/api/web/global/index.ts index 8359d8cd1a2..36dce60b6cc 100644 --- a/packages/types/src/api/web/global/index.ts +++ b/packages/types/src/api/web/global/index.ts @@ -8,3 +8,4 @@ export * from "./oldMigration" export * from "./email" export * from "./role" export * from "./self" +export * from "./template" diff --git a/packages/types/src/api/web/global/template.ts b/packages/types/src/api/web/global/template.ts new file mode 100644 index 00000000000..0e79cbe62d4 --- /dev/null +++ b/packages/types/src/api/web/global/template.ts @@ -0,0 +1,30 @@ +import { Document, Template } from "../../../documents" + +export interface TemplateDefinition { + name: string + description: string + category: string +} + +export interface TemplateBinding { + name: string + description: string +} + +export interface FetchTemplateDefinitionResponse { + info: Record + bindings: Record +} + +export interface SaveTemplateRequest extends Template {} +export interface SaveTemplateResponse extends Template {} + +export type FetchTemplateResponse = Template[] +export type FetchTemplateByTypeResponse = Template[] +export type FetchTemplateByOwnerIDResponse = Template[] + +export interface FindTemplateResponse extends Template {} + +export interface DeleteTemplateResponse { + message: string +} diff --git a/packages/worker/src/api/controllers/global/templates.ts b/packages/worker/src/api/controllers/global/templates.ts index 0abce704c7b..5fba215e961 100644 --- a/packages/worker/src/api/controllers/global/templates.ts +++ b/packages/worker/src/api/controllers/global/templates.ts @@ -3,10 +3,25 @@ import { TemplateBindings, GLOBAL_OWNER, } from "../../../constants" -import { getTemplates } from "../../../constants/templates" +import { getTemplateByID, getTemplates } from "../../../constants/templates" import { tenancy, db as dbCore } from "@budibase/backend-core" +import { + DeleteTemplateResponse, + FetchTemplateByOwnerIDResponse, + FetchTemplateByTypeResponse, + FetchTemplateDefinitionResponse, + FetchTemplateResponse, + FindTemplateResponse, + SaveTemplateRequest, + SaveTemplateResponse, + TemplateBinding, + TemplateDefinition, + UserCtx, +} from "@budibase/types" -export async function save(ctx: any) { +export async function save( + ctx: UserCtx +) { const db = tenancy.getGlobalDB() let template = ctx.request.body if (!template.ownerId) { @@ -23,9 +38,11 @@ export async function save(ctx: any) { } } -export async function definitions(ctx: any) { - const bindings: any = {} - const info: any = {} +export async function definitions( + ctx: UserCtx +) { + const bindings: Record = {} + const info: Record = {} for (let template of TemplateMetadata.email) { bindings[template.purpose] = template.bindings info[template.purpose] = { @@ -44,34 +61,33 @@ export async function definitions(ctx: any) { } } -export async function fetch(ctx: any) { +export async function fetch(ctx: UserCtx) { ctx.body = await getTemplates() } -export async function fetchByType(ctx: any) { - // @ts-ignore +export async function fetchByType( + ctx: UserCtx +) { ctx.body = await getTemplates({ type: ctx.params.type, }) } -export async function fetchByOwner(ctx: any) { +export async function fetchByOwner( + ctx: UserCtx +) { // @ts-ignore ctx.body = await getTemplates({ ownerId: ctx.params.ownerId, }) } -export async function find(ctx: any) { - // @ts-ignore - ctx.body = await getTemplates({ - id: ctx.params.id, - }) +export async function find(ctx: UserCtx) { + ctx.body = await getTemplateByID(ctx.params.id) } -export async function destroy(ctx: any) { +export async function destroy(ctx: UserCtx) { const db = tenancy.getGlobalDB() await db.remove(ctx.params.id, ctx.params.rev) - ctx.message = `Template ${ctx.params.id} deleted.` - ctx.status = 200 + ctx.body = { message: `Template ${ctx.params.id} deleted.` } } diff --git a/packages/worker/src/constants/templates/index.ts b/packages/worker/src/constants/templates/index.ts index 43c5b0870fc..b2e98afe585 100644 --- a/packages/worker/src/constants/templates/index.ts +++ b/packages/worker/src/constants/templates/index.ts @@ -48,26 +48,33 @@ export function addBaseTemplates(templates: Template[], type?: string) { export async function getTemplates({ ownerId, type, - id, -}: { ownerId?: string; type?: string; id?: string } = {}) { +}: { ownerId?: string; type?: string } = {}) { const db = tenancy.getGlobalDB() const response = await db.allDocs