app/apiHandler/sessionApiSlice.js

/**
 * @file
 * File : sessionApiSlice.js\
 * It is used by redux as a state management provider\
 * Defines the authorization profile api endpoints
 *
 * @author  Pierre-Yves Léglise <contact@axialdata.net>
 * @name sessionApiSlice
 */
import { apiSlice } from './apiSlice'

export const sessionApiSlice = apiSlice.injectEndpoints({
  /**
   * Injects additional endpoints into the base API slice.
   * Defines endpoints for user authentication and authorization.
   *
   * @category ApiSlice
   * @function
   * @author  Pierre-Yves Léglise <contact@axialdata.net>
   * @param {Object} builder - RTK Query endpoints builder.
   * @example
   *  const { data, isLoading, isFetching } = useLoginMutation()
   * @returns {Object} Object containing user authentication and authorization endpoint definitions.
   */
  endpoints: (builder) => ({
    /**
     * Endpoint for user authentication.
     * Sends a POST request to the `/session` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name login
     * @param {Object} credentials - User credentials.
     * @param {string} credentials.email - User email.
     * @param {string} credentials.password - User password.
     * @example
     *  const { data, isLoading, isFetching } = useLoginMutation()
     * @returns {Object} Result of the API request.
     */
    login: builder.mutation({
      query: (credentials) => ({
        url: '/session',
        method: 'post',
        data: { ...credentials },
      }),
      keepUnusedDataFor: 0,
    }),
    /**
     * Endpoint for user logout.
     * Sends a DELETE request to the `/session` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name logout
     * @example
     *  const { data, isLoading, isFetching } = useLogoutQuery()
     * @returns {Object} Result of the API request.
     */
    logout: builder.query({
      query: () => ({
        url: '/session',
        method: 'delete',
        withCredentials: true,
      }),
      keepUnusedDataFor: 0,
    }),
    /**
     * Endpoint for user authentication using a cookie.
     * Sends a GET request to the `/session/by-cookie` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name loginByCookie
     * @example
     *  const { data, isLoading, isFetching } = useLoginByCookieQuery()
     * @returns {Object} Result of the API request.
     */
    loginByCookie: builder.query({
      query: () => ({
        url: '/session/by-cookie',
        method: 'get',
        withCredentials: true,
      }),
      keepUnusedDataFor: 0,
    }),
    /**
     * Endpoint for user authorization.
     * Sends a GET request to the `/session/authorization` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name authorization
     * @param {Object} [params] - Additional query parameters for filtering or pagination.
     * @example
     *  const { data, isLoading, isFetching } = useAuthorizationQuery()
     * @returns {Object} Result of the API request.
     */
    authorization: builder.query({
      query: (params) => ({
        url: '/session/authorization',
        method: 'get',
        withCredentials: true,
        params: { ...params },
        // params: { ...params },
      }),
      keepUnusedDataFor: 0,
    }),
    /**
     * Endpoint for updating the user's profile.
     * Sends a PATCH request to the `/session/{userId}` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name updateSelfProfile
     * @param {Object} userData - User data to update.
     * @param {string} userData._id - User ID.
     * @param {Object} [params] - Additional query parameters for filtering or pagination.
     * @example
     *  const { data, isLoading, isFetching } = useUpdateSelfProfileMutation()
     * @returns {Object} Result of the API request.
     */
    updateSelfProfile: builder.mutation({
      query: ({ userData, params }) => ({
        url: `/session/${userData._id}`,
        method: 'patch',
        data: { ...userData },
        withCredentials: true,
        params: { ...params },
      }),
      keepUnusedDataFor: 0,
    }),
    /**
     * Endpoint for uploading a file to the user's profile.
     * Sends a PATCH request to the `/session/{userId}` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name uploadFileSelf
     * @param {Object} userData - User data to update.
     * @param {string} userData._id - User ID.
     * @param {Object} formData - Form data to upload.
     * @param {Object} headers - Headers for the request.
     * @example
     *  const { data, isLoading, isFetching } = useUploadFileSelfMutation()
     * @returns {Object} Result of the API request.
     */
    uploadFileSelf: builder.mutation({
      query: ({ userData, formData, headers }) => ({
        url: `/session/${userData._id}`,
        method: 'patch',
        headers: {
          'content-type': 'multipart/form-data',
        },
        data: formData,
      }),
      keepUnusedDataFor: 0,
    }),
    /**
     * Endpoint for verifying an OTP code.
     * Sends a POST request to the `/session/otp` endpoint.
     *
     * @method
     * @author  Pierre-Yves Léglise <contact@axialdata.net>
     * @name verifyOtp
     * @param {Object} code - OTP code to verify.
     * @param {Object} [params] - Additional query parameters for filtering or pagination.
     * @example
     *  const { data, isLoading, isFetching } = useVerifyOtpMutation()
     * @returns {Object} Result of the API request.
     */
    verifyOtp: builder.mutation({
      query: ({ code, params }) => ({
        url: '/session/otp',
        method: 'post',
        data: { ...code },
        params: { ...params },
      }),
      keepUnusedDataFor: 0,
    }),
  }),
  overrideExisting: true,
})

/**
 * Hooks for interacting with the user authentication and authorization endpoints.
 *
 * @typedef {Object} Hooks
 * @author  Pierre-Yves Léglise <contact@axialdata.net>
 * @property {Function} useLoginMutation - Hook to trigger the login mutation.
 * @property {Function} useVerifyOtpMutation - Hook to trigger the verifyOtp mutation.
 * @property {Function} useAuthorizationQuery - Hook to trigger the authorization query.
 * @property {Function} useLogoutQuery - Hook to trigger the logout query.
 * @property {Function} useLoginByCookieQuery - Hook to trigger the loginByCookie query.
 * @property {Function} useUpdateSelfProfileMutation - Hook to trigger the updateSelfProfile mutation.
 * @property {Function} useUploadFileSelfMutation - Hook to trigger the uploadFileSelf mutation.
 * @example
 *  const { data, isLoading, isFetching } = useLoginMutation()
 * @returns {Object} Object containing user authentication and authorization endpoint hooks.
 */
export const {
  useLoginMutation,
  useVerifyOtpMutation,
  useAuthorizationQuery,
  useLogoutQuery,
  useLoginByCookieQuery,
  useUpdateSelfProfileMutation,
  useUploadFileSelfMutation,
} = sessionApiSlice