PersonalContainer.js 6.1 KB

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