github.com/grafviktor/keep-my-secret@v0.9.10-0.20230908165355-19f35cce90e5/website/src/api.js (about)

     1  import axios from 'axios'
     2  import get from 'lodash/get'
     3  import isNil from 'lodash/isNil'
     4  import reduce from 'lodash/reduce'
     5  
     6  const BASE_URL = 'https://localhost:8080'
     7  const httpRequest = axios.create({
     8    baseURL        : BASE_URL,
     9    // we handle all responses independently of their HTTP status
    10    validateStatus : () => true,
    11  })
    12  
    13  const checkApiError = (response) => {
    14    const status = get(response, 'data.status')
    15  
    16    if (response.headers['content-type'] === 'application/json' && status !== 'success') {
    17      const message = get(response, 'data.message', 'Unknown error')
    18  
    19      throw Error(message)
    20    } else if (response.status >= 400) {
    21      throw Error(`status ${response.status}`, response.message)
    22    }
    23  
    24    return response
    25  }
    26  
    27  const getVersion = () => httpRequest.get('/api/v1/version')
    28  
    29  const register = (username, password) => httpRequest.post(
    30    '/api/v1/user/register',
    31    {username, password},
    32    {withCredentials: true},
    33  )
    34  
    35  const login = (username, password) => httpRequest.post(
    36    '/api/v1/user/login',
    37    {username, password},
    38    {withCredentials: true},
    39  )
    40  
    41  const logout = () => httpRequest.post('/api/v1/user/logout')
    42  
    43  const refreshToken = () => httpRequest.get(
    44    '/api/v1/user/token-refresh',
    45    {withCredentials: true},
    46  )
    47  const createSecretWithFile = async (accessToken, payload) => {
    48    const {file, ...otherAttributes} = payload
    49    const formData = new FormData()
    50  
    51    formData.append('data', JSON.stringify({ // Add JSON data
    52      ...otherAttributes,
    53      file_name: file.name,
    54    }))
    55    formData.append('file', file, file.name) // Add the file
    56  
    57    return httpRequest.post(
    58      '/api/v1/secrets',
    59      formData,
    60      {headers: {
    61        Authorization  : `Bearer ${accessToken}`,
    62        'Content-Type' : 'multipart/form-data',
    63      }},
    64    )
    65  }
    66  
    67  const createSecret = async (accessToken, payload) => {
    68    if (!isNil(payload.file)) {
    69      return createSecretWithFile(accessToken, payload)
    70    }
    71  
    72    return httpRequest.post(
    73      '/api/v1/secrets',
    74      payload,
    75      {headers: {
    76        Authorization: `Bearer ${accessToken}`,
    77      }},
    78    )
    79  }
    80  
    81  const updateSecret = (accessToken, id, payload) => httpRequest.put(
    82    `/api/v1/secrets/${id}`,
    83    payload,
    84    {headers: {Authorization: `Bearer ${accessToken}`}},
    85  )
    86  
    87  const deleteSecret = (accessToken, id) => httpRequest.delete(
    88    `/api/v1/secrets/${id}`,
    89    {headers: {Authorization: `Bearer ${accessToken}`}},
    90  )
    91  
    92  const getSecretFile = async (accessToken, id) => httpRequest.get(
    93    `/api/v1/secrets/file/${id}`,
    94    {
    95      // By default responseType is 'json'. If we're requesting binary data(like a file)
    96      // we receive malformed document, which content is different is different from
    97      // actual 'Content-Length' header value
    98      responseType : 'arraybuffer',
    99      headers      : {Authorization: `Bearer ${accessToken}`},
   100    },
   101  )
   102  
   103  const fetchSecrets = (accessToken) => httpRequest.get(
   104    '/api/v1/secrets',
   105    {headers: {Authorization: `Bearer ${accessToken}`}},
   106  )
   107  
   108  const api = (context) => reduce({
   109    // cannot use map[fn1, fn2, ...] because webpack removes function names (fn.name) from
   110    // prod build don't have time to make a proper setup for WebPack terser plugin
   111    login,
   112    logout,
   113    register,
   114    getVersion,
   115    refreshToken,
   116    createSecret,
   117    deleteSecret,
   118    updateSecret,
   119    fetchSecrets,
   120    getSecretFile,
   121  }, (acc, fn, name) => ({
   122    ...acc,
   123    [name]: async (...args) => {
   124      context.setAppBusy(true)
   125      const response = await fn(...args)
   126      context.setAppBusy(false)
   127  
   128      return checkApiError(response)
   129    },
   130  }), {})
   131  
   132  export default api