diff --git a/packages/server/src/middleware/authenticated.js b/packages/server/src/middleware/authenticated.js index 659baa8f6c..32ed3f63d0 100644 --- a/packages/server/src/middleware/authenticated.js +++ b/packages/server/src/middleware/authenticated.js @@ -31,6 +31,7 @@ module.exports = async (ctx, next) => { token = ctx.cookies.get(getCookieName()) authType = AuthTypes.BUILDER } + if (!token && appId) { token = ctx.cookies.get(getCookieName(appId)) authType = AuthTypes.APP @@ -58,6 +59,7 @@ module.exports = async (ctx, next) => { role: await getRole(appId, jwtPayload.roleId), } } catch (err) { + console.log(err) if (authType === AuthTypes.BUILDER) { clearCookie(ctx) ctx.status = 200 diff --git a/packages/server/src/middleware/tests/__snapshots__/authenticated.spec.js.snap b/packages/server/src/middleware/tests/__snapshots__/authenticated.spec.js.snap new file mode 100644 index 0000000000..1583ecb51f --- /dev/null +++ b/packages/server/src/middleware/tests/__snapshots__/authenticated.spec.js.snap @@ -0,0 +1,28 @@ +// 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", + "appId": "budibase:app:local", + "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", + "appId": "budibase:builder:local", + "role": Role { + "_id": "BUILDER", + "name": "Builder", + "permissionId": "admin", + }, + "roleId": "BUILDER", +} +`; diff --git a/packages/server/src/middleware/tests/authenticated.spec.js b/packages/server/src/middleware/tests/authenticated.spec.js index 799fbaf41b..bb124d2f4a 100644 --- a/packages/server/src/middleware/tests/authenticated.spec.js +++ b/packages/server/src/middleware/tests/authenticated.spec.js @@ -1,10 +1,13 @@ 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: {}, request: {}, cookies: { @@ -16,7 +19,8 @@ class TestConfiguration { path: "", request: { headers: {} - } + }, + throw: jest.fn() } this.next = jest.fn() } @@ -28,6 +32,10 @@ class TestConfiguration { executeMiddleware() { return this.middleware(this.ctx, this.next) } + + afterEach() { + jest.resetAllMocks() + } } describe("Authenticated middleware", () => { @@ -37,6 +45,10 @@ describe("Authenticated middleware", () => { config = new TestConfiguration() }) + afterEach(() => { + config.afterEach() + }) + it("calls next() when on the builder path", async () => { config.ctx.path = "/_builder" @@ -47,10 +59,10 @@ describe("Authenticated middleware", () => { it("sets a new cookie when the current cookie does not match the app id from context", async () => { const appId = "app_123" - config.ctx.cookies.get.mockImplementationOnce(() => "cookieAppId") config.setHeaders({ "x-budibase-app-id": appId }) + config.ctx.cookies.get.mockImplementation(() => "cookieAppId") await config.executeMiddleware() @@ -62,37 +74,53 @@ describe("Authenticated middleware", () => { }) - fit("sets a BUILDER auth type when the x-budibase-type header is not 'client'", async () => { - config.ctx.cookies.get.mockImplementationOnce(() => `budibase:builder:local`) + 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("assigns an APP auth type when the user is not in the builder", async () => { + 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.mockImplementationOnce(() => `budibase:builder:local`) + 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() - }) - - it("verifies the users JWT token and sets the user information in context when successful", async () => { - config.executeMiddleware() - expect() + 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.executeMiddleware() - expect() + 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") }) }) \ No newline at end of file