2
0

personal-setting.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /* eslint-disable no-unused-vars */
  2. const loggerFactory = require('@alias/logger');
  3. const logger = loggerFactory('growi:routes:apiv3:personal-setting');
  4. const express = require('express');
  5. const router = express.Router();
  6. const { body } = require('express-validator/check');
  7. const ErrorV3 = require('../../models/vo/error-apiv3');
  8. /**
  9. * @swagger
  10. * tags:
  11. * name: PsersonalSetting
  12. */
  13. /**
  14. * @swagger
  15. *
  16. * components:
  17. * schemas:
  18. * PersonalSettings:
  19. * description: personal settings
  20. * type: object
  21. * properties:
  22. * name:
  23. * type: string
  24. * email:
  25. * type: string
  26. * lang:
  27. * type: string
  28. * isEmailPublished:
  29. * type: boolean
  30. * Passwords:
  31. * description: passwords for update
  32. * type: object
  33. * properties:
  34. * oldPassword:
  35. * type: string
  36. * newPassword:
  37. * type: string
  38. * newPasswordConfirm:
  39. * type: string
  40. */
  41. module.exports = (crowi) => {
  42. const accessTokenParser = require('../../middleware/access-token-parser')(crowi);
  43. const loginRequiredStrictly = require('../../middleware/login-required')(crowi);
  44. const csrf = require('../../middleware/csrf')(crowi);
  45. const { User, ExternalAccount } = crowi.models;
  46. const { ApiV3FormValidator } = crowi.middlewares;
  47. const validator = {
  48. personal: [
  49. body('name').isString().not().isEmpty(),
  50. body('email').isEmail(),
  51. body('lang').isString().isIn(['en-US', 'ja']),
  52. body('isEmailPublished').isBoolean(),
  53. ],
  54. password: [
  55. body('oldPassword').isString(),
  56. body('newPassword').isString().not().isEmpty()
  57. .isLength({ min: 6 })
  58. .withMessage('password must be at least 6 characters long'),
  59. body('newPasswordConfirm').isString().not().isEmpty()
  60. .custom((value, { req }) => {
  61. return (value === req.body.newPassword);
  62. }),
  63. ],
  64. };
  65. /**
  66. * @swagger
  67. *
  68. * /personal-setting:
  69. * get:
  70. * tags: [PersonalSetting]
  71. * operationId: getPersonalSetting
  72. * summary: /personal-setting
  73. * description: Get personal parameters
  74. * responses:
  75. * 200:
  76. * description: params of personal
  77. * content:
  78. * application/json:
  79. * schema:
  80. * properties:
  81. * currentUser:
  82. * type: object
  83. * description: personal params
  84. */
  85. router.get('/', accessTokenParser, loginRequiredStrictly, async(req, res) => {
  86. const currentUser = await User.findUserByUsername(req.user.username);
  87. return res.apiv3({ currentUser });
  88. });
  89. /**
  90. * @swagger
  91. *
  92. * /personal-setting:
  93. * put:
  94. * tags: [PersonalSetting]
  95. * operationId: updatePersonalSetting
  96. * summary: /personal-setting
  97. * description: Update personal setting
  98. * requestBody:
  99. * required: true
  100. * content:
  101. * application/json:
  102. * schema:
  103. * $ref: '#/components/schemas/PersonalSettings'
  104. * responses:
  105. * 200:
  106. * description: params of personal
  107. * content:
  108. * application/json:
  109. * schema:
  110. * properties:
  111. * currentUser:
  112. * type: object
  113. * description: personal params
  114. */
  115. router.put('/', accessTokenParser, loginRequiredStrictly, csrf, validator.personal, ApiV3FormValidator, async(req, res) => {
  116. try {
  117. const user = await User.findOne({ _id: req.user.id });
  118. user.name = req.body.name;
  119. user.email = req.body.email;
  120. user.lang = req.body.lang;
  121. user.isEmailPublished = req.body.isEmailPublished;
  122. const updatedUser = await user.save();
  123. req.i18n.changeLanguage(req.body.lang);
  124. return res.apiv3({ updatedUser });
  125. }
  126. catch (err) {
  127. logger.error(err);
  128. return res.apiv3Err('update-personal-settings-failed');
  129. }
  130. });
  131. /**
  132. * @swagger
  133. *
  134. * /personal-setting/external-accounts:
  135. * get:
  136. * tags: [PersonalSetting]
  137. * operationId: getExternalAccounts
  138. * summary: /personal-setting/external-accounts
  139. * description: Get external accounts that linked current user
  140. * responses:
  141. * 200:
  142. * description: external accounts
  143. * content:
  144. * application/json:
  145. * schema:
  146. * properties:
  147. * externalAccounts:
  148. * type: object
  149. * description: array of external accounts
  150. */
  151. router.get('/external-accounts', accessTokenParser, loginRequiredStrictly, async(req, res) => {
  152. const userData = req.user;
  153. try {
  154. const externalAccounts = await ExternalAccount.find({ user: userData });
  155. return res.apiv3({ externalAccounts });
  156. }
  157. catch (err) {
  158. logger.error(err);
  159. return res.apiv3Err('get-external-accounts-failed');
  160. }
  161. });
  162. /**
  163. * @swagger
  164. *
  165. * /personal-setting/password:
  166. * put:
  167. * tags: [PersonalSetting]
  168. * operationId: putUserPassword
  169. * summary: /personal-setting/password
  170. * description: Update user password
  171. * requestBody:
  172. * required: true
  173. * content:
  174. * application/json:
  175. * schema:
  176. * $ref: '#/components/schemas/Passwords'
  177. * responses:
  178. * 200:
  179. * description: user password
  180. * content:
  181. * application/json:
  182. * schema:
  183. * properties:
  184. * userData:
  185. * type: object
  186. * description: user data updated
  187. */
  188. router.put('/password', accessTokenParser, loginRequiredStrictly, csrf, validator.password, ApiV3FormValidator, async(req, res) => {
  189. const { body, user } = req;
  190. const { oldPassword, newPassword } = body;
  191. if (user.isPasswordSet() && !user.isPasswordValid(oldPassword)) {
  192. return res.apiv3Err('wrong-current-password', 400);
  193. }
  194. try {
  195. const userData = await user.updatePassword(newPassword);
  196. return res.apiv3({ userData });
  197. }
  198. catch (err) {
  199. logger.error(err);
  200. return res.apiv3Err('update-password-failed');
  201. }
  202. });
  203. // TODO
  204. router.put('/api-token', loginRequiredStrictly, csrf, async(req, res) => {
  205. const { user } = req;
  206. try {
  207. const userData = await user.updateApiToken();
  208. return res.apiv3({ userData });
  209. }
  210. catch (err) {
  211. logger.error(err);
  212. return res.apiv3Err('update-api-token-failed');
  213. }
  214. });
  215. return router;
  216. };