From 4974ba81d153c381446bc54438195960690be588 Mon Sep 17 00:00:00 2001 From: Romain Lenzotti Date: Sun, 21 Feb 2021 11:47:49 +0100 Subject: [PATCH] fix(react-formio): Fix user authentication --- packages/react-formio/.eslintrc | 1 + .../src/stores/auth/auth.actions.ts | 112 +------ .../src/stores/auth/auth.constant.ts | 1 + .../src/stores/auth/getAccess.action.spec.ts | 299 ++++++++++++++++++ .../src/stores/auth/getAccess.action.ts | 61 ++++ .../stores/auth/getProjectAccess.action.ts | 24 ++ .../react-formio/src/stores/auth/index.ts | 6 + .../src/stores/auth/initAuth.action.spec.ts | 55 ++++ .../src/stores/auth/initAuth.action.ts | 30 ++ .../src/stores/auth/logout.action.spec.ts | 23 ++ .../src/stores/auth/logout.action.ts | 8 + .../src/stores/auth/setUser.action.spec.ts | 24 ++ .../src/stores/auth/setUser.action.ts | 8 + 13 files changed, 544 insertions(+), 108 deletions(-) create mode 100644 packages/react-formio/src/stores/auth/auth.constant.ts create mode 100644 packages/react-formio/src/stores/auth/getAccess.action.spec.ts create mode 100644 packages/react-formio/src/stores/auth/getAccess.action.ts create mode 100644 packages/react-formio/src/stores/auth/getProjectAccess.action.ts create mode 100644 packages/react-formio/src/stores/auth/initAuth.action.spec.ts create mode 100644 packages/react-formio/src/stores/auth/initAuth.action.ts create mode 100644 packages/react-formio/src/stores/auth/logout.action.spec.ts create mode 100644 packages/react-formio/src/stores/auth/logout.action.ts create mode 100644 packages/react-formio/src/stores/auth/setUser.action.spec.ts create mode 100644 packages/react-formio/src/stores/auth/setUser.action.ts diff --git a/packages/react-formio/.eslintrc b/packages/react-formio/.eslintrc index 086a0d21..5aed000a 100644 --- a/packages/react-formio/.eslintrc +++ b/packages/react-formio/.eslintrc @@ -35,6 +35,7 @@ "no-unused-vars": "off", "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/camelcase": 0, "import/export": 0 } } diff --git a/packages/react-formio/src/stores/auth/auth.actions.ts b/packages/react-formio/src/stores/auth/auth.actions.ts index ca91a817..9c04e6c1 100755 --- a/packages/react-formio/src/stores/auth/auth.actions.ts +++ b/packages/react-formio/src/stores/auth/auth.actions.ts @@ -1,116 +1,12 @@ import { createAction } from "@tsed/redux-utils"; -import { Formio } from "formiojs"; -import noop from "lodash/noop"; - -const name = "auth"; +import { FormSchema, RoleSchema, Submission } from "../../interfaces"; export const requestUser = createAction(); -export const receiveUser = createAction<{ user: any }>(); +export const receiveUser = createAction<{ user: Submission }>(); export const failUser = createAction<{ error: Error }>(); export const logoutUser = createAction(); export const submissionAccessUser = createAction<{ submissionAccess: any }>(); export const formAccessUser = createAction<{ formAccess: any }>(); export const projectAccessUser = createAction<{ projectAccess: any }>(); -export const userRoles = createAction<{ roles: any[] }>(); -export const userForms = createAction<{ forms: any[] }>(); - -function transformSubmissionAccess(forms: any[]) { - return Object.values(forms).reduce( - (result, form) => ({ - ...result, - [form.name]: form.submissionAccess.reduce( - (formSubmissionAccess: any, access: any) => ({ - ...formSubmissionAccess, - [access.type]: access.roles - }), - {} - ) - }), - {} - ); -} - -function transformFormAccess(forms: any[]) { - return Object.values(forms).reduce( - (result, form) => ({ - ...result, - [form.name]: form.access.reduce( - (formAccess: any, access: any) => ({ - ...formAccess, - [access.type]: access.roles - }), - {} - ) - }), - {} - ); -} - -function transformProjectAccess(projectAccess: any) { - return projectAccess.reduce( - (result: any, access: any) => ({ - ...result, - [access.type]: access.roles - }), - {} - ); -} - -async function getAccess(dispatch: any) { - const projectUrl = Formio.getProjectUrl(); - - try { - const result = await Formio.makeStaticRequest(`${projectUrl}/access`); - - const submissionAccess = transformSubmissionAccess(result.forms); - const formAccess = transformFormAccess(result.forms); - - dispatch(submissionAccessUser(name, { submissionAccess })); - dispatch(formAccessUser(name, { formAccess })); - dispatch(userRoles(name, { roles: result.roles })); - dispatch(userForms(name, { forms: result.forms })); - } catch (err) {} -} - -async function getProjectAccess(dispatch: any) { - const projectUrl = Formio.getProjectUrl(); - - try { - const project = await Formio.makeStaticRequest(projectUrl); - const projectAccess = transformProjectAccess(project.access); - - dispatch(projectAccessUser(name, projectAccess)); - } catch (er) {} -} - -export const initAuth = (done = noop) => async (dispatch: any) => { - dispatch(requestUser(name)); - - try { - const [user] = await Promise.all([ - Formio.currentUser(), - getAccess(dispatch), - getProjectAccess(dispatch) - ]); - - if (user) { - dispatch(receiveUser(name, user)); - } else { - dispatch(logoutUser(name)); - } - } catch (error) { - dispatch(failUser(name, { error })); - } - - done(); -}; - -export const setUser = (user: any) => (dispatch: any) => { - Formio.setUser(user); - dispatch(receiveUser(name, { user })); -}; - -export const logout = () => (dispatch: any) => { - Formio.logout(); - dispatch(logoutUser(name)); -}; +export const userRoles = createAction<{ roles: Record }>(); +export const userForms = createAction<{ forms: Record }>(); diff --git a/packages/react-formio/src/stores/auth/auth.constant.ts b/packages/react-formio/src/stores/auth/auth.constant.ts new file mode 100644 index 00000000..a51bad85 --- /dev/null +++ b/packages/react-formio/src/stores/auth/auth.constant.ts @@ -0,0 +1 @@ +export const USER_AUTH = "auth"; diff --git a/packages/react-formio/src/stores/auth/getAccess.action.spec.ts b/packages/react-formio/src/stores/auth/getAccess.action.spec.ts new file mode 100644 index 00000000..a48a617c --- /dev/null +++ b/packages/react-formio/src/stores/auth/getAccess.action.spec.ts @@ -0,0 +1,299 @@ +import { Formio } from "formiojs"; +import { + formAccessUser, + submissionAccessUser, + userForms, + userRoles +} from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; +import { getAccess } from "./getAccess.action"; + +jest.mock("./auth.actions"); + +describe("getAccess()", () => { + beforeEach(() => { + jest.spyOn(Formio, "makeStaticRequest"); + jest.spyOn(Formio, "getProjectUrl"); + }); + afterEach(() => { + jest.resetAllMocks(); + }); + it("should get access", async () => { + const dispatch = jest.fn(); + const access = { + roles: { + administrator: { + _id: "6016dd751c62ca370d59f0b8", + default: false, + admin: true, + title: "Administrator" + }, + authenticated: { + _id: "6016dd751c62ca370d59f0b9", + default: false, + admin: false, + title: "Authenticated" + }, + anonymous: { + _id: "6016dd751c62ca370d59f0ba", + default: true, + admin: false, + title: "Anonymous" + } + }, + forms: { + user: { + _id: "6016e1fb4ce825382505947d", + title: "User", + name: "user", + path: "user", + access: [ + { + roles: [ + "6016dd751c62ca370d59f0ba", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0b8" + ], + type: "read_all" + } + ], + submissionAccess: [ + { roles: ["6016dd751c62ca370d59f0b8"], type: "create_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "read_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "update_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "delete_all" }, + { roles: [], type: "create_own" }, + { roles: [], type: "read_own" }, + { roles: [], type: "update_own" }, + { roles: [], type: "delete_own" } + ] + }, + admin: { + _id: "6016e1fb4ce825382505947e", + title: "Admin", + name: "admin", + path: "admin", + access: [ + { + roles: [ + "6016dd751c62ca370d59f0ba", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0b8" + ], + type: "read_all" + } + ], + submissionAccess: [ + { roles: ["6016dd751c62ca370d59f0b8"], type: "create_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "read_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "update_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "delete_all" }, + { roles: [], type: "create_own" }, + { roles: [], type: "read_own" }, + { roles: [], type: "update_own" }, + { roles: [], type: "delete_own" } + ] + }, + todo: { + _id: "6016e1fb4ce825382505947f", + title: "ToDo", + name: "todo", + path: "todo", + access: [ + { + roles: [ + "6016dd751c62ca370d59f0b8", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0ba" + ], + type: "read_all" + } + ], + submissionAccess: [ + { roles: [], type: "create_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "read_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "update_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "delete_all" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "create_own" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "read_own" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "update_own" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "delete_own" } + ] + } + } + }; + + (Formio.makeStaticRequest as any).mockResolvedValue(access); + + await getAccess(dispatch); + + expect(Formio.getProjectUrl).toHaveBeenCalledWith(); + expect(Formio.makeStaticRequest).toHaveBeenCalledWith( + "https://api.form.io/access" + ); + + expect(submissionAccessUser).toHaveBeenCalledWith(USER_AUTH, { + submissionAccess: { + admin: { + create_all: ["6016dd751c62ca370d59f0b8"], + create_own: [], + delete_all: ["6016dd751c62ca370d59f0b8"], + delete_own: [], + read_all: ["6016dd751c62ca370d59f0b8"], + read_own: [], + update_all: ["6016dd751c62ca370d59f0b8"], + update_own: [] + }, + todo: { + create_all: [], + create_own: ["6016dd751c62ca370d59f0b9"], + delete_all: ["6016dd751c62ca370d59f0b8"], + delete_own: ["6016dd751c62ca370d59f0b9"], + read_all: ["6016dd751c62ca370d59f0b8"], + read_own: ["6016dd751c62ca370d59f0b9"], + update_all: ["6016dd751c62ca370d59f0b8"], + update_own: ["6016dd751c62ca370d59f0b9"] + }, + user: { + create_all: ["6016dd751c62ca370d59f0b8"], + create_own: [], + delete_all: ["6016dd751c62ca370d59f0b8"], + delete_own: [], + read_all: ["6016dd751c62ca370d59f0b8"], + read_own: [], + update_all: ["6016dd751c62ca370d59f0b8"], + update_own: [] + } + } + }); + expect(formAccessUser).toHaveBeenCalledWith(USER_AUTH, { + formAccess: { + admin: { + read_all: [ + "6016dd751c62ca370d59f0ba", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0b8" + ] + }, + todo: { + read_all: [ + "6016dd751c62ca370d59f0b8", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0ba" + ] + }, + user: { + read_all: [ + "6016dd751c62ca370d59f0ba", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0b8" + ] + } + } + }); + expect(userRoles).toHaveBeenCalledWith(USER_AUTH, { + roles: { + administrator: { + _id: "6016dd751c62ca370d59f0b8", + admin: true, + default: false, + title: "Administrator" + }, + anonymous: { + _id: "6016dd751c62ca370d59f0ba", + admin: false, + default: true, + title: "Anonymous" + }, + authenticated: { + _id: "6016dd751c62ca370d59f0b9", + admin: false, + default: false, + title: "Authenticated" + } + } + }); + expect(userForms).toHaveBeenCalledWith(USER_AUTH, { + forms: { + admin: { + _id: "6016e1fb4ce825382505947e", + access: [ + { + roles: [ + "6016dd751c62ca370d59f0ba", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0b8" + ], + type: "read_all" + } + ], + name: "admin", + path: "admin", + submissionAccess: [ + { roles: ["6016dd751c62ca370d59f0b8"], type: "create_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "read_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "update_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "delete_all" }, + { roles: [], type: "create_own" }, + { roles: [], type: "read_own" }, + { roles: [], type: "update_own" }, + { roles: [], type: "delete_own" } + ], + title: "Admin" + }, + todo: { + _id: "6016e1fb4ce825382505947f", + access: [ + { + roles: [ + "6016dd751c62ca370d59f0b8", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0ba" + ], + type: "read_all" + } + ], + name: "todo", + path: "todo", + submissionAccess: [ + { roles: [], type: "create_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "read_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "update_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "delete_all" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "create_own" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "read_own" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "update_own" }, + { roles: ["6016dd751c62ca370d59f0b9"], type: "delete_own" } + ], + title: "ToDo" + }, + user: { + _id: "6016e1fb4ce825382505947d", + access: [ + { + roles: [ + "6016dd751c62ca370d59f0ba", + "6016dd751c62ca370d59f0b9", + "6016dd751c62ca370d59f0b8" + ], + type: "read_all" + } + ], + name: "user", + path: "user", + submissionAccess: [ + { roles: ["6016dd751c62ca370d59f0b8"], type: "create_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "read_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "update_all" }, + { roles: ["6016dd751c62ca370d59f0b8"], type: "delete_all" }, + { roles: [], type: "create_own" }, + { roles: [], type: "read_own" }, + { roles: [], type: "update_own" }, + { roles: [], type: "delete_own" } + ], + title: "User" + } + } + }); + }); +}); diff --git a/packages/react-formio/src/stores/auth/getAccess.action.ts b/packages/react-formio/src/stores/auth/getAccess.action.ts new file mode 100644 index 00000000..5be53d69 --- /dev/null +++ b/packages/react-formio/src/stores/auth/getAccess.action.ts @@ -0,0 +1,61 @@ +import { Formio } from "formiojs"; +import { RoleSchema } from "../../interfaces"; +import { FormSchema } from "../../interfaces/FormSchema"; +import { + formAccessUser, + submissionAccessUser, + userForms, + userRoles +} from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; + +function transformSubmissionAccess(forms: Record) { + return Object.values(forms).reduce( + (result, form) => ({ + ...result, + [form.name]: form.submissionAccess.reduce( + (formSubmissionAccess: any, access: any) => ({ + ...formSubmissionAccess, + [access.type]: access.roles + }), + {} + ) + }), + {} + ); +} + +function transformFormAccess(forms: Record) { + return Object.values(forms).reduce( + (result, form) => ({ + ...result, + [form.name]: form.access.reduce( + (formAccess: any, access: any) => ({ + ...formAccess, + [access.type]: access.roles + }), + {} + ) + }), + {} + ); +} + +export async function getAccess(dispatch: any) { + const projectUrl = Formio.getProjectUrl(); + + try { + const result: { + roles: Record; + forms: Record; + } = await Formio.makeStaticRequest(`${projectUrl}/access`); + + const submissionAccess = transformSubmissionAccess(result.forms); + const formAccess = transformFormAccess(result.forms); + + dispatch(submissionAccessUser(USER_AUTH, { submissionAccess })); + dispatch(formAccessUser(USER_AUTH, { formAccess })); + dispatch(userRoles(USER_AUTH, { roles: result.roles })); + dispatch(userForms(USER_AUTH, { forms: result.forms })); + } catch (err) {} +} diff --git a/packages/react-formio/src/stores/auth/getProjectAccess.action.ts b/packages/react-formio/src/stores/auth/getProjectAccess.action.ts new file mode 100644 index 00000000..81c91fee --- /dev/null +++ b/packages/react-formio/src/stores/auth/getProjectAccess.action.ts @@ -0,0 +1,24 @@ +import { Formio } from "formiojs"; +import { projectAccessUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; + +function transformProjectAccess(projectAccess: any[]) { + return projectAccess.reduce( + (result: any, access: any) => ({ + ...result, + [access.type]: access.roles + }), + {} + ); +} + +export async function getProjectAccess(dispatch: any) { + const projectUrl = Formio.getProjectUrl(); + + try { + const project = await Formio.makeStaticRequest(projectUrl); + const projectAccess = transformProjectAccess(project.access); + + dispatch(projectAccessUser(USER_AUTH, projectAccess)); + } catch (er) {} +} diff --git a/packages/react-formio/src/stores/auth/index.ts b/packages/react-formio/src/stores/auth/index.ts index 70a0a1ef..2defde30 100755 --- a/packages/react-formio/src/stores/auth/index.ts +++ b/packages/react-formio/src/stores/auth/index.ts @@ -1,3 +1,9 @@ export * from "./auth.actions"; +export * from "./auth.actions"; export * from "./auth.reducers"; export * from "./auth.selectors"; +export * from "./getProjectAccess.action"; +export * from "./getAccess.action"; +export * from "./logout.action"; +export * from "./setUser.action"; +export * from "./initAuth.action"; diff --git a/packages/react-formio/src/stores/auth/initAuth.action.spec.ts b/packages/react-formio/src/stores/auth/initAuth.action.spec.ts new file mode 100644 index 00000000..a6d62249 --- /dev/null +++ b/packages/react-formio/src/stores/auth/initAuth.action.spec.ts @@ -0,0 +1,55 @@ +import { Formio } from "formiojs"; +import { requestUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; +import { getAccess } from "./getAccess.action"; +import { getProjectAccess } from "./getProjectAccess.action"; +import { initAuth } from "./initAuth.action"; +import { logout } from "./logout.action"; +import { setUser } from "./setUser.action"; + +jest.mock("./getAccess.action"); +jest.mock("./getProjectAccess.action"); +jest.mock("./setUser.action"); +jest.mock("./logout.action"); +jest.mock("./auth.actions"); + +describe("initAuth()", () => { + beforeEach(() => { + jest.spyOn(Formio, "currentUser"); + }); + afterEach(() => { + jest.resetAllMocks(); + }); + it("should init auth", async () => { + const dispatch = jest.fn(); + const done = jest.fn(); + const user = { data: {} }; + + (Formio.currentUser as any).mockResolvedValue(user); + + await initAuth(done)(dispatch); + + expect(requestUser).toHaveBeenCalledWith(USER_AUTH); + expect(Formio.currentUser).toHaveBeenCalledWith(); + expect(getAccess).toHaveBeenCalledWith(dispatch); + expect(getProjectAccess).toHaveBeenCalledWith(dispatch); + expect(setUser).toHaveBeenCalledWith(user); + expect(logout).not.toHaveBeenCalled(); + }); + it("should call logout when user is null", async () => { + const dispatch = jest.fn(); + const done = jest.fn(); + const user: any = null; + + (Formio.currentUser as any).mockResolvedValue(user); + + await initAuth(done)(dispatch); + + expect(requestUser).toHaveBeenCalledWith(USER_AUTH); + expect(Formio.currentUser).toHaveBeenCalledWith(); + expect(getAccess).toHaveBeenCalledWith(dispatch); + expect(getProjectAccess).toHaveBeenCalledWith(dispatch); + expect(setUser).not.toHaveBeenCalledWith(); + expect(logout).toHaveBeenCalledWith(); + }); +}); diff --git a/packages/react-formio/src/stores/auth/initAuth.action.ts b/packages/react-formio/src/stores/auth/initAuth.action.ts new file mode 100644 index 00000000..232f53cc --- /dev/null +++ b/packages/react-formio/src/stores/auth/initAuth.action.ts @@ -0,0 +1,30 @@ +import { Formio } from "formiojs"; +import noop from "lodash/noop"; +import { failUser, requestUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; +import { getAccess } from "./getAccess.action"; +import { getProjectAccess } from "./getProjectAccess.action"; +import { logout } from "./logout.action"; +import { setUser } from "./setUser.action"; + +export const initAuth = (done = noop) => async (dispatch: any) => { + dispatch(requestUser(USER_AUTH)); + + try { + const [user] = await Promise.all([ + Formio.currentUser(), + getAccess(dispatch), + getProjectAccess(dispatch) + ]); + + if (user) { + dispatch(setUser(user)); + } else { + dispatch(logout()); + } + } catch (error) { + dispatch(failUser(USER_AUTH, { error })); + } + + done(); +}; diff --git a/packages/react-formio/src/stores/auth/logout.action.spec.ts b/packages/react-formio/src/stores/auth/logout.action.spec.ts new file mode 100644 index 00000000..43cc1bae --- /dev/null +++ b/packages/react-formio/src/stores/auth/logout.action.spec.ts @@ -0,0 +1,23 @@ +import { Formio } from "formiojs"; +import { logoutUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; +import { logout } from "./logout.action"; + +jest.mock("./auth.actions"); + +describe("logout()", () => { + beforeEach(() => { + jest.spyOn(Formio, "logout"); + }); + afterEach(() => { + jest.resetAllMocks(); + }); + it("should call logout", async () => { + const dispatch = jest.fn(); + + await logout()(dispatch); + + expect(Formio.logout).toHaveBeenCalledWith(); + expect(logoutUser).toHaveBeenCalledWith(USER_AUTH); + }); +}); diff --git a/packages/react-formio/src/stores/auth/logout.action.ts b/packages/react-formio/src/stores/auth/logout.action.ts new file mode 100644 index 00000000..eb9beb23 --- /dev/null +++ b/packages/react-formio/src/stores/auth/logout.action.ts @@ -0,0 +1,8 @@ +import { Formio } from "formiojs"; +import { logoutUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; + +export const logout = () => (dispatch: any) => { + Formio.logout(); + dispatch(logoutUser(USER_AUTH)); +}; diff --git a/packages/react-formio/src/stores/auth/setUser.action.spec.ts b/packages/react-formio/src/stores/auth/setUser.action.spec.ts new file mode 100644 index 00000000..50840910 --- /dev/null +++ b/packages/react-formio/src/stores/auth/setUser.action.spec.ts @@ -0,0 +1,24 @@ +import { Formio } from "formiojs"; +import { receiveUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; +import { setUser } from "./setUser.action"; + +jest.mock("./auth.actions"); + +describe("setUser()", () => { + beforeEach(() => { + jest.spyOn(Formio, "setUser"); + }); + afterEach(() => { + jest.resetAllMocks(); + }); + it("should call logout", async () => { + const dispatch = jest.fn(); + const user = {}; + + await setUser(user)(dispatch); + + expect(Formio.setUser).toHaveBeenCalledWith(user); + expect(receiveUser).toHaveBeenCalledWith(USER_AUTH, { user }); + }); +}); diff --git a/packages/react-formio/src/stores/auth/setUser.action.ts b/packages/react-formio/src/stores/auth/setUser.action.ts new file mode 100644 index 00000000..3788ea19 --- /dev/null +++ b/packages/react-formio/src/stores/auth/setUser.action.ts @@ -0,0 +1,8 @@ +import { Formio } from "formiojs"; +import { receiveUser } from "./auth.actions"; +import { USER_AUTH } from "./auth.constant"; + +export const setUser = (user: any) => (dispatch: any) => { + Formio.setUser(user); + dispatch(receiveUser(USER_AUTH, { user })); +};