PersonalContainer.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. isPasswordSet: false,
  26. apiToken: '',
  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 this.appContainer.apiv3.get('/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. isPasswordSet: (currentUser.password != null),
  49. apiToken: currentUser.apiToken,
  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. * define a function for uploaded picture
  60. */
  61. getUploadedPictureSrc(user) {
  62. if (user == null) {
  63. return DEFAULT_IMAGE;
  64. }
  65. if (user.image) {
  66. this.setState({ isUploadedPicture: true });
  67. return user.image;
  68. }
  69. if (user.imageAttachment != null) {
  70. this.setState({ isUploadedPicture: true });
  71. return user.imageAttachment.filePathProxied;
  72. }
  73. return DEFAULT_IMAGE;
  74. }
  75. /**
  76. * retrieve external accounts that linked me
  77. */
  78. async retrieveExternalAccounts() {
  79. try {
  80. const response = await this.appContainer.apiv3.get('/personal-setting/external-accounts');
  81. const { externalAccounts } = response.data;
  82. this.setState({ externalAccounts });
  83. }
  84. catch (err) {
  85. this.setState({ retrieveError: err });
  86. logger.error(err);
  87. throw new Error('Failed to fetch external accounts');
  88. }
  89. }
  90. /**
  91. * Change name
  92. */
  93. changeName(inputValue) {
  94. this.setState({ name: inputValue });
  95. }
  96. /**
  97. * Change email
  98. */
  99. changeEmail(inputValue) {
  100. this.setState({ email: inputValue });
  101. }
  102. /**
  103. * Change isEmailPublished
  104. */
  105. changeIsEmailPublished(boolean) {
  106. this.setState({ isEmailPublished: boolean });
  107. }
  108. /**
  109. * Change lang
  110. */
  111. changeLang(lang) {
  112. this.setState({ lang });
  113. }
  114. /**
  115. * Change isGravatarEnabled
  116. */
  117. changeIsGravatarEnabled(boolean) {
  118. this.setState({ isGravatarEnabled: boolean });
  119. }
  120. /**
  121. * Update basic info
  122. * @memberOf PersonalContainer
  123. * @return {Array} basic info
  124. */
  125. async updateBasicInfo() {
  126. try {
  127. const response = await this.appContainer.apiv3.put('/personal-setting/', {
  128. name: this.state.name,
  129. email: this.state.email,
  130. isEmailPublished: this.state.isEmailPublished,
  131. lang: this.state.lang,
  132. });
  133. const { updatedUser } = response.data;
  134. this.setState({
  135. name: updatedUser.name,
  136. email: updatedUser.email,
  137. isEmailPublished: updatedUser.isEmailPublished,
  138. lang: updatedUser.lang,
  139. });
  140. }
  141. catch (err) {
  142. this.setState({ retrieveError: err });
  143. logger.error(err);
  144. throw new Error('Failed to update personal data');
  145. }
  146. }
  147. /**
  148. * Update profile image
  149. * @memberOf PersonalContainer
  150. */
  151. async updateProfileImage() {
  152. try {
  153. const response = await this.appContainer.apiv3.put('/personal-setting/image-type', {
  154. isGravatarEnabled: this.state.isGravatarEnabled,
  155. });
  156. const { userData } = response.data;
  157. this.setState({
  158. isGravatarEnabled: userData.isGravatarEnabled,
  159. });
  160. }
  161. catch (err) {
  162. this.setState({ retrieveError: err });
  163. logger.error(err);
  164. throw new Error('Failed to update profile image');
  165. }
  166. }
  167. /**
  168. * Upload image
  169. */
  170. async uploadAttachment(file) {
  171. try {
  172. const formData = new FormData();
  173. formData.append('file', file);
  174. formData.append('_csrf', this.appContainer.csrfToken);
  175. const response = await this.appContainer.apiPost('/attachments.uploadProfileImage', formData);
  176. this.setState({ isUploadedPicture: true, uploadedPictureSrc: response.attachment.filePathProxied });
  177. }
  178. catch (err) {
  179. this.setState({ retrieveError: err });
  180. logger.error(err);
  181. throw new Error('Failed to upload profile image');
  182. }
  183. }
  184. /**
  185. * Delete image
  186. */
  187. async deleteProfileImage() {
  188. try {
  189. await this.appContainer.apiPost('/attachments.removeProfileImage', { _csrf: this.appContainer.csrfToken });
  190. this.setState({ isUploadedPicture: false, uploadedPictureSrc: DEFAULT_IMAGE });
  191. }
  192. catch (err) {
  193. this.setState({ retrieveError: err });
  194. logger.error(err);
  195. throw new Error('Failed to delete profile image');
  196. }
  197. }
  198. /**
  199. * Associate LDAP account
  200. */
  201. async associateLdapAccount(account) {
  202. try {
  203. await this.appContainer.apiv3.put('/personal-setting/associate-ldap', account);
  204. }
  205. catch (err) {
  206. this.setState({ retrieveError: err });
  207. logger.error(err);
  208. throw new Error('Failed to associate ldap account');
  209. }
  210. }
  211. /**
  212. * Disassociate LDAP account
  213. */
  214. async disassociateLdapAccount(account) {
  215. try {
  216. await this.appContainer.apiv3.put('/personal-setting/disassociate-ldap', account);
  217. }
  218. catch (err) {
  219. this.setState({ retrieveError: err });
  220. logger.error(err);
  221. throw new Error('Failed to disassociate ldap account');
  222. }
  223. }
  224. }