| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117 |
- const OError = require('@overleaf/o-error')
- const request = require('./request')
- const settings = require('@overleaf/settings')
- const { db, ObjectId } = require('../../../../app/src/infrastructure/mongodb')
- const UserModel = require('../../../../app/src/models/User').User
- const UserUpdater = require('../../../../app/src/Features/User/UserUpdater')
- const AuthenticationManager = require('../../../../app/src/Features/Authentication/AuthenticationManager')
- const { promisifyClass } = require('@overleaf/promise-utils')
- const fs = require('fs')
- const Path = require('path')
- let count = settings.test.counterInit
- class User {
- constructor(options) {
- if (options == null) {
- options = {}
- }
- this.emails = [
- {
- email: options.email || `acceptance-test-${count}@example.com`,
- createdAt: new Date(),
- confirmedAt: options.confirmedAt,
- },
- ]
- this.email = this.emails[0].email
- this.password = `a-terrible-secret-${count}`
- count++
- this.jar = request.jar()
- this.request = request.defaults({
- jar: this.jar,
- })
- }
- getSession(callback) {
- this.request.get(
- {
- url: '/dev/session',
- },
- (err, response, body) => {
- if (err != null) {
- return callback(err)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `get session failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- const session = JSON.parse(response.body)
- callback(null, session)
- }
- )
- }
- getEmailConfirmationCode(callback) {
- this.getSession((err, session) => {
- if (err != null) {
- return callback(err)
- }
- const code = session.pendingUserRegistration?.confirmCode
- if (!code) {
- return callback(new Error('No confirmation code found in session'))
- }
- callback(null, code)
- })
- }
- resetCookies() {
- this.jar = request.jar()
- this.request = request.defaults({
- jar: this.jar,
- })
- }
- setExtraAttributes(user) {
- if ((user != null ? user._id : undefined) == null) {
- throw new Error('User does not exist')
- }
- this.id = user._id.toString()
- this._id = user._id.toString()
- this.first_name = user.first_name
- this.referal_id = user.referal_id
- this.enrollment = user.enrollment
- }
- get(callback) {
- db.users.findOne({ _id: new ObjectId(this._id) }, callback)
- }
- getAuditLog(callback) {
- this.get((error, user) => {
- if (error) return callback(error)
- if (!user) return callback(new Error('User not found'))
- db.userAuditLogEntries
- .find({ userId: new ObjectId(this._id) })
- .toArray((error, auditLog) => {
- if (error) return callback(error)
- callback(null, auditLog || [])
- })
- })
- }
- getAuditLogWithoutNoise(callback) {
- this.getAuditLog((error, auditLog) => {
- if (error) return callback(error)
- callback(
- null,
- auditLog.filter(entry => {
- return entry.operation !== 'login'
- })
- )
- })
- }
- mongoUpdate(updateOp, callback) {
- db.users.updateOne({ _id: new ObjectId(this._id) }, updateOp, callback)
- }
- register(callback) {
- this.registerWithQuery('', callback)
- }
- registerWithQuery(query, callback) {
- if (this._id != null) {
- return callback(new Error('User already registered'))
- }
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: `/register${query}`,
- json: { email: this.email, password: this.password },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `register failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- this.getEmailConfirmationCode((error, code) => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: '/registration/confirm-email',
- json: { code },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `email confirmation failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- db.users.findOne({ email: this.email }, (error, user) => {
- if (error != null) {
- return callback(error)
- }
- this.setExtraAttributes(user)
- callback(null, user)
- })
- }
- )
- })
- }
- )
- })
- }
- login(callback) {
- this.loginWith(this.email, callback)
- }
- loginWith(email, callback) {
- this.ensureUserExists(error => {
- if (error != null) {
- return callback(error)
- }
- this.loginWithEmailPassword(email, this.password, callback)
- })
- }
- loginNoUpdate(callback) {
- this.loginWithEmailPassword(this.email, this.password, callback)
- }
- loginWithEmailPassword(email, password, callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: settings.enableLegacyLogin ? '/login/legacy' : '/login',
- json: {
- email,
- password,
- 'g-recaptcha-response': 'valid',
- },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new OError(
- `login failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`,
- { response, body }
- )
- )
- }
- // get new csrf token, then return result of login
- this.getCsrfToken(err => {
- if (err) {
- return callback(OError.tag(err, 'after login'))
- }
- callback(null, response, body)
- })
- }
- )
- })
- }
- ensureUserExists(callback) {
- const filter = { email: this.email }
- const options = { upsert: true, new: true, setDefaultsOnInsert: true }
- AuthenticationManager.hashPassword(
- this.password,
- (error, hashedPassword) => {
- if (error != null) {
- return callback(error)
- }
- UserModel.findOneAndUpdate(
- filter,
- { $set: { hashedPassword, emails: this.emails } },
- options,
- (error, user) => {
- if (error != null) {
- return callback(error)
- }
- this.setExtraAttributes(user)
- callback(null, this.password)
- }
- )
- }
- )
- }
- setFeatures(features, callback) {
- const update = {}
- for (const key in features) {
- const value = features[key]
- update[`features.${key}`] = value
- }
- UserModel.updateOne({ _id: this.id }, update, callback)
- }
- setFeaturesOverride(featuresOverride, callback) {
- const update = { $push: { featuresOverrides: featuresOverride } }
- UserModel.updateOne({ _id: this.id }, update, callback)
- }
- setOverleafId(overleafId, callback) {
- UserModel.updateOne(
- { _id: this.id },
- { 'overleaf.id': overleafId },
- callback
- )
- }
- setEmails(emails, callback) {
- UserModel.updateOne({ _id: this.id }, { emails }, callback)
- }
- setSuspended(suspended, callback) {
- UserModel.updateOne({ _id: this.id }, { suspended }, callback)
- }
- logout(callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: '/logout',
- json: {
- email: this.email,
- password: this.password,
- },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `logout failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- db.users.findOne({ email: this.email }, (error, user) => {
- if (error != null) {
- return callback(error)
- }
- if (user == null) {
- return callback()
- }
- this.id = user._id.toString()
- this._id = user._id.toString()
- callback()
- })
- }
- )
- })
- }
- addEmail(email, callback) {
- this.emails.push({ email, createdAt: new Date() })
- UserUpdater.addEmailAddress(
- this.id,
- email,
- {},
- { initiatorId: this._id, ipAddress: '127:0:0:0' },
- callback
- )
- }
- confirmEmail(email, callback) {
- for (let idx = 0; idx < this.emails.length; idx++) {
- const emailData = this.emails[idx]
- if (emailData.email === email) {
- this.emails[idx].confirmedAt = new Date()
- }
- }
- UserUpdater.confirmEmail(this.id, email, callback)
- }
- ensureAdmin(callback) {
- this.mongoUpdate({ $set: { isAdmin: true } }, callback)
- }
- ensureStaffAccess(flag, callback) {
- const update = { $set: {} }
- update.$set[`staffAccess.${flag}`] = true
- this.mongoUpdate(update, callback)
- }
- upgradeFeatures(callback) {
- const features = {
- collaborators: -1, // Infinite
- versioning: true,
- dropbox: true,
- compileTimeout: 60,
- compileGroup: 'priority',
- templates: true,
- references: true,
- trackChanges: true,
- trackChangesVisible: true,
- }
- this.mongoUpdate({ $set: { features } }, callback)
- }
- downgradeFeatures(callback) {
- const features = {
- collaborators: 1,
- versioning: false,
- dropbox: false,
- compileTimeout: 60,
- compileGroup: 'standard',
- templates: false,
- references: false,
- trackChanges: false,
- trackChangesVisible: false,
- }
- this.mongoUpdate({ $set: { features } }, callback)
- }
- defaultFeatures(callback) {
- const features = settings.defaultFeatures
- this.mongoUpdate({ $set: { features } }, callback)
- }
- getFeatures(callback) {
- db.users.findOne(
- { _id: new ObjectId(this.id) },
- { projection: { features: 1 } },
- (error, user) => callback(error, user && user.features)
- )
- }
- fullDeleteUser(email, callback) {
- db.users.findOne({ email }, (error, user) => {
- if (error != null) {
- return callback(error)
- }
- if (user == null) {
- return callback()
- }
- const userId = user._id
- db.projects.deleteMany({ owner_ref: new ObjectId(userId) }, err => {
- if (err != null) {
- callback(err)
- }
- db.users.deleteOne({ _id: new ObjectId(userId) }, callback)
- })
- })
- }
- deleteUser(callback) {
- this.getCsrfToken(error => {
- if (error) {
- return callback(error)
- }
- this.request.post(
- {
- url: '/user/delete',
- json: { password: this.password },
- },
- (err, response, body) => {
- if (err) {
- return callback(err)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `user deletion failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- })
- }
- getProject(projectId, callback) {
- db.projects.findOne({ _id: new ObjectId(projectId.toString()) }, callback)
- }
- saveProject(project, callback) {
- db.projects.updateOne({ _id: project._id }, { $set: project }, callback)
- }
- createProject(name, options, callback) {
- if (typeof options === 'function') {
- callback = options
- options = {}
- }
- this.request.post(
- {
- url: '/project/new',
- json: Object.assign({ projectName: name }, options),
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `project creation failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- if ((body != null ? body.project_id : undefined) == null) {
- error = new Error(
- JSON.stringify([
- 'SOMETHING WENT WRONG CREATING PROJECT',
- name,
- options,
- response.statusCode,
- response.headers.location,
- body,
- ])
- )
- callback(error)
- } else {
- callback(null, body.project_id)
- }
- }
- )
- }
- deleteProject(projectId, callback) {
- this.request.delete(
- {
- url: `/project/${projectId}`,
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `project deletion failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null)
- }
- )
- }
- undeleteProject(projectId, callback) {
- this.request.post(
- {
- url: `/admin/project/${projectId}/undelete`,
- },
- (error, response, body) => {
- if (error) {
- return callback(error)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `project un-deletion failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null)
- }
- )
- }
- deleteProjects(callback) {
- db.projects.deleteMany({ owner_ref: new ObjectId(this.id) }, callback)
- }
- openProject(projectId, callback) {
- this.request.get(
- {
- url: `/project/${projectId}`,
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `opening project failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null)
- }
- )
- }
- createDocInProject(projectId, parentFolderId, name, callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: `/project/${projectId}/doc`,
- json: {
- name,
- parentFolderId,
- },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `doc creation in project failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null, body._id)
- }
- )
- })
- }
- uploadFileInProject(projectId, folderId, file, name, contentType, callback) {
- const fileStream = fs.createReadStream(
- Path.resolve(Path.join(__dirname, '..', '..', 'files', file))
- )
- this.request.post(
- {
- uri: `project/${projectId}/upload`,
- qs: {
- folder_id: String(folderId),
- },
- formData: {
- name,
- qqfile: {
- value: fileStream,
- options: {
- filename: name,
- contentType,
- },
- },
- },
- },
- (error, response, body) => {
- if (error) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `uploading file failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null, JSON.parse(body).entity_id)
- }
- )
- }
- uploadExampleFileInProject(projectId, folderId, name, callback) {
- this.uploadFileInProject(
- projectId,
- folderId,
- '1pixel.png',
- name,
- 'image/png',
- callback
- )
- }
- moveItemInProject(projectId, type, itemId, folderId, callback) {
- this.request.post(
- {
- uri: `project/${projectId}/${type}/${itemId}/move`,
- json: {
- folder_id: folderId,
- },
- },
- (error, response, body) => {
- if (error) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `move item in project failed: type=${type} status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- }
- renameItemInProject(projectId, type, itemId, name, callback) {
- this.request.post(
- {
- uri: `project/${projectId}/${type}/${itemId}/rename`,
- json: {
- name,
- },
- },
- (error, response, body) => {
- if (error) {
- return callback(error)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `rename item in project failed: type=${type} status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- }
- deleteItemInProject(projectId, type, itemId, callback) {
- this.request.delete(
- `project/${projectId}/${type}/${itemId}`,
- (error, response, body) => {
- if (error) {
- return callback(error)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `delete item in project failed: type=${type} status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- }
- joinProject(projectId, callback) {
- this.request.post(
- {
- url: `/project/${projectId}/join`,
- auth: {
- user: settings.apis.web.user,
- pass: settings.apis.web.pass,
- sendImmediately: true,
- },
- json: { userId: this._id },
- jar: false,
- },
- (error, response, body) => {
- if (error) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `join project failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null, body)
- }
- )
- }
- addUserToProject(projectId, user, privileges, callback) {
- let updateOp
- if (privileges === 'readAndWrite') {
- updateOp = { $addToSet: { collaberator_refs: user._id } }
- } else if (privileges === 'readOnly') {
- updateOp = { $addToSet: { readOnly_refs: user._id } }
- }
- db.projects.updateOne({ _id: new ObjectId(projectId) }, updateOp, callback)
- }
- makePublic(projectId, level, callback) {
- // A fudge, to get around the fact that `readOnly` and `readAndWrite` are now disallowed
- // via the API, but we still need to test the behaviour of projects with these values set.
- db.projects.updateOne(
- { _id: new ObjectId(projectId) },
- // NOTE: Yes, there is a typo in the db schema.
- { $set: { publicAccesLevel: level } },
- callback
- )
- }
- makePrivate(projectId, callback) {
- this.request.post(
- {
- url: `/project/${projectId}/settings/admin`,
- json: {
- publicAccessLevel: 'private',
- },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `disable link sharing failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null)
- }
- )
- }
- makeTokenBased(projectId, callback) {
- this.request.post(
- {
- url: `/project/${projectId}/settings/admin`,
- json: {
- publicAccessLevel: 'tokenBased',
- },
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `enable link sharing failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null)
- }
- )
- }
- getCsrfToken(callback) {
- this.request.get(
- {
- url: '/dev/csrf',
- },
- (err, response, body) => {
- if (err != null) {
- return callback(err)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `get csrf token failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- this.csrfToken = body
- this.request = this.request.defaults({
- headers: {
- 'x-csrf-token': this.csrfToken,
- },
- })
- callback()
- }
- )
- }
- changePassword(newPassword, callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: '/user/password/update',
- json: {
- currentPassword: this.password,
- newPassword1: newPassword,
- newPassword2: newPassword,
- },
- },
- (err, response, body) => {
- if (err) {
- return callback(err)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `change password failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- this.password = newPassword
- callback()
- }
- )
- })
- }
- reconfirmAccountRequest(userEmail, callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: '/user/reconfirm',
- json: {
- email: userEmail,
- },
- },
- (error, response) => {
- callback(error, response)
- }
- )
- })
- }
- getUserSettingsPage(callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.get(
- {
- url: '/user/settings',
- },
- (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `open settings page failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback(null, response.statusCode)
- }
- )
- })
- }
- updateSettings(newSettings, callback) {
- this.getCsrfToken(error => {
- if (error != null) {
- return callback(error)
- }
- this.request.post(
- {
- url: '/user/settings',
- json: newSettings,
- },
- (err, response, body) => {
- if (err) return callback(err)
- if (response.statusCode !== 200) {
- return callback(
- new Error(
- `login failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- })
- }
- getProjectListPage(callback) {
- this.request.get('/project', (error, response) => {
- if (error != null) {
- return callback(error)
- }
- callback(null, response.statusCode)
- })
- }
- isLoggedIn(callback) {
- this.request.get('/user/personal_info', (error, response, body) => {
- if (error != null) {
- return callback(error)
- }
- if (response.statusCode === 200) {
- callback(null, true)
- } else if (response.statusCode === 302) {
- callback(null, false)
- } else {
- callback(
- new Error(
- `unexpected status code from /user/personal_info: status=${response.statusCode} body=${body}`
- )
- )
- }
- })
- }
- transferProjectOwnership(projectId, userId, callback) {
- this.getCsrfToken(err => {
- if (err != null) {
- return callback(err)
- }
- this.request.post(
- {
- url: `/project/${projectId.toString()}/transfer-ownership`,
- json: {
- user_id: userId.toString(),
- },
- },
- (err, response, body) => {
- if (err != null) {
- return callback(err)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `transfer project ownership failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- })
- }
- setV1Id(v1Id, callback) {
- UserModel.updateOne(
- {
- _id: this._id,
- },
- {
- overleaf: {
- id: v1Id,
- },
- },
- callback
- )
- }
- setCollaboratorInfo(projectId, userId, info, callback) {
- this.getCsrfToken(err => {
- if (err != null) {
- return callback(err)
- }
- this.request.put(
- {
- url: `/project/${projectId.toString()}/users/${userId.toString()}`,
- json: info,
- },
- (err, response, body) => {
- if (err != null) {
- return callback(err)
- }
- if (response.statusCode !== 204) {
- return callback(
- new Error(
- `update collaborator access failed: status=${
- response.statusCode
- } body=${JSON.stringify(body)}`
- )
- )
- }
- callback()
- }
- )
- })
- }
- }
- User.promises = promisifyClass(User, {
- without: ['setExtraAttributes'],
- })
- User.promises.prototype.doRequest = async function (method, params) {
- return new Promise((resolve, reject) => {
- this.request[method.toLowerCase()](params, (err, response, body) => {
- if (err) {
- reject(err)
- } else {
- resolve({ response, body })
- }
- })
- })
- }
- module.exports = User
|