PersonalContainer.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import { Container } from 'unstated';
  2. import { AttachmentType } from '~/server/interfaces/attachment';
  3. import loggerFactory from '~/utils/logger';
  4. import { apiPost } from '../util/apiv1-client';
  5. import { apiv3Get, apiv3Put } from '../util/apiv3-client';
  6. // eslint-disable-next-line no-unused-vars
  7. const logger = loggerFactory('growi:services:PersonalContainer');
  8. /**
  9. * Service container for personal settings page (PersonalSettings.jsx)
  10. * @extends {Container} unstated Container
  11. */
  12. export default class PersonalContainer extends Container {
  13. constructor(appContainer) {
  14. super();
  15. this.appContainer = appContainer;
  16. this.state = {
  17. retrieveError: null,
  18. name: '',
  19. email: '',
  20. registrationWhiteList: this.appContainer.getConfig().registrationWhiteList,
  21. isEmailPublished: false,
  22. lang: 'en_US',
  23. isGravatarEnabled: false,
  24. externalAccounts: [],
  25. apiToken: '',
  26. slackMemberId: '',
  27. };
  28. }
  29. /**
  30. * Workaround for the mangling in production build to break constructor.name
  31. */
  32. static getClassName() {
  33. return 'PersonalContainer';
  34. }
  35. /**
  36. * retrieve personal data
  37. */
  38. async retrievePersonalData() {
  39. try {
  40. const response = await apiv3Get('/personal-setting/');
  41. const { currentUser } = response.data;
  42. this.setState({
  43. name: currentUser.name,
  44. email: currentUser.email,
  45. isEmailPublished: currentUser.isEmailPublished,
  46. lang: currentUser.lang,
  47. isGravatarEnabled: currentUser.isGravatarEnabled,
  48. apiToken: currentUser.apiToken,
  49. slackMemberId: currentUser.slackMemberId,
  50. });
  51. }
  52. catch (err) {
  53. this.setState({ retrieveError: err });
  54. logger.error(err);
  55. throw new Error('Failed to fetch personal data');
  56. }
  57. }
  58. /**
  59. * retrieve external accounts that linked me
  60. */
  61. async retrieveExternalAccounts() {
  62. try {
  63. const response = await apiv3Get('/personal-setting/external-accounts');
  64. const { externalAccounts } = response.data;
  65. this.setState({ externalAccounts });
  66. }
  67. catch (err) {
  68. this.setState({ retrieveError: err });
  69. logger.error(err);
  70. throw new Error('Failed to fetch external accounts');
  71. }
  72. }
  73. /**
  74. * Change name
  75. */
  76. changeName(inputValue) {
  77. this.setState({ name: inputValue });
  78. }
  79. /**
  80. * Change email
  81. */
  82. changeEmail(inputValue) {
  83. this.setState({ email: inputValue });
  84. }
  85. /**
  86. * Change Slack Member ID
  87. */
  88. changeSlackMemberId(inputValue) {
  89. this.setState({ slackMemberId: inputValue });
  90. }
  91. /**
  92. * Change isEmailPublished
  93. */
  94. changeIsEmailPublished(boolean) {
  95. this.setState({ isEmailPublished: boolean });
  96. }
  97. /**
  98. * Change lang
  99. */
  100. changeLang(lang) {
  101. this.setState({ lang });
  102. }
  103. /**
  104. * Change isGravatarEnabled
  105. */
  106. changeIsGravatarEnabled(boolean) {
  107. this.setState({ isGravatarEnabled: boolean });
  108. }
  109. /**
  110. * Update basic info
  111. * @memberOf PersonalContainer
  112. * @return {Array} basic info
  113. */
  114. async updateBasicInfo() {
  115. try {
  116. const response = await apiv3Put('/personal-setting/', {
  117. name: this.state.name,
  118. email: this.state.email,
  119. isEmailPublished: this.state.isEmailPublished,
  120. lang: this.state.lang,
  121. slackMemberId: this.state.slackMemberId,
  122. });
  123. const { updatedUser } = response.data;
  124. this.setState({
  125. name: updatedUser.name,
  126. email: updatedUser.email,
  127. isEmailPublished: updatedUser.isEmailPublished,
  128. lang: updatedUser.lang,
  129. slackMemberId: updatedUser.slackMemberId,
  130. });
  131. }
  132. catch (err) {
  133. this.setState({ retrieveError: err });
  134. logger.error(err);
  135. throw new Error('Failed to update personal data');
  136. }
  137. }
  138. /**
  139. * Update profile image
  140. * @memberOf PersonalContainer
  141. */
  142. async updateProfileImage() {
  143. try {
  144. const response = await apiv3Put('/personal-setting/image-type', {
  145. isGravatarEnabled: this.state.isGravatarEnabled,
  146. });
  147. const { userData } = response.data;
  148. this.setState({
  149. isGravatarEnabled: userData.isGravatarEnabled,
  150. });
  151. }
  152. catch (err) {
  153. this.setState({ retrieveError: err });
  154. logger.error(err);
  155. throw new Error('Failed to update profile image');
  156. }
  157. }
  158. /**
  159. * Upload image
  160. */
  161. async uploadAttachment(file) {
  162. try {
  163. const formData = new FormData();
  164. formData.append('file', file);
  165. formData.append('_csrf', this.appContainer.csrfToken);
  166. formData.append('attachmentType', AttachmentType.PROFILE_IMAGE);
  167. const response = await apiPost('/attachments.uploadProfileImage', formData);
  168. this.setState({ isUploadedPicture: true, uploadedPictureSrc: response.attachment.filePathProxied });
  169. }
  170. catch (err) {
  171. this.setState({ retrieveError: err });
  172. logger.error(err);
  173. throw new Error('Failed to upload profile image');
  174. }
  175. }
  176. /**
  177. * Delete image
  178. */
  179. async deleteProfileImage() {
  180. try {
  181. await apiPost('/attachments.removeProfileImage', { _csrf: this.appContainer.csrfToken });
  182. this.setState({ isUploadedPicture: false, uploadedPictureSrc: DEFAULT_IMAGE });
  183. }
  184. catch (err) {
  185. this.setState({ retrieveError: err });
  186. logger.error(err);
  187. throw new Error('Failed to delete profile image');
  188. }
  189. }
  190. /**
  191. * Associate LDAP account
  192. */
  193. async associateLdapAccount(account) {
  194. try {
  195. await apiv3Put('/personal-setting/associate-ldap', account);
  196. }
  197. catch (err) {
  198. this.setState({ retrieveError: err });
  199. logger.error(err);
  200. throw new Error('Failed to associate ldap account');
  201. }
  202. }
  203. /**
  204. * Disassociate LDAP account
  205. */
  206. async disassociateLdapAccount(account) {
  207. try {
  208. await apiv3Put('/personal-setting/disassociate-ldap', account);
  209. }
  210. catch (err) {
  211. this.setState({ retrieveError: err });
  212. logger.error(err);
  213. throw new Error('Failed to disassociate ldap account');
  214. }
  215. }
  216. }