@openneuro/server 4.16.1 → 4.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/datalad/__tests__/pagination.spec.js +2 -2
- package/src/graphql/resolvers/follow.js +1 -1
- package/src/graphql/resolvers/stars.js +4 -4
- package/src/handlers/{stars.js → stars.ts} +24 -23
- package/src/handlers/subscriptions.js +27 -19
- package/src/libs/authentication/jwt.js +1 -1
- package/src/libs/authentication/orcid.js +21 -3
- package/src/libs/authentication/passport.js +3 -3
- package/src/libs/notifications.js +117 -107
- package/src/libs/orcid.js +15 -5
- package/src/models/__tests__/ingestDataset.spec.ts +6 -9
- package/src/models/dataset.ts +4 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openneuro/server",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.1",
|
|
4
4
|
"description": "Core service for the OpenNeuro platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src/server.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@apollo/client": "3.7.2",
|
|
19
19
|
"@elastic/elasticsearch": "7.15.0",
|
|
20
|
-
"@openneuro/search": "^4.
|
|
20
|
+
"@openneuro/search": "^4.17.1",
|
|
21
21
|
"@passport-next/passport-google-oauth2": "^1.0.0",
|
|
22
22
|
"@sentry/node": "^4.5.3",
|
|
23
23
|
"apollo-server": "2.25.4",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"date-fns": "^2.16.1",
|
|
30
30
|
"draft-js": "^0.11.7",
|
|
31
31
|
"draft-js-export-html": "^1.4.1",
|
|
32
|
-
"elastic-apm-node": "
|
|
32
|
+
"elastic-apm-node": "3.43.0",
|
|
33
33
|
"express": "^4.17.1",
|
|
34
34
|
"graphql": "14.7.0",
|
|
35
35
|
"graphql-bigint": "^1.0.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"jsonwebtoken": "^9.0.0",
|
|
45
45
|
"mime-types": "^2.1.19",
|
|
46
46
|
"moment": "^2.14.1",
|
|
47
|
-
"mongoose": "^
|
|
47
|
+
"mongoose": "^7.0.2",
|
|
48
48
|
"morgan": "^1.6.1",
|
|
49
49
|
"node-mailjet": "^3.3.5",
|
|
50
50
|
"object-hash": "2.1.1",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"publishConfig": {
|
|
93
93
|
"access": "public"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "c93f1fd308cddfbaef9990be47e77497a277b35e"
|
|
96
96
|
}
|
|
@@ -20,7 +20,7 @@ describe('pagination model operations', () => {
|
|
|
20
20
|
})
|
|
21
21
|
describe('apiCursor()', () => {
|
|
22
22
|
it('returns base64 string', () => {
|
|
23
|
-
expect(pagination.apiCursor(ObjectID(5))).toMatch(base64)
|
|
23
|
+
expect(pagination.apiCursor(new ObjectID(5))).toMatch(base64)
|
|
24
24
|
})
|
|
25
25
|
})
|
|
26
26
|
describe('applyCursorToEdges()', () => {
|
|
@@ -40,7 +40,7 @@ describe('pagination model operations', () => {
|
|
|
40
40
|
beforeAll(async () => {
|
|
41
41
|
await connect(globalThis.__MONGO_URI__)
|
|
42
42
|
const ds = new Dataset({
|
|
43
|
-
_id: ObjectID('5bef51a1ed211400c08e5524'),
|
|
43
|
+
_id: new ObjectID('5bef51a1ed211400c08e5524'),
|
|
44
44
|
id: 'ds001001',
|
|
45
45
|
created: new Date('2018-11-16T23:24:17.203Z'),
|
|
46
46
|
modified: new Date('2018-11-16T23:24:25.050Z'),
|
|
@@ -4,19 +4,19 @@ export const starDataset = async (obj, { datasetId }, { user }) => {
|
|
|
4
4
|
const star = await Star.findOne({ datasetId, userId: user }).exec()
|
|
5
5
|
const newStar = {
|
|
6
6
|
datasetId,
|
|
7
|
-
userId: user
|
|
7
|
+
userId: user,
|
|
8
8
|
}
|
|
9
9
|
if (star) {
|
|
10
10
|
// unstar
|
|
11
|
-
return star.
|
|
11
|
+
return star.deleteOne().then(() => ({
|
|
12
12
|
starred: false,
|
|
13
|
-
newStar
|
|
13
|
+
newStar,
|
|
14
14
|
}))
|
|
15
15
|
} else {
|
|
16
16
|
const star = new Star({ datasetId, userId: user })
|
|
17
17
|
return star.save().then(() => ({
|
|
18
18
|
starred: true,
|
|
19
|
-
newStar
|
|
19
|
+
newStar,
|
|
20
20
|
}))
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -18,19 +18,16 @@ export default {
|
|
|
18
18
|
const datasetId = data.datasetId
|
|
19
19
|
const userId = data.userId
|
|
20
20
|
|
|
21
|
-
Star.create(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
)
|
|
21
|
+
Star.create({
|
|
22
|
+
datasetId: datasetId,
|
|
23
|
+
userId: userId,
|
|
24
|
+
})
|
|
25
|
+
.then(response => {
|
|
26
|
+
return res.send(response.$op)
|
|
27
|
+
})
|
|
28
|
+
.catch(err => {
|
|
29
|
+
next(err)
|
|
30
|
+
})
|
|
34
31
|
},
|
|
35
32
|
|
|
36
33
|
/**
|
|
@@ -72,19 +69,23 @@ export default {
|
|
|
72
69
|
if (datasetId) {
|
|
73
70
|
Star.find({
|
|
74
71
|
datasetId: datasetId,
|
|
75
|
-
}).exec((err, stars) => {
|
|
76
|
-
if (err) {
|
|
77
|
-
return next(err)
|
|
78
|
-
}
|
|
79
|
-
res.send(stars)
|
|
80
72
|
})
|
|
73
|
+
.exec()
|
|
74
|
+
.then(stars => {
|
|
75
|
+
res.send(stars)
|
|
76
|
+
})
|
|
77
|
+
.catch(err => {
|
|
78
|
+
return next(err)
|
|
79
|
+
})
|
|
81
80
|
} else {
|
|
82
|
-
Star.find()
|
|
83
|
-
|
|
81
|
+
Star.find()
|
|
82
|
+
.exec()
|
|
83
|
+
.then(stars => {
|
|
84
|
+
res.send(stars)
|
|
85
|
+
})
|
|
86
|
+
.catch(err => {
|
|
84
87
|
return next(err)
|
|
85
|
-
}
|
|
86
|
-
res.send(stars)
|
|
87
|
-
})
|
|
88
|
+
})
|
|
88
89
|
}
|
|
89
90
|
},
|
|
90
91
|
}
|
|
@@ -59,17 +59,21 @@ export const deleteAll = (req, res, next) => {
|
|
|
59
59
|
notifications.datasetDeleted(datasetId)
|
|
60
60
|
Subscription.find({
|
|
61
61
|
datasetId: datasetId,
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
})
|
|
63
|
+
.exec()
|
|
64
|
+
.then(subscriptions => {
|
|
65
|
+
subscriptions.forEach(subscription => {
|
|
66
|
+
Subscription.deleteOne({
|
|
67
|
+
_id: new ObjectID(subscription._id),
|
|
68
|
+
})
|
|
69
69
|
})
|
|
70
|
+
return res.send()
|
|
71
|
+
})
|
|
72
|
+
.catch(err => {
|
|
73
|
+
if (err) {
|
|
74
|
+
return next(err)
|
|
75
|
+
}
|
|
70
76
|
})
|
|
71
|
-
return res.send()
|
|
72
|
-
})
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
// read
|
|
@@ -85,19 +89,23 @@ export const getSubscriptions = (req, res, next) => {
|
|
|
85
89
|
if (datasetId) {
|
|
86
90
|
Subscription.find({
|
|
87
91
|
datasetId: datasetId,
|
|
88
|
-
}).exec((err, subscriptions) => {
|
|
89
|
-
if (err) {
|
|
90
|
-
return next(err)
|
|
91
|
-
}
|
|
92
|
-
res.send(subscriptions)
|
|
93
92
|
})
|
|
93
|
+
.exec()
|
|
94
|
+
.then(subscriptions => {
|
|
95
|
+
res.send(subscriptions)
|
|
96
|
+
})
|
|
97
|
+
.catch(err => {
|
|
98
|
+
return next(err)
|
|
99
|
+
})
|
|
94
100
|
} else {
|
|
95
|
-
Subscription.find()
|
|
96
|
-
|
|
101
|
+
Subscription.find()
|
|
102
|
+
.exec()
|
|
103
|
+
.then(subscriptions => {
|
|
104
|
+
res.send(subscriptions)
|
|
105
|
+
})
|
|
106
|
+
.catch(err => {
|
|
97
107
|
return next(err)
|
|
98
|
-
}
|
|
99
|
-
res.send(subscriptions)
|
|
100
|
-
})
|
|
108
|
+
})
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
|
|
@@ -115,7 +115,7 @@ export const decodeJWT = token => {
|
|
|
115
115
|
return jwt.decode(token)
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
const parsedJwtFromRequest = req => {
|
|
118
|
+
export const parsedJwtFromRequest = req => {
|
|
119
119
|
const jwt = jwtFromRequest(req)
|
|
120
120
|
if (jwt) return decodeJWT(jwt)
|
|
121
121
|
else return null
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import passport from 'passport'
|
|
2
|
+
import User from '../../models/user'
|
|
3
|
+
import { parsedJwtFromRequest } from './jwt.js'
|
|
2
4
|
|
|
3
5
|
export const requestAuth = passport.authenticate('orcid', {
|
|
4
6
|
session: false,
|
|
@@ -16,7 +18,23 @@ export const authCallback = (req, res, next) =>
|
|
|
16
18
|
if (!user) {
|
|
17
19
|
return res.redirect('/')
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
const existingAuth = parsedJwtFromRequest(req)
|
|
22
|
+
if (existingAuth) {
|
|
23
|
+
// Save ORCID to primary account
|
|
24
|
+
User.findOne({ id: existingAuth.sub }, (err, userModel) => {
|
|
25
|
+
if (err) {
|
|
26
|
+
return next(err)
|
|
27
|
+
} else {
|
|
28
|
+
userModel.orcid = user.providerId
|
|
29
|
+
return userModel.save().then(() => {
|
|
30
|
+
res.redirect('/')
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
} else {
|
|
35
|
+
// Complete login with ORCID as primary account
|
|
36
|
+
req.logIn(user, { session: false }, err => {
|
|
37
|
+
return next(err)
|
|
38
|
+
})
|
|
39
|
+
}
|
|
22
40
|
})(req, res, next)
|
|
@@ -55,7 +55,7 @@ export const verifyGoogleUser = (accessToken, refreshToken, profile, done) => {
|
|
|
55
55
|
profileUpdate,
|
|
56
56
|
{ upsert: true, new: true, setDefaultsOnInsert: true },
|
|
57
57
|
)
|
|
58
|
-
.then(user => done(null, addJWT(config)(user)))
|
|
58
|
+
.then(user => done(null, addJWT(config)(user.toObject())))
|
|
59
59
|
.catch(err => done(err, null))
|
|
60
60
|
} else {
|
|
61
61
|
done(profileUpdate, null)
|
|
@@ -80,7 +80,7 @@ export const verifyORCIDUser = (
|
|
|
80
80
|
{ providerId: profile.orcid, provider: profile.provider },
|
|
81
81
|
profileUpdate,
|
|
82
82
|
{ upsert: true, new: true, setDefaultsOnInsert: true },
|
|
83
|
-
).then(user => done(null, addJWT(config)(user)))
|
|
83
|
+
).then(user => done(null, addJWT(config)(user.toObject())))
|
|
84
84
|
})
|
|
85
85
|
.catch(err => done(err, null))
|
|
86
86
|
}
|
|
@@ -110,7 +110,7 @@ export const setupPassportAuth = () => {
|
|
|
110
110
|
// A user must already exist to use a JWT to auth a request
|
|
111
111
|
User.findOne({ id: jwt.sub, provider: jwt.provider })
|
|
112
112
|
.then(user => {
|
|
113
|
-
if (user) done(null, user)
|
|
113
|
+
if (user) done(null, user.toObject())
|
|
114
114
|
else done(null, false)
|
|
115
115
|
})
|
|
116
116
|
.catch(done)
|
|
@@ -116,54 +116,56 @@ const notifications = {
|
|
|
116
116
|
const htmlContent = stateToHTML(contentState)
|
|
117
117
|
|
|
118
118
|
// get all users that are subscribed to the dataset
|
|
119
|
-
Subscription.find({ datasetId: datasetId })
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
'reply-' +
|
|
141
|
-
encodeURIComponent(comment._id) +
|
|
142
|
-
'-' +
|
|
143
|
-
encodeURIComponent(user._id),
|
|
144
|
-
subject: 'Comment Created',
|
|
145
|
-
html: commentCreated({
|
|
119
|
+
Subscription.find({ datasetId: datasetId })
|
|
120
|
+
.exec()
|
|
121
|
+
.then(subscriptions => {
|
|
122
|
+
// create the email object for each user, using subscription userid and scitran
|
|
123
|
+
subscriptions.forEach(subscription => {
|
|
124
|
+
User.findOne({ id: subscription.userId })
|
|
125
|
+
.exec()
|
|
126
|
+
.then(user => {
|
|
127
|
+
if (user && user.email !== userId) {
|
|
128
|
+
const emailContent = {
|
|
129
|
+
_id:
|
|
130
|
+
datasetId +
|
|
131
|
+
'_' +
|
|
132
|
+
subscription._id +
|
|
133
|
+
'_' +
|
|
134
|
+
comment._id +
|
|
135
|
+
'_' +
|
|
136
|
+
'comment_created',
|
|
137
|
+
type: 'email',
|
|
138
|
+
email: {
|
|
139
|
+
to: user.email,
|
|
146
140
|
name: user.name,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
141
|
+
from:
|
|
142
|
+
'reply-' +
|
|
143
|
+
encodeURIComponent(comment._id) +
|
|
144
|
+
'-' +
|
|
145
|
+
encodeURIComponent(user._id),
|
|
146
|
+
subject: 'Comment Created',
|
|
147
|
+
html: commentCreated({
|
|
148
|
+
name: user.name,
|
|
149
|
+
datasetName: bidsId.decodeId(datasetId),
|
|
150
|
+
datasetLabel: datasetLabel,
|
|
151
|
+
commentUserId: userId,
|
|
152
|
+
commentId: commentId,
|
|
153
|
+
dateCreated: moment(comment.createDate).format('MMMM Do'),
|
|
154
|
+
commentContent: htmlContent,
|
|
155
|
+
commentStatus: commentStatus,
|
|
156
|
+
siteUrl:
|
|
157
|
+
url.parse(config.url).protocol +
|
|
158
|
+
'//' +
|
|
159
|
+
url.parse(config.url).hostname,
|
|
160
|
+
}),
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
// send each email to the notification database for distribution
|
|
164
|
+
notifications.send(emailContent)
|
|
160
165
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
})
|
|
166
|
+
})
|
|
167
|
+
})
|
|
165
168
|
})
|
|
166
|
-
})
|
|
167
169
|
},
|
|
168
170
|
|
|
169
171
|
/**
|
|
@@ -180,36 +182,42 @@ const notifications = {
|
|
|
180
182
|
)
|
|
181
183
|
|
|
182
184
|
// get all users that are subscribed to the dataset
|
|
183
|
-
Subscription.find({ datasetId: datasetId })
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
.
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
185
|
+
Subscription.find({ datasetId: datasetId })
|
|
186
|
+
.exec()
|
|
187
|
+
.then(subscriptions => {
|
|
188
|
+
// create the email object for each user, using subscription userid and scitran
|
|
189
|
+
subscriptions.forEach(subscription => {
|
|
190
|
+
User.findOne({ id: subscription.userId })
|
|
191
|
+
.exec()
|
|
192
|
+
.then(user => {
|
|
193
|
+
if (user) {
|
|
194
|
+
const emailContent = {
|
|
195
|
+
_id:
|
|
196
|
+
datasetId +
|
|
197
|
+
'_' +
|
|
198
|
+
subscription._id +
|
|
199
|
+
'_' +
|
|
200
|
+
'dataset_deleted',
|
|
201
|
+
type: 'email',
|
|
202
|
+
email: {
|
|
203
|
+
to: user.email,
|
|
199
204
|
name: user.name,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
subject: 'Dataset Deleted',
|
|
206
|
+
html: datasetDeleted({
|
|
207
|
+
name: user.name,
|
|
208
|
+
datasetName: bidsId.decodeId(datasetId),
|
|
209
|
+
siteUrl:
|
|
210
|
+
url.parse(config.url).protocol +
|
|
211
|
+
'//' +
|
|
212
|
+
url.parse(config.url).hostname,
|
|
213
|
+
}),
|
|
214
|
+
},
|
|
215
|
+
}
|
|
216
|
+
notifications.send(emailContent)
|
|
207
217
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
})
|
|
218
|
+
})
|
|
219
|
+
})
|
|
211
220
|
})
|
|
212
|
-
})
|
|
213
221
|
},
|
|
214
222
|
|
|
215
223
|
/**
|
|
@@ -226,40 +234,42 @@ const notifications = {
|
|
|
226
234
|
)
|
|
227
235
|
|
|
228
236
|
// get all users that are subscribed to the dataset
|
|
229
|
-
Subscription.find({ datasetId: datasetId })
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
html: ownerUnsubscribed({
|
|
237
|
+
Subscription.find({ datasetId: datasetId })
|
|
238
|
+
.exec()
|
|
239
|
+
.then(subscriptions => {
|
|
240
|
+
// create the email object for each user, using subscription userid and scitran
|
|
241
|
+
subscriptions.forEach(subscription => {
|
|
242
|
+
User.findOne({ id: subscription.userId })
|
|
243
|
+
.exec()
|
|
244
|
+
.then(user => {
|
|
245
|
+
if (user) {
|
|
246
|
+
const emailContent = {
|
|
247
|
+
_id:
|
|
248
|
+
datasetId +
|
|
249
|
+
'_' +
|
|
250
|
+
subscription._id +
|
|
251
|
+
'_' +
|
|
252
|
+
'owner_unsubscribed',
|
|
253
|
+
type: 'email',
|
|
254
|
+
email: {
|
|
255
|
+
to: user.email,
|
|
249
256
|
name: user.name,
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
subject: 'Owner Unsubscribed',
|
|
258
|
+
html: ownerUnsubscribed({
|
|
259
|
+
name: user.name,
|
|
260
|
+
datasetName: bidsId.decodeId(datasetId),
|
|
261
|
+
siteUrl:
|
|
262
|
+
url.parse(config.url).protocol +
|
|
263
|
+
'//' +
|
|
264
|
+
url.parse(config.url).hostname,
|
|
265
|
+
}),
|
|
266
|
+
},
|
|
267
|
+
}
|
|
268
|
+
notifications.send(emailContent)
|
|
257
269
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
})
|
|
270
|
+
})
|
|
271
|
+
})
|
|
261
272
|
})
|
|
262
|
-
})
|
|
263
273
|
},
|
|
264
274
|
|
|
265
275
|
/**
|
|
@@ -276,8 +286,9 @@ const notifications = {
|
|
|
276
286
|
)
|
|
277
287
|
|
|
278
288
|
// get all users that are subscribed to the dataset
|
|
279
|
-
await Subscription.find({ datasetId: datasetId })
|
|
280
|
-
(
|
|
289
|
+
await Subscription.find({ datasetId: datasetId })
|
|
290
|
+
.exec()
|
|
291
|
+
.then(subscriptions => {
|
|
281
292
|
// create the email object for each user, using subscription userid and scitran
|
|
282
293
|
subscriptions.forEach(subscription => {
|
|
283
294
|
User.findOne({ id: subscription.userId })
|
|
@@ -312,8 +323,7 @@ const notifications = {
|
|
|
312
323
|
}
|
|
313
324
|
})
|
|
314
325
|
})
|
|
315
|
-
}
|
|
316
|
-
)
|
|
326
|
+
})
|
|
317
327
|
},
|
|
318
328
|
|
|
319
329
|
/**
|
package/src/libs/orcid.js
CHANGED
|
@@ -20,12 +20,22 @@ export default {
|
|
|
20
20
|
},
|
|
21
21
|
(err, res) => {
|
|
22
22
|
if (err) {
|
|
23
|
-
reject({
|
|
23
|
+
return reject({
|
|
24
24
|
message:
|
|
25
25
|
'An unexpected ORCID login failure occurred, please try again later.',
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
let doc
|
|
29
|
+
// Catch issues with parsing this response
|
|
30
|
+
try {
|
|
31
|
+
doc = new xmldoc.XmlDocument(res.body)
|
|
32
|
+
} catch (err) {
|
|
33
|
+
return reject({
|
|
34
|
+
type: 'config',
|
|
35
|
+
message:
|
|
36
|
+
'ORCID auth response invalid, most likely this is a misconfigured ORCID_API_ENDPOINT value',
|
|
37
|
+
})
|
|
38
|
+
}
|
|
29
39
|
let name = doc.valueWithPath(
|
|
30
40
|
'person:person.person:name.personal-details:credit-name',
|
|
31
41
|
)
|
|
@@ -41,13 +51,13 @@ export default {
|
|
|
41
51
|
|
|
42
52
|
if (!name) {
|
|
43
53
|
if (!firstname) {
|
|
44
|
-
reject({
|
|
54
|
+
return reject({
|
|
45
55
|
type: 'given',
|
|
46
56
|
message:
|
|
47
57
|
'Your ORCID account does not have a given name, or it is not public. Please fix your account before continuing.',
|
|
48
58
|
})
|
|
49
59
|
} else if (!lastname) {
|
|
50
|
-
reject({
|
|
60
|
+
return reject({
|
|
51
61
|
type: 'family',
|
|
52
62
|
message:
|
|
53
63
|
'Your ORCID account does not have a family name, or it is not public. Please fix your account before continuing.',
|
|
@@ -58,7 +68,7 @@ export default {
|
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
if (!email) {
|
|
61
|
-
reject({
|
|
71
|
+
return reject({
|
|
62
72
|
type: 'email',
|
|
63
73
|
message:
|
|
64
74
|
'Your ORCID account does not have an e-mail, or your e-mail is not public. Please fix your account before continuing.',
|
|
@@ -6,9 +6,8 @@ vi.mock('ioredis')
|
|
|
6
6
|
describe('IngestDataset model', () => {
|
|
7
7
|
it('IngestDataset model fails if required fields are missing', () => {
|
|
8
8
|
const model = new IngestDataset()
|
|
9
|
-
model.
|
|
10
|
-
|
|
11
|
-
})
|
|
9
|
+
const result = model.validateSync()
|
|
10
|
+
expect(result.name).toEqual('ValidationError')
|
|
12
11
|
})
|
|
13
12
|
it('IngestDataset model URL validation fails with a bad URL', async () => {
|
|
14
13
|
const badUrlModel = new IngestDataset({
|
|
@@ -18,9 +17,8 @@ describe('IngestDataset model', () => {
|
|
|
18
17
|
imported: false,
|
|
19
18
|
notified: false,
|
|
20
19
|
})
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
})
|
|
20
|
+
const result = badUrlModel.validateSync()
|
|
21
|
+
expect(result.name).toEqual('ValidationError')
|
|
24
22
|
})
|
|
25
23
|
it('IngestDataset model URL validation succeeds with a good URL', async () => {
|
|
26
24
|
const goodUrlModel = new IngestDataset({
|
|
@@ -30,8 +28,7 @@ describe('IngestDataset model', () => {
|
|
|
30
28
|
imported: false,
|
|
31
29
|
notified: false,
|
|
32
30
|
})
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
31
|
+
const result = goodUrlModel.validateSync()
|
|
32
|
+
expect(result).toBe(undefined)
|
|
36
33
|
})
|
|
37
34
|
})
|
package/src/models/dataset.ts
CHANGED
|
@@ -74,24 +74,17 @@ datasetSchema.virtual('subscriptions', {
|
|
|
74
74
|
justOne: true,
|
|
75
75
|
})
|
|
76
76
|
|
|
77
|
-
datasetSchema.post('save', dataset => {
|
|
78
|
-
new DatasetChange({
|
|
79
|
-
datasetId: dataset.id,
|
|
80
|
-
created: true,
|
|
81
|
-
}).save()
|
|
82
|
-
})
|
|
83
|
-
|
|
84
77
|
datasetSchema.post('updateOne', function () {
|
|
85
|
-
const datasetId = this.
|
|
86
|
-
new DatasetChange({
|
|
78
|
+
const datasetId = this.getQuery()?.['id']
|
|
79
|
+
return new DatasetChange({
|
|
87
80
|
datasetId,
|
|
88
81
|
modified: true,
|
|
89
82
|
}).save()
|
|
90
83
|
})
|
|
91
84
|
|
|
92
85
|
datasetSchema.post('deleteOne', function () {
|
|
93
|
-
const datasetId = this.
|
|
94
|
-
new DatasetChange({
|
|
86
|
+
const datasetId = this.getQuery()?.['id']
|
|
87
|
+
return new DatasetChange({
|
|
95
88
|
datasetId,
|
|
96
89
|
deleted: true,
|
|
97
90
|
}).save()
|