[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
4.2 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. import { Action } from 'redux'
  2. import { apiFetch } from '../api'
  3. import { setEntities } from '../actions/entities'
  4. import { startRequest, finishRequest } from '../actions/requests'
  5. import { normalize } from '../utils/normalization'
  6. import {
  7. LOCAL_STORAGE_ACCESS_TOKEN_KEY,
  8. LOCAL_STORAGE_REFRESH_TOKEN_KEY,
  9. LOCAL_STORAGE_ACCESS_TOKEN_EXPIRES_AT_KEY,
  10. } from '../constants'
  11. import { AppThunkAction, Entity, RequestKey, EntityType, Settings } from '../types'
  12. export interface SetCheckedAction extends Action {
  13. type: 'AUTHENTICATION_SET_CHECKED'
  14. }
  15. export interface SetAuthenticatedAction extends Action {
  16. type: 'AUTHENTICATION_SET_AUTHENTICATED'
  17. payload: boolean
  18. }
  19. export interface SetUserAction extends Action {
  20. type: 'AUTHENTICATION_SET_USER'
  21. payload: string
  22. }
  23. export interface UnauthenticateAction extends Action {
  24. type: 'AUTHENTICATION_UNAUTHENTICATE'
  25. }
  26. export type AuthenticationActions = SetCheckedAction | SetAuthenticatedAction | SetUserAction | UnauthenticateAction
  27. export const setChecked = (): SetCheckedAction => ({
  28. type: 'AUTHENTICATION_SET_CHECKED',
  29. })
  30. export const setAuthenticated = (authenticated: boolean): SetAuthenticatedAction => ({
  31. type: 'AUTHENTICATION_SET_AUTHENTICATED',
  32. payload: authenticated,
  33. })
  34. export const setUser = (userId: string): SetUserAction => ({
  35. type: 'AUTHENTICATION_SET_USER',
  36. payload: userId,
  37. })
  38. export const unauthenticate = (): UnauthenticateAction => ({
  39. type: 'AUTHENTICATION_UNAUTHENTICATE',
  40. })
  41. export const fetchSelf = (): AppThunkAction => async dispatch => {
  42. dispatch(startRequest(RequestKey.FetchSelf))
  43. try {
  44. const self = await apiFetch<Entity>({
  45. path: '/v1/self',
  46. })
  47. const result = normalize([self], EntityType.User)
  48. dispatch(setEntities(result.entities))
  49. dispatch(setUser(self.id))
  50. dispatch(setAuthenticated(true))
  51. dispatch(finishRequest(RequestKey.FetchSelf, true))
  52. } catch (err) {
  53. dispatch(setAuthenticated(false))
  54. dispatch(finishRequest(RequestKey.FetchSelf, false))
  55. throw err
  56. }
  57. }
  58. interface AuthenticateResponse {
  59. id: string
  60. access: string
  61. refresh: string
  62. expires: number
  63. }
  64. export const authenticate = (name: string, password: string): AppThunkAction<string> => async dispatch => {
  65. dispatch(startRequest(RequestKey.Authenticate))
  66. try {
  67. const response = await apiFetch<AuthenticateResponse>({
  68. path: '/v1/authenticate',
  69. method: 'post',
  70. body: {
  71. id: name,
  72. password,
  73. },
  74. })
  75. localStorage.setItem(LOCAL_STORAGE_ACCESS_TOKEN_KEY, response.access)
  76. localStorage.setItem(LOCAL_STORAGE_REFRESH_TOKEN_KEY, response.refresh)
  77. if (response.expires) localStorage.setItem(LOCAL_STORAGE_ACCESS_TOKEN_EXPIRES_AT_KEY, response.expires.toString())
  78. dispatch(finishRequest(RequestKey.Authenticate, true))
  79. await dispatch(fetchSelf())
  80. return response.id
  81. } catch (err) {
  82. dispatch(finishRequest(RequestKey.Authenticate, false))
  83. throw err
  84. }
  85. }
  86. interface UpdateSelfOptions {
  87. name: string
  88. about: string
  89. requiresApproval: boolean
  90. privacy: string
  91. imageUrl: string
  92. coverImageUrl: string
  93. theme: string
  94. settings: Settings
  95. }
  96. export const updateSelf = (options: UpdateSelfOptions): AppThunkAction => async dispatch => {
  97. const { name, about, requiresApproval, privacy, imageUrl, coverImageUrl, theme, settings } = options
  98. dispatch(startRequest(RequestKey.UpdateSelf))
  99. try {
  100. const self = await apiFetch<Entity>({
  101. path: '/v1/self',
  102. method: 'put',
  103. body: {
  104. name,
  105. about,
  106. requiresApproval,
  107. privacy,
  108. imageUrl,
  109. coverImageUrl,
  110. theme,
  111. settings,
  112. },
  113. })
  114. const result = normalize([self], EntityType.User)
  115. dispatch(setEntities(result.entities))
  116. dispatch(setUser(self.id))
  117. dispatch(setAuthenticated(true))
  118. dispatch(finishRequest(RequestKey.UpdateSelf, true))
  119. } catch (err) {
  120. dispatch(finishRequest(RequestKey.UpdateSelf, false))
  121. throw err
  122. }
  123. }