User.coffee 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. request = require("./request")
  2. _ = require("underscore")
  3. settings = require("settings-sharelatex")
  4. {db, ObjectId} = require("../../../../app/js/infrastructure/mongojs")
  5. UserModel = require("../../../../app/js/models/User").User
  6. UserUpdater = require("../../../../app/js/Features/User/UserUpdater")
  7. AuthenticationManager = require("../../../../app/js/Features/Authentication/AuthenticationManager")
  8. count = 0
  9. class User
  10. constructor: (options = {}) ->
  11. @emails = [
  12. email: "acceptance-test-#{count}@example.com"
  13. createdAt: new Date()
  14. ]
  15. @email = @emails[0].email
  16. @password = "acceptance-test-#{count}-password"
  17. count++
  18. @jar = request.jar()
  19. @request = request.defaults({
  20. jar: @jar
  21. })
  22. setExtraAttributes: (user) ->
  23. throw new Error("User does not exist") unless user?._id?
  24. @id = user._id.toString()
  25. @_id = user._id.toString()
  26. @first_name = user.first_name
  27. @referal_id = user.referal_id
  28. get: (callback = (error, user)->) ->
  29. db.users.findOne { _id: ObjectId(@_id) }, callback
  30. mongoUpdate: (updateOp, callback=(error)->) ->
  31. db.users.update {_id: ObjectId(@_id)}, updateOp, callback
  32. register: (callback = (error, user) ->) ->
  33. return callback(new Error('User already registered')) if @_id?
  34. @getCsrfToken (error) =>
  35. return callback(error) if error?
  36. @request.post {
  37. url: '/register'
  38. json: { @email, @password }
  39. }, (error, response, body) =>
  40. return callback(error) if error?
  41. db.users.findOne { email: @email }, (error, user) =>
  42. return callback(error) if error?
  43. @setExtraAttributes user
  44. callback(null, user)
  45. login: (callback = (error) ->) ->
  46. @loginWith(@email, callback)
  47. loginWith: (email, callback = (error) ->) ->
  48. @ensureUserExists (error) =>
  49. return callback(error) if error?
  50. @getCsrfToken (error) =>
  51. return callback(error) if error?
  52. @request.post {
  53. url: "/login"
  54. json: { email, @password }
  55. }, callback
  56. ensureUserExists: (callback = (error) ->) ->
  57. filter = {@email}
  58. options = {upsert: true, new: true, setDefaultsOnInsert: true}
  59. UserModel.findOneAndUpdate filter, {}, options, (error, user) =>
  60. return callback(error) if error?
  61. AuthenticationManager.setUserPassword user._id, @password, (error) =>
  62. return callback(error) if error?
  63. UserUpdater.updateUser user._id, $set: emails: @emails, (error) =>
  64. return callback(error) if error?
  65. @setExtraAttributes user
  66. callback(null, @password)
  67. setFeatures: (features, callback = (error) ->) ->
  68. update = {}
  69. for key, value of features
  70. update["features.#{key}"] = value
  71. UserModel.update { _id: @id }, update, callback
  72. logout: (callback = (error) ->) ->
  73. @getCsrfToken (error) =>
  74. return callback(error) if error?
  75. @request.get {
  76. url: "/logout"
  77. json:
  78. email: @email
  79. password: @password
  80. }, (error, response, body) =>
  81. return callback(error) if error?
  82. db.users.findOne {email: @email}, (error, user) =>
  83. return callback(error) if error?
  84. @id = user?._id?.toString()
  85. @_id = user?._id?.toString()
  86. callback()
  87. addEmail: (email, callback = (error) ->) ->
  88. @emails.push(email: email, createdAt: new Date())
  89. UserUpdater.addEmailAddress @id, email, callback
  90. confirmEmail: (email, callback = (error) ->) ->
  91. for emailData, idx in @emails
  92. @emails[idx].confirmedAt = new Date() if emailData.email == email
  93. UserUpdater.confirmEmail @id, email, callback
  94. ensure_admin: (callback = (error) ->) ->
  95. db.users.update {_id: ObjectId(@id)}, { $set: { isAdmin: true }}, callback
  96. upgradeFeatures: (callback = (error) -> ) ->
  97. features = {
  98. collaborators: -1 # Infinite
  99. versioning: true
  100. dropbox:true
  101. compileTimeout: 60
  102. compileGroup:"priority"
  103. templates: true
  104. references: true
  105. trackChanges: true
  106. trackChangesVisible: true
  107. }
  108. db.users.update {_id: ObjectId(@id)}, { $set: { features: features }}, callback
  109. downgradeFeatures: (callback = (error) -> ) ->
  110. features = {
  111. collaborators: 1
  112. versioning: false
  113. dropbox:false
  114. compileTimeout: 60
  115. compileGroup:"standard"
  116. templates: false
  117. references: false
  118. trackChanges: false
  119. trackChangesVisible: false
  120. }
  121. db.users.update {_id: ObjectId(@id)}, { $set: { features: features }}, callback
  122. defaultFeatures: (callback = (error) -> ) ->
  123. features = settings.defaultFeatures
  124. db.users.update {_id: ObjectId(@id)}, { $set: { features: features }}, callback
  125. full_delete_user: (email, callback = (error) ->) ->
  126. db.users.findOne {email: email}, (error, user) =>
  127. if !user?
  128. return callback()
  129. user_id = user._id
  130. db.projects.remove owner_ref:ObjectId(user_id), {multi:true}, (err)->
  131. if err?
  132. callback(err)
  133. db.users.remove {_id: ObjectId(user_id)}, callback
  134. getProject: (project_id, callback = (error, project)->) ->
  135. db.projects.findOne {_id: ObjectId(project_id.toString())}, callback
  136. saveProject: (project, callback=(error)->) ->
  137. db.projects.update {_id: project._id}, project, callback
  138. createProject: (name, options, callback = (error, oroject_id) ->) ->
  139. if typeof options == "function"
  140. callback = options
  141. options = {}
  142. @request.post {
  143. url: "/project/new",
  144. json: Object.assign({projectName: name}, options)
  145. }, (error, response, body) ->
  146. return callback(error) if error?
  147. if !body?.project_id?
  148. error = new Error("SOMETHING WENT WRONG CREATING PROJECT", response.statusCode, response.headers["location"], body)
  149. callback error
  150. else
  151. callback(null, body.project_id)
  152. deleteProject: (project_id, callback=(error)) ->
  153. @request.delete {
  154. url: "/project/#{project_id}"
  155. }, (error, response, body) ->
  156. return callback(error) if error?
  157. callback(null)
  158. openProject: (project_id, callback=(error)) ->
  159. @request.get {
  160. url: "/project/#{project_id}"
  161. }, (error, response, body) ->
  162. return callback(error) if error?
  163. if response.statusCode != 200
  164. err = new Error("Non-success response when opening project: #{response.statusCode}")
  165. return callback(err)
  166. callback(null)
  167. createDocInProject: (project_id, parent_folder_id, name, callback=(error, doc_id)->) ->
  168. @getCsrfToken (error) =>
  169. return callback(error) if error?
  170. @request.post {
  171. url: "/project/#{project_id}/doc",
  172. json: {
  173. name: name,
  174. parent_folder_id: parent_folder_id
  175. }
  176. }, (error, response, body) =>
  177. callback(null, body._id)
  178. addUserToProject: (project_id, user, privileges, callback = (error, user) ->) ->
  179. if privileges == 'readAndWrite'
  180. updateOp = {$addToSet: {collaberator_refs: user._id.toString()}}
  181. else if privileges == 'readOnly'
  182. updateOp = {$addToSet: {readOnly_refs: user._id.toString()}}
  183. db.projects.update {_id: db.ObjectId(project_id)}, updateOp, (err) ->
  184. callback(err)
  185. makePublic: (project_id, level, callback = (error) ->) ->
  186. @request.post {
  187. url: "/project/#{project_id}/settings/admin",
  188. json:
  189. publicAccessLevel: level
  190. }, (error, response, body) ->
  191. return callback(error) if error?
  192. callback(null)
  193. makePrivate: (project_id, callback = (error) ->) ->
  194. @request.post {
  195. url: "/project/#{project_id}/settings/admin",
  196. json:
  197. publicAccessLevel: 'private'
  198. }, (error, response, body) ->
  199. return callback(error) if error?
  200. callback(null)
  201. makeTokenBased: (project_id, callback = (error) ->) ->
  202. @request.post {
  203. url: "/project/#{project_id}/settings/admin",
  204. json:
  205. publicAccessLevel: 'tokenBased'
  206. }, (error, response, body) ->
  207. return callback(error) if error?
  208. callback(null)
  209. getCsrfToken: (callback = (error) ->) ->
  210. @request.get {
  211. url: "/dev/csrf"
  212. }, (err, response, body) =>
  213. return callback(err) if err?
  214. @csrfToken = body
  215. @request = @request.defaults({
  216. headers:
  217. "x-csrf-token": @csrfToken
  218. })
  219. callback()
  220. changePassword: (callback = (error) ->) ->
  221. @getCsrfToken (error) =>
  222. return callback(error) if error?
  223. @request.post {
  224. url: "/user/password/update"
  225. json:
  226. currentPassword: @password
  227. newPassword1: @password
  228. newPassword2: @password
  229. }, (error, response, body) =>
  230. return callback(error) if error?
  231. db.users.findOne {email: @email}, (error, user) =>
  232. return callback(error) if error?
  233. callback()
  234. getUserSettingsPage: (callback = (error, statusCode) ->) ->
  235. @getCsrfToken (error) =>
  236. return callback(error) if error?
  237. @request.get {
  238. url: "/user/settings"
  239. }, (error, response, body) =>
  240. return callback(error) if error?
  241. callback(null, response.statusCode)
  242. activateSudoMode: (callback = (error)->) ->
  243. @getCsrfToken (error) =>
  244. return callback(error) if error?
  245. @request.post {
  246. uri: '/confirm-password',
  247. json:
  248. password: @password
  249. }, callback
  250. updateSettings: (newSettings, callback = (error, response, body) ->) ->
  251. @getCsrfToken (error) =>
  252. return callback(error) if error?
  253. @request.post {
  254. url: '/user/settings'
  255. json: newSettings
  256. }, callback
  257. getProjectListPage: (callback=(error, statusCode)->) ->
  258. @getCsrfToken (error) =>
  259. return callback(error) if error?
  260. @request.get {
  261. url: "/project"
  262. }, (error, response, body) =>
  263. return callback(error) if error?
  264. callback(null, response.statusCode)
  265. isLoggedIn: (callback = (error, loggedIn) ->) ->
  266. @request.get "/user/personal_info", (error, response, body) ->
  267. return callback(error) if error?
  268. if response.statusCode == 200
  269. return callback(null, true)
  270. else if response.statusCode == 302
  271. return callback(null, false)
  272. else
  273. return callback(new Error("unexpected status code from /user/personal_info: #{response.statusCode}"))
  274. module.exports = User