Merge branch 'develop' into fix/shared-core-dev
This commit is contained in:
commit
7bb1db6c1d
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.9.40-alpha.1",
|
||||
"version": "2.9.40-alpha.3",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -22,6 +22,8 @@ export enum Header {
|
|||
TENANT_ID = "x-budibase-tenant-id",
|
||||
VERIFICATION_CODE = "x-budibase-verification-code",
|
||||
RETURN_VERIFICATION_CODE = "x-budibase-return-verification-code",
|
||||
RESET_PASSWORD_CODE = "x-budibase-reset-password-code",
|
||||
RETURN_RESET_PASSWORD_CODE = "x-budibase-return-reset-password-code",
|
||||
TOKEN = "x-budibase-token",
|
||||
CSRF_TOKEN = "x-csrf-token",
|
||||
CORRELATION_ID = "x-budibase-correlation-id",
|
||||
|
|
|
@ -102,7 +102,7 @@ class Orchestrator {
|
|||
}
|
||||
|
||||
cleanupTriggerOutputs(stepId: string, triggerOutput: TriggerOutput) {
|
||||
if (stepId === CRON_STEP_ID) {
|
||||
if (stepId === CRON_STEP_ID && !triggerOutput.timestamp) {
|
||||
triggerOutput.timestamp = Date.now()
|
||||
}
|
||||
return triggerOutput
|
||||
|
|
|
@ -114,4 +114,10 @@ export default class AccountAPI extends BaseAPI {
|
|||
})
|
||||
}, opts)
|
||||
}
|
||||
|
||||
async self(opts: APIRequestOpts = { status: 200 }) {
|
||||
return this.doRequest(() => {
|
||||
return this.client.get(`/api/auth/self`)
|
||||
}, opts)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Response } from "node-fetch"
|
|||
import AccountInternalAPIClient from "../AccountInternalAPIClient"
|
||||
import { APIRequestOpts } from "../../../types"
|
||||
import BaseAPI from "./BaseAPI"
|
||||
import { Header } from "@budibase/backend-core"
|
||||
|
||||
export default class AuthAPI extends BaseAPI {
|
||||
client: AccountInternalAPIClient
|
||||
|
@ -27,4 +28,41 @@ export default class AuthAPI extends BaseAPI {
|
|||
return [res, cookie]
|
||||
}, opts)
|
||||
}
|
||||
|
||||
async logout(opts: APIRequestOpts = { status: 200 }) {
|
||||
return this.doRequest(() => {
|
||||
return this.client.post(`/api/auth/logout`)
|
||||
}, opts)
|
||||
}
|
||||
|
||||
async resetPassword(
|
||||
email: string,
|
||||
opts: APIRequestOpts = { status: 200 }
|
||||
): Promise<[Response, string]> {
|
||||
return this.doRequest(async () => {
|
||||
const [response] = await this.client.post(`/api/auth/reset`, {
|
||||
body: { email },
|
||||
headers: {
|
||||
[Header.RETURN_RESET_PASSWORD_CODE]: "1",
|
||||
},
|
||||
})
|
||||
const code = response.headers.get(Header.RESET_PASSWORD_CODE)
|
||||
return [response, code]
|
||||
}, opts)
|
||||
}
|
||||
|
||||
async resetPasswordUpdate(
|
||||
resetCode: string,
|
||||
password: string,
|
||||
opts: APIRequestOpts = { status: 200 }
|
||||
) {
|
||||
return this.doRequest(() => {
|
||||
return this.client.post(`/api/auth/reset/update`, {
|
||||
body: {
|
||||
resetCode: resetCode,
|
||||
password: password,
|
||||
},
|
||||
})
|
||||
}, opts)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import TestConfiguration from "../../config/TestConfiguration"
|
||||
import * as fixtures from "../../fixtures"
|
||||
import { generator } from "../../../shared"
|
||||
import { Hosting } from "@budibase/types"
|
||||
|
||||
describe("Account Internal Operations", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
@ -20,7 +21,9 @@ describe("Account Internal Operations", () => {
|
|||
|
||||
// Create new account
|
||||
const [_, account] = await config.api.accounts.create({
|
||||
...fixtures.accounts.generateAccount(),
|
||||
...fixtures.accounts.generateAccount({
|
||||
hosting: Hosting.CLOUD,
|
||||
}),
|
||||
})
|
||||
|
||||
// New account can be deleted
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import TestConfiguration from "../../config/TestConfiguration"
|
||||
import * as fixtures from "../../fixtures"
|
||||
import { generator } from "../../../shared"
|
||||
import { Hosting } from "@budibase/types"
|
||||
|
||||
describe("Accounts", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
@ -16,7 +17,9 @@ describe("Accounts", () => {
|
|||
it("performs signup and deletion flow", async () => {
|
||||
await config.doInNewState(async () => {
|
||||
// Create account
|
||||
const createAccountRequest = fixtures.accounts.generateAccount()
|
||||
const createAccountRequest = fixtures.accounts.generateAccount({
|
||||
hosting: Hosting.CLOUD,
|
||||
})
|
||||
const email = createAccountRequest.email
|
||||
const tenantId = createAccountRequest.tenantId
|
||||
|
||||
|
@ -42,9 +45,16 @@ describe("Accounts", () => {
|
|||
// Send the verification request
|
||||
await config.accountsApi.accounts.verifyAccount(code!)
|
||||
|
||||
// Verify self response is unauthorized
|
||||
await config.api.accounts.self({ status: 403 })
|
||||
|
||||
// Can now log in to the account
|
||||
await config.loginAsAccount(createAccountRequest)
|
||||
|
||||
// Verify self response matches account
|
||||
const [selfRes, selfBody] = await config.api.accounts.self()
|
||||
expect(selfBody.email).toBe(email)
|
||||
|
||||
// Delete account
|
||||
await config.api.accounts.deleteCurrentAccount()
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import TestConfiguration from "../../config/TestConfiguration"
|
||||
import * as fixtures from "../../fixtures"
|
||||
import { generator } from "../../../shared"
|
||||
import { Hosting } from "@budibase/types"
|
||||
|
||||
describe("Password Management", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
||||
beforeAll(async () => {
|
||||
await config.beforeAll()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await config.afterAll()
|
||||
})
|
||||
|
||||
it("performs password reset flow", async () => {
|
||||
// Create account
|
||||
const createAccountRequest = fixtures.accounts.generateAccount({
|
||||
hosting: Hosting.CLOUD,
|
||||
})
|
||||
await config.api.accounts.create(createAccountRequest, { autoVerify: true })
|
||||
|
||||
// Request password reset to get code
|
||||
const [_, code] = await config.api.auth.resetPassword(
|
||||
createAccountRequest.email
|
||||
)
|
||||
|
||||
// Change password using code
|
||||
const password = generator.string()
|
||||
await config.api.auth.resetPasswordUpdate(code, password)
|
||||
|
||||
// Login using the new password
|
||||
await config.api.auth.login(createAccountRequest.email, password)
|
||||
|
||||
// Logout of account
|
||||
await config.api.auth.logout()
|
||||
|
||||
// Cannot log in using old password
|
||||
await config.api.auth.login(
|
||||
createAccountRequest.email,
|
||||
createAccountRequest.password,
|
||||
{ status: 403 }
|
||||
)
|
||||
})
|
||||
})
|
20
yarn.lock
20
yarn.lock
|
@ -15278,10 +15278,10 @@ jest-snapshot@^29.6.2:
|
|||
pretty-format "^29.6.2"
|
||||
semver "^7.5.3"
|
||||
|
||||
jest-util@^29.0.0:
|
||||
version "29.6.1"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.1.tgz#c9e29a87a6edbf1e39e6dee2b4689b8a146679cb"
|
||||
integrity sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==
|
||||
jest-util@^29.0.0, jest-util@^29.6.2:
|
||||
version "29.6.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d"
|
||||
integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==
|
||||
dependencies:
|
||||
"@jest/types" "^29.6.1"
|
||||
"@types/node" "*"
|
||||
|
@ -15302,18 +15302,6 @@ jest-util@^29.4.3:
|
|||
graceful-fs "^4.2.9"
|
||||
picomatch "^2.2.3"
|
||||
|
||||
jest-util@^29.6.2:
|
||||
version "29.6.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d"
|
||||
integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==
|
||||
dependencies:
|
||||
"@jest/types" "^29.6.1"
|
||||
"@types/node" "*"
|
||||
chalk "^4.0.0"
|
||||
ci-info "^3.2.0"
|
||||
graceful-fs "^4.2.9"
|
||||
picomatch "^2.2.3"
|
||||
|
||||
jest-validate@^29.6.2:
|
||||
version "29.6.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082"
|
||||
|
|
Loading…
Reference in New Issue