mirror of https://github.com/Budibase/budibase.git
15 changed files with 201 additions and 176 deletions
@ -1 +1 @@ |
|||
export { LoginForm } from "./LoginForm.svelte" |
|||
export { LoginForm } from "./LoginForm.svelte" |
|||
|
|||
@ -0,0 +1,28 @@ |
|||
<script> |
|||
import { TextButton as Button, Modal } from "@budibase/bbui" |
|||
import { auth } from "stores/backend" |
|||
</script> |
|||
|
|||
<div> |
|||
<Button text on:click={auth.logout}> |
|||
<i class="ri-logout-box-line" /> |
|||
<p>Logout</p> |
|||
</Button> |
|||
</div> |
|||
|
|||
<style> |
|||
div i { |
|||
font-size: 26px; |
|||
color: var(--grey-7); |
|||
margin-left: 12px; |
|||
margin-top: 10px; |
|||
} |
|||
|
|||
div p { |
|||
font-family: var(--font-sans); |
|||
font-size: var(--font-size-s); |
|||
color: var(--ink); |
|||
font-weight: 400; |
|||
margin: 0 0 0 12px; |
|||
} |
|||
</style> |
|||
@ -1,26 +0,0 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`Authenticated middleware sets the correct APP auth type information when the user is not in the builder 1`] = ` |
|||
Object { |
|||
"apiKey": "1234", |
|||
"role": Role { |
|||
"_id": "ADMIN", |
|||
"inherits": "POWER", |
|||
"name": "Admin", |
|||
"permissionId": "admin", |
|||
}, |
|||
"roleId": "ADMIN", |
|||
} |
|||
`; |
|||
|
|||
exports[`Authenticated middleware sets the correct BUILDER auth type information when the x-budibase-type header is not 'client' 1`] = ` |
|||
Object { |
|||
"apiKey": "1234", |
|||
"role": Role { |
|||
"_id": "BUILDER", |
|||
"name": "Builder", |
|||
"permissionId": "admin", |
|||
}, |
|||
"roleId": "BUILDER", |
|||
} |
|||
`; |
|||
@ -1,124 +0,0 @@ |
|||
const { AuthTypes } = require("../../constants") |
|||
const authenticatedMiddleware = require("../authenticated") |
|||
const jwt = require("jsonwebtoken") |
|||
jest.mock("jsonwebtoken") |
|||
|
|||
class TestConfiguration { |
|||
constructor(middleware) { |
|||
this.middleware = authenticatedMiddleware |
|||
this.ctx = { |
|||
config: {}, |
|||
auth: {}, |
|||
cookies: { |
|||
set: jest.fn(), |
|||
get: jest.fn(), |
|||
}, |
|||
headers: {}, |
|||
params: {}, |
|||
path: "", |
|||
request: { |
|||
headers: {}, |
|||
}, |
|||
throw: jest.fn(), |
|||
} |
|||
this.next = jest.fn() |
|||
} |
|||
|
|||
setHeaders(headers) { |
|||
this.ctx.headers = headers |
|||
} |
|||
|
|||
executeMiddleware() { |
|||
return this.middleware(this.ctx, this.next) |
|||
} |
|||
|
|||
afterEach() { |
|||
jest.resetAllMocks() |
|||
} |
|||
} |
|||
|
|||
describe("Authenticated middleware", () => { |
|||
let config |
|||
|
|||
beforeEach(() => { |
|||
config = new TestConfiguration() |
|||
}) |
|||
|
|||
afterEach(() => { |
|||
config.afterEach() |
|||
}) |
|||
|
|||
it("calls next() when on the builder path", async () => { |
|||
config.ctx.path = "/builder" |
|||
|
|||
await config.executeMiddleware() |
|||
|
|||
expect(config.next).toHaveBeenCalled() |
|||
}) |
|||
|
|||
it("sets a new cookie when the current cookie does not match the app id from context", async () => { |
|||
const appId = "app_123" |
|||
config.setHeaders({ |
|||
"x-budibase-app-id": appId, |
|||
}) |
|||
config.ctx.cookies.get.mockImplementation(() => "cookieAppId") |
|||
|
|||
await config.executeMiddleware() |
|||
|
|||
expect(config.ctx.cookies.set).toHaveBeenCalledWith( |
|||
"budibase:currentapp", |
|||
appId, |
|||
expect.any(Object) |
|||
) |
|||
}) |
|||
|
|||
it("sets the correct BUILDER auth type information when the x-budibase-type header is not 'client'", async () => { |
|||
config.ctx.cookies.get.mockImplementation(() => "budibase:builder:local") |
|||
jwt.verify.mockImplementationOnce(() => ({ |
|||
apiKey: "1234", |
|||
roleId: "BUILDER", |
|||
})) |
|||
|
|||
await config.executeMiddleware() |
|||
|
|||
expect(config.ctx.auth.authenticated).toEqual(AuthTypes.BUILDER) |
|||
expect(config.ctx.user).toMatchSnapshot() |
|||
}) |
|||
|
|||
it("sets the correct APP auth type information when the user is not in the builder", async () => { |
|||
config.setHeaders({ |
|||
"x-budibase-type": "client", |
|||
}) |
|||
config.ctx.cookies.get.mockImplementation(() => `budibase:app:local`) |
|||
jwt.verify.mockImplementationOnce(() => ({ |
|||
apiKey: "1234", |
|||
roleId: "ADMIN", |
|||
})) |
|||
|
|||
await config.executeMiddleware() |
|||
|
|||
expect(config.ctx.auth.authenticated).toEqual(AuthTypes.APP) |
|||
expect(config.ctx.user).toMatchSnapshot() |
|||
}) |
|||
|
|||
it("marks the user as unauthenticated when a token cannot be determined from the users cookie", async () => { |
|||
config.executeMiddleware() |
|||
expect(config.ctx.auth.authenticated).toBe(false) |
|||
expect(config.ctx.user.role).toEqual({ |
|||
_id: "PUBLIC", |
|||
name: "Public", |
|||
permissionId: "public", |
|||
}) |
|||
}) |
|||
|
|||
it("clears the cookie when there is an error authenticating in the builder", async () => { |
|||
config.ctx.cookies.get.mockImplementation(() => "budibase:builder:local") |
|||
jwt.verify.mockImplementationOnce(() => { |
|||
throw new Error() |
|||
}) |
|||
|
|||
await config.executeMiddleware() |
|||
|
|||
expect(config.ctx.cookies.set).toBeCalledWith("budibase:builder:local") |
|||
}) |
|||
}) |
|||
@ -0,0 +1,148 @@ |
|||
mockAuthWithNoCookie() |
|||
mockWorker() |
|||
|
|||
function mockWorker() { |
|||
jest.mock("../../utilities/workerRequests", () => ({ |
|||
getGlobalUsers: () => { |
|||
return { |
|||
email: "test@test.com", |
|||
roles: { |
|||
"app_test": "BASIC", |
|||
} |
|||
} |
|||
} |
|||
})) |
|||
} |
|||
|
|||
function mockReset() { |
|||
jest.resetModules() |
|||
mockWorker() |
|||
} |
|||
|
|||
function mockAuthWithNoCookie() { |
|||
jest.resetModules() |
|||
mockWorker() |
|||
jest.mock("@budibase/auth", () => ({ |
|||
getAppId: jest.fn(), |
|||
setCookie: jest.fn(), |
|||
getCookie: jest.fn(), |
|||
Cookies: {}, |
|||
})) |
|||
} |
|||
|
|||
function mockAuthWithCookie() { |
|||
jest.resetModules() |
|||
mockWorker() |
|||
jest.mock("@budibase/auth", () => ({ |
|||
getAppId: () => { |
|||
return "app_test" |
|||
}, |
|||
setCookie: jest.fn(), |
|||
getCookie: () => ({ appId: "app_different", roleId: "PUBLIC" }), |
|||
Cookies: { |
|||
Auth: "auth", |
|||
CurrentApp: "currentapp", |
|||
} |
|||
})) |
|||
} |
|||
|
|||
class TestConfiguration { |
|||
constructor() { |
|||
this.next = jest.fn() |
|||
this.throw = jest.fn() |
|||
|
|||
this.ctx = { |
|||
next: this.next, |
|||
throw: this.throw |
|||
} |
|||
} |
|||
|
|||
setUser() { |
|||
this.ctx.user = { |
|||
email: "test@test.com", |
|||
} |
|||
} |
|||
|
|||
executeMiddleware() { |
|||
// import as late as possible for mocks
|
|||
const currentAppMiddleware = require("../currentapp") |
|||
return currentAppMiddleware(this.ctx, this.next) |
|||
} |
|||
} |
|||
|
|||
describe("Current app middleware", () => { |
|||
let config |
|||
|
|||
beforeEach(() => { |
|||
config = new TestConfiguration() |
|||
}) |
|||
|
|||
afterEach(() => { |
|||
jest.clearAllMocks() |
|||
}) |
|||
|
|||
describe("test having no cookies or app ID", () => { |
|||
it("should be able to proceed with nothing setup", async () => { |
|||
await config.executeMiddleware() |
|||
expect(config.next).toHaveBeenCalled() |
|||
}) |
|||
}) |
|||
|
|||
describe("check get public for app when not logged in", () => { |
|||
it("should be able to proceed with no login, but cookies configured", async () => { |
|||
mockAuthWithCookie() |
|||
await config.executeMiddleware() |
|||
expect(config.ctx.roleId).toEqual("PUBLIC") |
|||
expect(config.ctx.appId).toEqual("app_test") |
|||
expect(config.next).toHaveBeenCalled() |
|||
}) |
|||
}) |
|||
|
|||
describe("check functionality when logged in", () => { |
|||
async function checkExpected(setCookie) { |
|||
config.setUser() |
|||
await config.executeMiddleware() |
|||
const cookieFn = require("@budibase/auth").setCookie |
|||
if (setCookie) { |
|||
expect(cookieFn).toHaveBeenCalled() |
|||
} else { |
|||
expect(cookieFn).not.toHaveBeenCalled() |
|||
} |
|||
expect(config.ctx.roleId).toEqual("BASIC") |
|||
expect(config.ctx.appId).toEqual("app_test") |
|||
expect(config.next).toHaveBeenCalled() |
|||
} |
|||
|
|||
it("should be able to setup an app token when cookie not setup", async () => { |
|||
mockAuthWithCookie() |
|||
await checkExpected(true) |
|||
}) |
|||
|
|||
it("should perform correct when no cookie exists", async () => { |
|||
mockReset() |
|||
jest.mock("@budibase/auth", () => ({ |
|||
getAppId: () => { |
|||
return "app_test" |
|||
}, |
|||
setCookie: jest.fn(), |
|||
getCookie: jest.fn(), |
|||
Cookies: {}, |
|||
})) |
|||
await checkExpected(true) |
|||
}) |
|||
|
|||
it("lastly check what occurs when cookie doesn't need updated", async () => { |
|||
mockReset() |
|||
jest.mock("@budibase/auth", () => ({ |
|||
getAppId: () => { |
|||
return "app_test" |
|||
}, |
|||
setCookie: jest.fn(), |
|||
getCookie: () => ({ appId: "app_test", roleId: "BASIC" }), |
|||
Cookies: {}, |
|||
})) |
|||
await checkExpected(false) |
|||
}) |
|||
}) |
|||
|
|||
}) |
|||
@ -1,11 +0,0 @@ |
|||
const env = require("../environment") |
|||
|
|||
module.exports = async (ctx, next) => { |
|||
const selfHostKey = |
|||
ctx.request.headers["x-budibase-auth"] || ctx.request.body.selfHostKey |
|||
if (!selfHostKey || env.SELF_HOST_KEY !== selfHostKey) { |
|||
ctx.throw(401, "Request unauthorised") |
|||
} else { |
|||
await next() |
|||
} |
|||
} |
|||
Loading…
Reference in new issue