authReducer.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { gql } from "graphql-request";
  2. import { createApi } from '@reduxjs/toolkit/query/react'
  3. import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query' //npm install
  4. import { getFullBackendUrl, jwtDecode } from "../utills";
  5. import { createSlice } from "@reduxjs/toolkit";
  6. import { history } from "../App";
  7. import { UserEntity } from "../Entities";
  8. import { createFullQuery } from "../utills";
  9. const getUsersSearchParams = (searchStr, queryExt) => (
  10. {
  11. searchStr: searchStr,
  12. searchFieldNames: ["nick", "login"],
  13. queryExt
  14. });
  15. export const prepareHeaders = (headers, { getState }) => {
  16. const token = getState().auth.token;
  17. if (token) {
  18. headers.set("Authorization", `Bearer ${token}`);
  19. }
  20. return headers;
  21. }
  22. const authApi = createApi({
  23. reducerPath: "authApi",
  24. baseQuery: graphqlRequestBaseQuery({
  25. url: getFullBackendUrl('/graphql'),
  26. prepareHeaders
  27. }),
  28. endpoints: (builder) => ({
  29. login: builder.mutation({
  30. query: ({ login, password }) => ({
  31. document: gql`
  32. query login($login: String, $password: String) {
  33. login(login: $login, password: $password)
  34. }
  35. `,
  36. variables: { login, password }
  37. })
  38. }),
  39. register: builder.mutation({
  40. query: ({ login, password, nick }) => ({
  41. document: gql`
  42. mutation UserRegistration($login: String, $password: String, $nick: String) {
  43. UserUpsert(user: {login: $login, password: $password, nick: $nick}) {
  44. _id
  45. createdAt
  46. nick
  47. acl
  48. }
  49. }
  50. `,
  51. variables: { login, password, nick: nick || login }
  52. })
  53. }),
  54. userFind: builder.query({
  55. query: (_id) => ({
  56. document: gql`
  57. query UserFind($q: String) {
  58. UserFindOne(query: $q){
  59. _id login nick acl avatar {_id url} createdAt
  60. }
  61. }
  62. `,
  63. variables: { q: JSON.stringify([{ _id }]) }
  64. }),
  65. providesTags: (result, error, id) => ([{ type: 'User', id }])
  66. }),
  67. saveUser: builder.mutation({
  68. query: ({ user }) => ({
  69. document: gql`
  70. mutation UserUpsert($user: UserInput) {
  71. UserUpsert(user: $user) {
  72. _id acl
  73. }
  74. }
  75. `,
  76. variables: { user }
  77. }),
  78. invalidatesTags: (result, error, arg) => ([{ type: 'User', id: arg._id }])
  79. }),
  80. getUsers: builder.query({
  81. query: ({ fromPage, pageSize, searchStr = '' }) => {
  82. let params = createFullQuery(getUsersSearchParams(searchStr), { fromPage, pageSize, sort: { _id: -1 } });
  83. return {
  84. document: gql`
  85. query UserFind($q: String) {
  86. UserFind(query: $q){
  87. _id login nick acl avatar {_id url} createdAt
  88. }
  89. }
  90. `,
  91. variables: params
  92. }
  93. },
  94. }),
  95. getUsersCount: builder.query({
  96. query: ({ searchStr = '' }) => {
  97. let params = createFullQuery(getUsersSearchParams(searchStr));
  98. return {
  99. document: gql`
  100. query UsersCount($q: String) { UserCount(query: $q) }
  101. `,
  102. variables: params
  103. }
  104. },
  105. }),
  106. }),
  107. })
  108. const authSlice = createSlice({
  109. name: 'auth',
  110. initialState: {},
  111. reducers: {
  112. logout(state) {
  113. history.push('/');
  114. return {}
  115. }
  116. },
  117. extraReducers: builder => {
  118. builder.addMatcher(authApi.endpoints.login.matchFulfilled,
  119. (state, { payload }) => {
  120. const tokenPayload = jwtDecode(payload.login);
  121. if (tokenPayload) {
  122. state.token = payload.login;
  123. state.payload = tokenPayload;
  124. state.currentUser = { _id: tokenPayload.sub.id };
  125. history.push('/');
  126. }
  127. });
  128. builder.addMatcher(authApi.endpoints.userFind.matchFulfilled,
  129. (state, { payload }) => {
  130. let retrievedUser = payload?.UserFindOne;
  131. if (retrievedUser?._id === state.currentUser?._id)
  132. state.currentUser = retrievedUser;
  133. });
  134. }
  135. })
  136. const actionAboutMe = () =>
  137. async (dispatch, getState) => {
  138. const auth = getState().auth
  139. if (auth.token) {
  140. dispatch(authApi.endpoints.userFind.initiate(auth.currentUser._id))
  141. }
  142. }
  143. const getCurrentUser = state => state.auth?.currentUser ?? {};
  144. const isCurrentUserAdmin = state =>{
  145. let currentUser = getCurrentUser(state);
  146. return currentUser ? new UserEntity(currentUser).isAdminRole : false;
  147. }
  148. const { logout: actionAuthLogout } = authSlice.actions;
  149. export const { useLoginMutation, useUserFindQuery, useSaveUserMutation, useGetUsersQuery, useGetUsersCountQuery, useRegisterMutation } = authApi;
  150. export { authApi, authSlice, actionAuthLogout, actionAboutMe, getCurrentUser, isCurrentUserAdmin }