Merge remote-tracking branch 'origin/master' into feature/multistep-form-block
This commit is contained in:
commit
c358344611
|
@ -38,10 +38,10 @@ jobs:
|
|||
submodules: ${{ env.IS_OSS_CONTRIBUTOR == 'false' }}
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- run: yarn lint
|
||||
|
@ -56,10 +56,10 @@ jobs:
|
|||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
|
||||
|
@ -84,7 +84,7 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: azure/setup-helm@v3
|
||||
- run: cd charts/budibase && helm lint .
|
||||
|
||||
|
@ -98,10 +98,10 @@ jobs:
|
|||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Test
|
||||
|
@ -122,10 +122,10 @@ jobs:
|
|||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Test worker
|
||||
|
@ -146,10 +146,10 @@ jobs:
|
|||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Test server
|
||||
|
@ -171,10 +171,10 @@ jobs:
|
|||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Test
|
||||
|
@ -194,10 +194,10 @@ jobs:
|
|||
submodules: ${{ env.IS_OSS_CONTRIBUTOR == 'false' }}
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
- name: Use Node.js 20.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
cache: yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Build packages
|
||||
|
|
|
@ -16,8 +16,8 @@ jobs:
|
|||
days-before-pr-stale: 7
|
||||
stale-issue-label: stale
|
||||
exempt-pr-labels: pinned,security,roadmap
|
||||
|
||||
days-before-pr-close: 7
|
||||
days-before-issue-close: 30
|
||||
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
|
@ -26,6 +26,7 @@ jobs:
|
|||
days-before-stale: 30
|
||||
only-issue-labels: bug,High priority
|
||||
stale-issue-label: warn
|
||||
days-before-close: 30
|
||||
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
|
@ -34,6 +35,7 @@ jobs:
|
|||
days-before-stale: 90
|
||||
only-issue-labels: bug,Medium priority
|
||||
stale-issue-label: warn
|
||||
days-before-close: 30
|
||||
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
|
@ -43,5 +45,4 @@ jobs:
|
|||
stale-issue-label: stale
|
||||
only-issue-labels: bug
|
||||
stale-issue-message: "This issue has been automatically marked as stale because it has not had any activity for six months."
|
||||
|
||||
days-before-close: 30
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
nodejs 18.17.0
|
||||
nodejs 20.10.0
|
||||
python 3.10.0
|
||||
yarn 1.22.19
|
||||
|
|
|
@ -90,7 +90,7 @@ Component libraries are collections of components as well as the definition of t
|
|||
|
||||
#### 1. Prerequisites
|
||||
|
||||
- NodeJS version `18.x.x`
|
||||
- NodeJS version `20.x.x`
|
||||
- Python version `3.x`
|
||||
|
||||
### Using asdf (recommended)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18-slim as build
|
||||
FROM node:20-slim as build
|
||||
|
||||
# install node-gyp dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends g++ make python3 jq
|
||||
|
@ -42,7 +42,7 @@ COPY packages/string-templates packages/string-templates
|
|||
FROM budibase/couchdb as runner
|
||||
ARG TARGETARCH
|
||||
ENV TARGETARCH $TARGETARCH
|
||||
ENV NODE_MAJOR 18
|
||||
ENV NODE_MAJOR 20
|
||||
#TARGETBUILD can be set to single (for single docker image) or aas (for azure app service)
|
||||
# e.g. docker build --build-arg TARGETBUILD=aas ....
|
||||
ARG TARGETBUILD=single
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.13.52",
|
||||
"version": "2.14.0",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"@babel/eslint-parser": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@esbuild-plugins/tsconfig-paths": "^0.1.2",
|
||||
"@types/node": "20.10.0",
|
||||
"@typescript-eslint/parser": "6.9.0",
|
||||
"esbuild": "^0.18.17",
|
||||
"esbuild-node-externals": "^1.8.0",
|
||||
|
@ -99,7 +100,7 @@
|
|||
"@budibase/types": "0.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
"node": ">=20.0.0 <21.0.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit c1a53bb2f4cafcb4c55ad7181146617b449907f2
|
||||
Subproject commit b11e6b47370d9b77c63648b45929c86bfed6360c
|
|
@ -65,7 +65,6 @@
|
|||
"@types/cookies": "0.7.8",
|
||||
"@types/jest": "29.5.5",
|
||||
"@types/lodash": "4.14.200",
|
||||
"@types/node": "18.17.0",
|
||||
"@types/node-fetch": "2.6.4",
|
||||
"@types/pouchdb": "6.4.0",
|
||||
"@types/redlock": "4.0.3",
|
||||
|
|
|
@ -134,7 +134,7 @@ export async function doInContext(appId: string, task: any): Promise<any> {
|
|||
}
|
||||
|
||||
export async function doInTenant<T>(
|
||||
tenantId: string | null,
|
||||
tenantId: string | undefined,
|
||||
task: () => T
|
||||
): Promise<T> {
|
||||
// make sure default always selected in single tenancy
|
||||
|
|
|
@ -33,6 +33,7 @@ export * as docUpdates from "./docUpdates"
|
|||
export * from "./utils/Duration"
|
||||
export { SearchParams } from "./db"
|
||||
export * as docIds from "./docIds"
|
||||
export * as security from "./security"
|
||||
// Add context to tenancy for backwards compatibility
|
||||
// only do this for external usages to prevent internal
|
||||
// circular dependencies
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { env } from ".."
|
||||
|
||||
export const PASSWORD_MIN_LENGTH = +(process.env.PASSWORD_MIN_LENGTH || 8)
|
||||
export const PASSWORD_MAX_LENGTH = +(process.env.PASSWORD_MAX_LENGTH || 512)
|
||||
|
||||
export function validatePassword(
|
||||
password: string
|
||||
): { valid: true } | { valid: false; error: string } {
|
||||
if (!password || password.length < PASSWORD_MIN_LENGTH) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `Password invalid. Minimum ${PASSWORD_MIN_LENGTH} characters.`,
|
||||
}
|
||||
}
|
||||
|
||||
if (password.length > PASSWORD_MAX_LENGTH) {
|
||||
return {
|
||||
valid: false,
|
||||
error: `Password invalid. Maximum ${PASSWORD_MAX_LENGTH} characters.`,
|
||||
}
|
||||
}
|
||||
|
||||
return { valid: true }
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from "./auth"
|
|
@ -0,0 +1,45 @@
|
|||
import { generator } from "../../../tests"
|
||||
import { PASSWORD_MAX_LENGTH, validatePassword } from "../auth"
|
||||
|
||||
describe("auth", () => {
|
||||
describe("validatePassword", () => {
|
||||
it("a valid password returns successful", () => {
|
||||
expect(validatePassword("password")).toEqual({ valid: true })
|
||||
})
|
||||
|
||||
it.each([
|
||||
["undefined", undefined],
|
||||
["null", null],
|
||||
["empty", ""],
|
||||
])("%s returns unsuccessful", (_, password) => {
|
||||
expect(validatePassword(password as string)).toEqual({
|
||||
valid: false,
|
||||
error: "Password invalid. Minimum 8 characters.",
|
||||
})
|
||||
})
|
||||
|
||||
it.each([
|
||||
generator.word({ length: PASSWORD_MAX_LENGTH }),
|
||||
generator.paragraph().substring(0, PASSWORD_MAX_LENGTH),
|
||||
])(`can use passwords up to 512 characters in length`, password => {
|
||||
expect(validatePassword(password)).toEqual({
|
||||
valid: true,
|
||||
})
|
||||
})
|
||||
|
||||
it.each([
|
||||
generator.word({ length: PASSWORD_MAX_LENGTH + 1 }),
|
||||
generator
|
||||
.paragraph({ sentences: 50 })
|
||||
.substring(0, PASSWORD_MAX_LENGTH + 1),
|
||||
])(
|
||||
`passwords cannot have more than ${PASSWORD_MAX_LENGTH} characters`,
|
||||
password => {
|
||||
expect(validatePassword(password)).toEqual({
|
||||
valid: false,
|
||||
error: "Password invalid. Maximum 512 characters.",
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
|
@ -39,7 +39,7 @@ const ALL_STRATEGIES = Object.values(TenantResolutionStrategy)
|
|||
export const getTenantIDFromCtx = (
|
||||
ctx: BBContext,
|
||||
opts: GetTenantIdOptions
|
||||
): string | null => {
|
||||
): string | undefined => {
|
||||
// exit early if not multi-tenant
|
||||
if (!isMultiTenant()) {
|
||||
return DEFAULT_TENANT_ID
|
||||
|
@ -144,5 +144,5 @@ export const getTenantIDFromCtx = (
|
|||
ctx.throw(403, "Tenant id not set")
|
||||
}
|
||||
|
||||
return null
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -157,12 +157,12 @@ describe("getTenantIDFromCtx", () => {
|
|||
TenantResolutionStrategy.PATH,
|
||||
],
|
||||
}
|
||||
expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull()
|
||||
expect(getTenantIDFromCtx(ctx, mockOpts)).toBeUndefined()
|
||||
expect(ctx.throw).toBeCalledTimes(1)
|
||||
expect(ctx.throw).toBeCalledWith(403, "Tenant id not set")
|
||||
})
|
||||
|
||||
it("returns null if allowNoTenant is true", () => {
|
||||
it("returns undefined if allowNoTenant is true", () => {
|
||||
const ctx = createCtx({})
|
||||
mockOpts = {
|
||||
allowNoTenant: true,
|
||||
|
@ -172,7 +172,7 @@ describe("getTenantIDFromCtx", () => {
|
|||
TenantResolutionStrategy.PATH,
|
||||
],
|
||||
}
|
||||
expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull()
|
||||
expect(getTenantIDFromCtx(ctx, mockOpts)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
} from "./utils"
|
||||
import { searchExistingEmails } from "./lookup"
|
||||
import { hash } from "../utils"
|
||||
import { validatePassword } from "../security"
|
||||
|
||||
type QuotaUpdateFn = (
|
||||
change: number,
|
||||
|
@ -110,6 +111,12 @@ export class UserDB {
|
|||
if (await UserDB.isPreventPasswordActions(user, account)) {
|
||||
throw new HTTPError("Password change is disabled for this user", 400)
|
||||
}
|
||||
|
||||
const passwordValidation = validatePassword(password)
|
||||
if (!passwordValidation.valid) {
|
||||
throw new HTTPError(passwordValidation.error, 400)
|
||||
}
|
||||
|
||||
hashedPassword = opts.hashPassword ? await hash(password) : password
|
||||
} else if (dbUser) {
|
||||
hashedPassword = dbUser.password
|
||||
|
|
|
@ -31,8 +31,8 @@ export async function resolveAppUrl(ctx: Ctx) {
|
|||
const appUrl = ctx.path.split("/")[2]
|
||||
let possibleAppUrl = `/${appUrl.toLowerCase()}`
|
||||
|
||||
let tenantId: string | null = context.getTenantId()
|
||||
if (env.MULTI_TENANCY) {
|
||||
let tenantId: string | undefined = context.getTenantId()
|
||||
if (!env.isDev() && env.MULTI_TENANCY) {
|
||||
// always use the tenant id from the subdomain in multi tenancy
|
||||
// this ensures the logged-in user tenant id doesn't overwrite
|
||||
// e.g. in the case of viewing a public app while already logged-in to another tenant
|
||||
|
@ -41,7 +41,7 @@ export async function resolveAppUrl(ctx: Ctx) {
|
|||
})
|
||||
}
|
||||
|
||||
// search prod apps for a url that matches
|
||||
// search prod apps for an url that matches
|
||||
const apps: App[] = await context.doInTenant(
|
||||
tenantId,
|
||||
() => getAllApps({ dev: false }) as Promise<App[]>
|
||||
|
|
|
@ -21,7 +21,7 @@ export const user = (userProps?: Partial<Omit<User, "userId">>): User => {
|
|||
_id: userId,
|
||||
userId,
|
||||
email: newEmail(),
|
||||
password: "test",
|
||||
password: "password",
|
||||
roles: { app_test: "admin" },
|
||||
firstName: generator.first(),
|
||||
lastName: generator.last(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { string, number } from "yup"
|
||||
import { string, number, object } from "yup"
|
||||
|
||||
const propertyValidator = type => {
|
||||
if (type === "number") {
|
||||
|
@ -9,6 +9,10 @@ const propertyValidator = type => {
|
|||
return string().email().nullable()
|
||||
}
|
||||
|
||||
if (type === "object") {
|
||||
return object().nullable()
|
||||
}
|
||||
|
||||
return string().nullable()
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<div class="filter-editor">
|
||||
<ActionButton on:click={drawer.show}>{text}</ActionButton>
|
||||
</div>
|
||||
<Drawer bind:this={drawer} title="Filtering">
|
||||
<Drawer bind:this={drawer} title="Filtering" on:drawerHide on:drawerShow>
|
||||
<Button cta slot="buttons" on:click={saveFilter}>Save</Button>
|
||||
<FilterDrawer
|
||||
slot="body"
|
||||
|
|
|
@ -32,4 +32,4 @@
|
|||
$: schema = linkedTable?.schema
|
||||
</script>
|
||||
|
||||
<FilterEditor on:change {...$$props} {schema} />
|
||||
<FilterEditor on:change {...$$props} {schema} on:drawerHide on:drawerShow />
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
$goto("../portal")
|
||||
} catch (error) {
|
||||
submitted = false
|
||||
notifications.error("Failed to create admin user")
|
||||
notifications.error(error.message || "Failed to create admin user")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
}
|
||||
} catch (err) {
|
||||
submitted = false
|
||||
notifications.error("Unable to reset password")
|
||||
notifications.error(err.message || "Unable to reset password")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ build/
|
|||
docker-error.log
|
||||
envoy.yaml
|
||||
*.tar.gz
|
||||
prebuilds/
|
||||
dist/
|
||||
budibase-automation/
|
||||
budibase-component/
|
||||
|
|
|
@ -9,26 +9,11 @@
|
|||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"prebuild": "rm -rf prebuilds 2> /dev/null && cp -r ../../node_modules/leveldown/prebuilds prebuilds",
|
||||
"rename": "renamer --find .node --replace .fake 'prebuilds/**'",
|
||||
"tsc": "node ../../scripts/build.js",
|
||||
"pkg": "pkg . --out-path build --no-bytecode --public --public-packages \"*\" -C GZip",
|
||||
"build": "yarn prebuild && yarn rename && yarn tsc && yarn pkg && yarn postbuild",
|
||||
"build": "yarn tsc",
|
||||
"check:types": "tsc -p tsconfig.json --noEmit --paths null",
|
||||
"postbuild": "rm -rf prebuilds 2> /dev/null",
|
||||
"start": "ts-node ./src/index.ts"
|
||||
},
|
||||
"pkg": {
|
||||
"targets": [
|
||||
"node18-linux",
|
||||
"node18-win",
|
||||
"node18-macos"
|
||||
],
|
||||
"assets": [
|
||||
"prebuilds/**/*"
|
||||
],
|
||||
"outputPath": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "0.0.0",
|
||||
"@budibase/string-templates": "0.0.0",
|
||||
|
@ -43,7 +28,6 @@
|
|||
"inquirer": "8.0.0",
|
||||
"lookpath": "1.1.0",
|
||||
"node-fetch": "2.6.7",
|
||||
"pkg": "5.8.0",
|
||||
"posthog-node": "1.3.0",
|
||||
"pouchdb": "7.3.0",
|
||||
"pouchdb-replication-stream": "1.2.9",
|
||||
|
@ -55,7 +39,6 @@
|
|||
"@types/jest": "29.5.5",
|
||||
"@types/node-fetch": "2.6.4",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"renamer": "^4.0.0",
|
||||
"ts-node": "10.8.1",
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#!/usr/bin/env node
|
||||
process.env.DISABLE_PINO_LOGGER = "1"
|
||||
import "./prebuilds"
|
||||
import "./environment"
|
||||
import { getCommands } from "./options"
|
||||
import { Command } from "commander"
|
||||
import { getHelpDescription } from "./utils"
|
||||
import { getHelpDescription, error } from "./utils"
|
||||
import { version } from "../package.json"
|
||||
|
||||
// add hosting config
|
||||
|
@ -21,6 +20,23 @@ async function init() {
|
|||
await program.parseAsync(process.argv)
|
||||
}
|
||||
|
||||
const events = ["exit", "SIGINT", "SIGUSR1", "SIGUSR2", "uncaughtException"]
|
||||
events.forEach(event => {
|
||||
process.on(event, (evt?: number) => {
|
||||
if (evt && !isNaN(evt)) {
|
||||
return
|
||||
}
|
||||
if (evt) {
|
||||
console.error(
|
||||
error(
|
||||
"Failed to run CLI command - please report with the following message:"
|
||||
)
|
||||
)
|
||||
console.error(error(evt))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
init().catch(err => {
|
||||
console.error(`Unexpected error - `, err)
|
||||
})
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
import os from "os"
|
||||
import { join } from "path"
|
||||
import fs from "fs"
|
||||
import { error } from "./utils"
|
||||
|
||||
const PREBUILDS = "prebuilds"
|
||||
const ARCH = `${os.platform()}-${os.arch()}`
|
||||
const PREBUILD_DIR = join(process.execPath, "..", "cli", PREBUILDS, ARCH)
|
||||
|
||||
// running as built CLI pkg bundle
|
||||
if (!process.argv[0].includes("node")) {
|
||||
checkForBinaries()
|
||||
}
|
||||
|
||||
function localPrebuildPath() {
|
||||
return join(process.execPath, "..", PREBUILDS)
|
||||
}
|
||||
|
||||
function checkForBinaries() {
|
||||
const readDir = join(__filename, "..", "..", "..", "cli", PREBUILDS, ARCH)
|
||||
if (fs.existsSync(PREBUILD_DIR) || !fs.existsSync(readDir)) {
|
||||
return
|
||||
}
|
||||
const natives = fs.readdirSync(readDir)
|
||||
if (fs.existsSync(readDir)) {
|
||||
const writePath = join(localPrebuildPath(), ARCH)
|
||||
fs.mkdirSync(writePath, { recursive: true })
|
||||
for (let native of natives) {
|
||||
const filename = `${native.split(".fake")[0]}.node`
|
||||
fs.cpSync(join(readDir, native), join(writePath, filename))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup(evt?: number) {
|
||||
// cleanup prebuilds first
|
||||
const path = localPrebuildPath()
|
||||
if (fs.existsSync(path)) {
|
||||
fs.rmSync(path, { recursive: true })
|
||||
}
|
||||
if (evt && !isNaN(evt)) {
|
||||
return
|
||||
}
|
||||
if (evt) {
|
||||
console.error(
|
||||
error(
|
||||
"Failed to run CLI command - please report with the following message:"
|
||||
)
|
||||
)
|
||||
console.error(error(evt))
|
||||
}
|
||||
}
|
||||
|
||||
const events = ["exit", "SIGINT", "SIGUSR1", "SIGUSR2", "uncaughtException"]
|
||||
events.forEach(event => {
|
||||
process.on(event, cleanup)
|
||||
})
|
|
@ -1 +1 @@
|
|||
Subproject commit 992486c10044a7495496b97bdf5f454d4020bfba
|
||||
Subproject commit dc2b1b22e7f9bac705746bf1fb72c817db043fa3
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18-slim
|
||||
FROM node:20-slim
|
||||
|
||||
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check="scripts/watchtower-hooks/pre-check.sh"
|
||||
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="scripts/watchtower-hooks/pre-update.sh"
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
"lodash": "4.17.21",
|
||||
"memorystream": "0.3.1",
|
||||
"mongodb": "5.7",
|
||||
"mssql": "9.1.1",
|
||||
"mssql": "10.0.1",
|
||||
"mysql2": "3.5.2",
|
||||
"node-fetch": "2.6.7",
|
||||
"object-sizeof": "2.6.1",
|
||||
|
@ -121,8 +121,7 @@
|
|||
"@types/koa": "2.13.4",
|
||||
"@types/koa__router": "8.0.8",
|
||||
"@types/lodash": "4.14.200",
|
||||
"@types/mssql": "8.1.2",
|
||||
"@types/node": "18.17.0",
|
||||
"@types/mssql": "9.1.4",
|
||||
"@types/node-fetch": "2.6.4",
|
||||
"@types/oracledb": "5.2.2",
|
||||
"@types/pg": "8.6.6",
|
||||
|
|
|
@ -48,6 +48,7 @@ async function init() {
|
|||
HTTP_MIGRATIONS: "0",
|
||||
HTTP_LOGGING: "0",
|
||||
VERSION: "0.0.0+local",
|
||||
PASSWORD_MIN_LENGTH: "1",
|
||||
}
|
||||
|
||||
config = { ...config, ...existingConfig }
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"devDependencies": {
|
||||
"@budibase/nano": "10.1.4",
|
||||
"@types/koa": "2.13.4",
|
||||
"@types/node": "18.17.0",
|
||||
"@types/pouchdb": "6.4.0",
|
||||
"@types/redlock": "4.0.3",
|
||||
"rimraf": "3.0.2",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:18-alpine
|
||||
FROM node:20-alpine
|
||||
|
||||
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check="scripts/watchtower-hooks/pre-check.sh"
|
||||
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="scripts/watchtower-hooks/pre-update.sh"
|
||||
|
|
|
@ -79,7 +79,6 @@
|
|||
"@types/koa": "2.13.4",
|
||||
"@types/koa__router": "8.0.8",
|
||||
"@types/lodash": "4.14.200",
|
||||
"@types/node": "18.17.0",
|
||||
"@types/node-fetch": "2.6.4",
|
||||
"@types/server-destroy": "1.0.1",
|
||||
"@types/supertest": "2.0.14",
|
||||
|
|
|
@ -30,6 +30,7 @@ async function init() {
|
|||
ENABLE_EMAIL_TEST_MODE: "1",
|
||||
HTTP_LOGGING: "0",
|
||||
VERSION: "0.0.0+local",
|
||||
PASSWORD_MIN_LENGTH: "1",
|
||||
}
|
||||
|
||||
config = { ...config, ...existingConfig }
|
||||
|
|
|
@ -122,10 +122,10 @@ export const resetUpdate = async (ctx: Ctx<PasswordResetUpdateRequest>) => {
|
|||
ctx.body = {
|
||||
message: "password reset successfully.",
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
console.warn(err)
|
||||
// hide any details of the error for security
|
||||
ctx.throw(400, "Cannot reset password.")
|
||||
ctx.throw(400, err.message || "Cannot reset password.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ describe("/api/global/auth", () => {
|
|||
)
|
||||
|
||||
expect(res.body).toEqual({
|
||||
message: "Cannot reset password.",
|
||||
message: "Password change is disabled for this user",
|
||||
status: 400,
|
||||
})
|
||||
}
|
||||
|
@ -261,8 +261,12 @@ describe("/api/global/auth", () => {
|
|||
)
|
||||
|
||||
// convert to account owner now that password has been requested
|
||||
const account = structures.accounts.ssoAccount() as CloudAccount
|
||||
mocks.accounts.getAccount.mockReturnValueOnce(
|
||||
const account: CloudAccount = {
|
||||
...structures.accounts.ssoAccount(),
|
||||
budibaseUserId: "budibaseUserId",
|
||||
email: user.email,
|
||||
}
|
||||
mocks.accounts.getAccountByTenantId.mockReturnValueOnce(
|
||||
Promise.resolve(account)
|
||||
)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class TestConfiguration {
|
|||
tenantId: string
|
||||
user?: User
|
||||
apiKey?: string
|
||||
userPassword = "test"
|
||||
userPassword = "password"
|
||||
|
||||
constructor(opts: { openServer: boolean } = { openServer: true }) {
|
||||
// default to cloud hosting
|
||||
|
|
|
@ -101,7 +101,7 @@ export class UserAPI extends TestAPI {
|
|||
if (!request) {
|
||||
request = {
|
||||
email: structures.email(),
|
||||
password: generator.string(),
|
||||
password: generator.string({ length: 8 }),
|
||||
tenantId: structures.tenant.id(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue