@openneuro/server 4.20.5 → 4.20.6-alpha.3

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.
Files changed (185) hide show
  1. package/package.json +4 -6
  2. package/src/__mocks__/{config.js → config.ts} +5 -5
  3. package/src/app.ts +32 -31
  4. package/src/cache/item.ts +6 -7
  5. package/src/cache/types.ts +8 -8
  6. package/src/{config.js → config.ts} +6 -6
  7. package/src/datalad/__tests__/changelog.spec.ts +83 -0
  8. package/src/datalad/__tests__/dataset.spec.ts +109 -0
  9. package/src/datalad/__tests__/description.spec.ts +141 -0
  10. package/src/datalad/__tests__/files.spec.ts +77 -0
  11. package/src/datalad/__tests__/pagination.spec.ts +136 -0
  12. package/src/datalad/__tests__/{snapshots.spec.js → snapshots.spec.ts} +17 -17
  13. package/src/datalad/{analytics.js → analytics.ts} +4 -4
  14. package/src/datalad/{changelog.js → changelog.ts} +17 -14
  15. package/src/datalad/{dataset.js → dataset.ts} +95 -93
  16. package/src/datalad/{description.js → description.ts} +37 -37
  17. package/src/datalad/draft.ts +38 -0
  18. package/src/datalad/files.ts +26 -20
  19. package/src/datalad/{pagination.js → pagination.ts} +47 -47
  20. package/src/datalad/{readme.js → readme.ts} +13 -11
  21. package/src/datalad/{reexporter.js → reexporter.ts} +4 -4
  22. package/src/datalad/{snapshots.js → snapshots.ts} +56 -62
  23. package/src/datalad/{upload.js → upload.ts} +7 -5
  24. package/src/elasticsearch/elastic-client.ts +11 -0
  25. package/src/elasticsearch/reindex-dataset.ts +7 -7
  26. package/src/graphql/__tests__/__snapshots__/permissions.spec.ts.snap +5 -0
  27. package/src/graphql/__tests__/{comment.spec.js → comment.spec.ts} +17 -17
  28. package/src/graphql/__tests__/permissions.spec.ts +113 -0
  29. package/src/graphql/{permissions.js → permissions.ts} +14 -14
  30. package/src/graphql/resolvers/__tests__/brainlife.spec.ts +11 -11
  31. package/src/graphql/resolvers/__tests__/{dataset-search.spec.js → dataset-search.spec.ts} +25 -23
  32. package/src/graphql/resolvers/__tests__/dataset.spec.ts +175 -0
  33. package/src/graphql/resolvers/__tests__/derivatives.spec.ts +19 -19
  34. package/src/graphql/resolvers/__tests__/importRemoteDataset.spec.ts +20 -20
  35. package/src/graphql/resolvers/__tests__/permssions.spec.ts +35 -0
  36. package/src/graphql/resolvers/__tests__/snapshots.spec.ts +59 -0
  37. package/src/graphql/resolvers/__tests__/user.spec.ts +18 -0
  38. package/src/graphql/resolvers/brainlife.ts +4 -4
  39. package/src/graphql/resolvers/cache.ts +4 -4
  40. package/src/graphql/resolvers/{comment.js → comment.ts} +16 -16
  41. package/src/graphql/resolvers/{dataset-search.js → dataset-search.ts} +45 -43
  42. package/src/graphql/resolvers/{dataset.js → dataset.ts} +38 -52
  43. package/src/graphql/resolvers/datasetType.ts +3 -3
  44. package/src/graphql/resolvers/derivatives.ts +11 -11
  45. package/src/graphql/resolvers/description.ts +18 -0
  46. package/src/graphql/resolvers/{draft.js → draft.ts} +13 -13
  47. package/src/graphql/resolvers/{flaggedFiles.js → flaggedFiles.ts} +4 -4
  48. package/src/graphql/resolvers/{follow.js → follow.ts} +1 -1
  49. package/src/graphql/resolvers/git.ts +3 -3
  50. package/src/graphql/resolvers/history.ts +13 -0
  51. package/src/graphql/resolvers/importRemoteDataset.ts +12 -11
  52. package/src/graphql/resolvers/index.ts +25 -0
  53. package/src/graphql/resolvers/{issues.js → issues.ts} +9 -9
  54. package/src/graphql/resolvers/metadata.ts +8 -8
  55. package/src/graphql/resolvers/{mutation.js → mutation.ts} +26 -26
  56. package/src/graphql/resolvers/{newsletter.js → newsletter.ts} +2 -2
  57. package/src/graphql/resolvers/permissions.ts +15 -21
  58. package/src/graphql/resolvers/publish.ts +17 -0
  59. package/src/graphql/resolvers/query.ts +21 -0
  60. package/src/graphql/resolvers/{readme.js → readme.ts} +3 -3
  61. package/src/graphql/resolvers/{reexporter.js → reexporter.ts} +2 -2
  62. package/src/graphql/resolvers/relation.ts +5 -5
  63. package/src/graphql/resolvers/{reset.js → reset.ts} +2 -2
  64. package/src/graphql/resolvers/reviewer.ts +4 -4
  65. package/src/graphql/resolvers/{snapshots.js → snapshots.ts} +49 -49
  66. package/src/graphql/resolvers/{stars.js → stars.ts} +1 -1
  67. package/src/graphql/resolvers/summary.ts +3 -3
  68. package/src/graphql/resolvers/{upload.js → upload.ts} +5 -5
  69. package/src/graphql/resolvers/{user.js → user.ts} +16 -18
  70. package/src/graphql/resolvers/{validation.js → validation.ts} +12 -14
  71. package/src/graphql/{schema.js → schema.ts} +4 -6
  72. package/src/graphql/utils/{file.js → file.ts} +2 -2
  73. package/src/handlers/{comments.js → comments.ts} +11 -11
  74. package/src/handlers/{config.js → config.ts} +1 -1
  75. package/src/handlers/{datalad.js → datalad.ts} +22 -22
  76. package/src/handlers/{doi.js → doi.ts} +6 -6
  77. package/src/handlers/reviewer.ts +6 -6
  78. package/src/handlers/{sitemap.js → sitemap.ts} +19 -19
  79. package/src/handlers/stars.ts +11 -10
  80. package/src/handlers/{subscriptions.js → subscriptions.ts} +17 -16
  81. package/src/handlers/{users.js → users.ts} +3 -3
  82. package/src/libs/__tests__/apikey.spec.ts +25 -0
  83. package/src/libs/__tests__/datalad-service.spec.ts +27 -0
  84. package/src/libs/__tests__/{dataset.spec.js → dataset.spec.ts} +9 -9
  85. package/src/libs/{apikey.js → apikey.ts} +5 -5
  86. package/src/libs/authentication/__tests__/jwt.spec.ts +59 -0
  87. package/src/libs/authentication/{crypto.js → crypto.ts} +16 -16
  88. package/src/libs/authentication/google.ts +18 -0
  89. package/src/libs/authentication/jwt.ts +40 -33
  90. package/src/libs/authentication/{orcid.js → orcid.ts} +11 -11
  91. package/src/libs/authentication/{passport.js → passport.ts} +45 -30
  92. package/src/libs/authentication/{states.js → states.ts} +17 -20
  93. package/src/libs/{counter.js → counter.ts} +1 -1
  94. package/src/libs/{datalad-service.js → datalad-service.ts} +4 -4
  95. package/src/libs/dataset.ts +9 -0
  96. package/src/libs/doi/__tests__/__snapshots__/doi.spec.ts.snap +17 -0
  97. package/src/libs/doi/__tests__/doi.spec.ts +25 -0
  98. package/src/libs/doi/__tests__/normalize.spec.ts +19 -19
  99. package/src/libs/doi/{index.js → index.ts} +27 -21
  100. package/src/libs/doi/normalize.ts +2 -2
  101. package/src/libs/email/__tests__/index.spec.ts +14 -14
  102. package/src/libs/email/index.ts +4 -4
  103. package/src/libs/email/templates/__tests__/comment-created.spec.ts +12 -12
  104. package/src/libs/email/templates/__tests__/dataset-deleted.spec.ts +6 -6
  105. package/src/libs/email/templates/__tests__/owner-unsubscribed.spec.ts +6 -6
  106. package/src/libs/email/templates/__tests__/snapshot-created.spec.ts +9 -9
  107. package/src/libs/email/templates/__tests__/snapshot-reminder.spec.ts +7 -7
  108. package/src/libs/email/templates/comment-created.ts +2 -1
  109. package/src/libs/email/templates/dataset-deleted.ts +2 -1
  110. package/src/libs/email/templates/dataset-import-failed.ts +2 -1
  111. package/src/libs/email/templates/dataset-imported.ts +2 -1
  112. package/src/libs/email/templates/owner-unsubscribed.ts +2 -1
  113. package/src/libs/email/templates/snapshot-created.ts +2 -1
  114. package/src/libs/email/templates/snapshot-reminder.ts +2 -1
  115. package/src/libs/{notifications.js → notifications.ts} +100 -113
  116. package/src/libs/{orcid.js → orcid.ts} +20 -20
  117. package/src/libs/{redis.js → redis.ts} +6 -6
  118. package/src/models/__tests__/ingestDataset.spec.ts +15 -15
  119. package/src/models/analytics.ts +2 -2
  120. package/src/models/badAnnexObject.ts +6 -6
  121. package/src/models/comment.ts +10 -10
  122. package/src/models/counter.ts +2 -2
  123. package/src/models/dataset.ts +16 -16
  124. package/src/models/deletion.ts +3 -3
  125. package/src/models/deprecatedSnapshot.ts +2 -2
  126. package/src/models/doi.ts +2 -2
  127. package/src/models/file.ts +2 -2
  128. package/src/models/ingestDataset.ts +4 -4
  129. package/src/models/issue.ts +2 -2
  130. package/src/models/key.ts +2 -2
  131. package/src/models/mailgunIdentifier.ts +2 -2
  132. package/src/models/metadata.ts +3 -3
  133. package/src/models/newsletter.ts +3 -3
  134. package/src/models/notification.ts +2 -2
  135. package/src/models/permission.ts +4 -4
  136. package/src/models/reviewer.ts +7 -7
  137. package/src/models/snapshot.ts +2 -2
  138. package/src/models/stars.ts +6 -6
  139. package/src/models/subscription.ts +2 -2
  140. package/src/models/summary.ts +2 -2
  141. package/src/models/upload.ts +3 -3
  142. package/src/models/user.ts +4 -4
  143. package/src/{routes.js → routes.ts} +62 -62
  144. package/src/server.ts +9 -9
  145. package/src/utils/__tests__/datasetOrSnapshot.spec.ts +25 -25
  146. package/src/utils/__tests__/validateUrl.spec.ts +10 -10
  147. package/src/utils/datasetOrSnapshot.ts +2 -2
  148. package/src/utils/validateUrl.ts +1 -1
  149. package/src/datalad/__tests__/changelog.spec.js +0 -82
  150. package/src/datalad/__tests__/dataset.spec.js +0 -109
  151. package/src/datalad/__tests__/description.spec.js +0 -137
  152. package/src/datalad/__tests__/files.spec.js +0 -75
  153. package/src/datalad/__tests__/pagination.spec.js +0 -136
  154. package/src/datalad/draft.js +0 -37
  155. package/src/elasticsearch/elastic-client.js +0 -11
  156. package/src/graphql/__tests__/permissions.spec.js +0 -107
  157. package/src/graphql/pubsub.js +0 -5
  158. package/src/graphql/resolvers/__tests__/dataset.spec.js +0 -175
  159. package/src/graphql/resolvers/__tests__/permssions.spec.js +0 -34
  160. package/src/graphql/resolvers/__tests__/snapshots.spec.js +0 -58
  161. package/src/graphql/resolvers/__tests__/user.spec.js +0 -17
  162. package/src/graphql/resolvers/description.js +0 -29
  163. package/src/graphql/resolvers/history.js +0 -11
  164. package/src/graphql/resolvers/index.js +0 -25
  165. package/src/graphql/resolvers/publish.js +0 -17
  166. package/src/graphql/resolvers/query.js +0 -21
  167. package/src/graphql/resolvers/subscriptions.js +0 -81
  168. package/src/graphql/utils/publish-draft-update.js +0 -13
  169. package/src/libs/__tests__/apikey.spec.js +0 -24
  170. package/src/libs/__tests__/datalad-service.spec.js +0 -26
  171. package/src/libs/authentication/__tests__/jwt.spec.js +0 -23
  172. package/src/libs/authentication/globus.js +0 -11
  173. package/src/libs/authentication/google.js +0 -19
  174. package/src/libs/bidsId.js +0 -68
  175. package/src/libs/dataset.js +0 -9
  176. package/src/libs/doi/__tests__/doi.spec.js +0 -24
  177. package/src/libs/redis-pubsub.js +0 -5
  178. package/src/libs/request.js +0 -155
  179. package/src/libs/scitran.js +0 -25
  180. package/src/libs/subscription-server.js +0 -20
  181. package/src/libs/testing-utils.js +0 -17
  182. package/src/persistent/datasets/.gitignore +0 -3
  183. package/src/persistent/temp/.gitignore +0 -3
  184. /package/src/libs/__mocks__/{notifications.js → notifications.ts} +0 -0
  185. /package/src/libs/authentication/{verifyUser.js → verifyUser.ts} +0 -0
@@ -1,22 +1,21 @@
1
1
  /*eslint no-console: ["error", { allow: ["log"] }] */
2
- import config from '../config'
3
- import { send as emailSend } from './email'
4
- import request from 'superagent'
5
- import User from '../models/user'
6
- import Subscription from '../models/subscription'
7
- import { format } from 'date-fns'
8
- import url from 'url'
9
- import bidsId from './bidsId'
10
- import { convertFromRaw, EditorState } from 'draft-js'
11
- import { stateToHTML } from 'draft-js-export-html'
12
- import { getDatasetWorker } from '../libs/datalad-service'
13
- import { commentCreated } from '../libs/email/templates/comment-created'
14
- import { datasetDeleted } from '../libs/email/templates/dataset-deleted'
15
- import { ownerUnsubscribed } from '../libs/email/templates/owner-unsubscribed'
16
- import { snapshotCreated } from '../libs/email/templates/snapshot-created'
17
- import { snapshotReminder } from '../libs/email/templates/snapshot-reminder'
18
- import { datasetImportEmail } from '../libs/email/templates/dataset-imported'
19
- import { datasetImportFailed } from '../libs/email/templates/dataset-import-failed'
2
+ import config from "../config"
3
+ import { send as emailSend } from "./email"
4
+ import request from "superagent"
5
+ import User from "../models/user"
6
+ import Subscription from "../models/subscription"
7
+ import { format } from "date-fns"
8
+ import url from "url"
9
+ import { convertFromRaw, EditorState } from "draft-js"
10
+ import { stateToHTML } from "draft-js-export-html"
11
+ import { getDatasetWorker } from "./datalad-service"
12
+ import { commentCreated } from "./email/templates/comment-created"
13
+ import { datasetDeleted } from "./email/templates/dataset-deleted"
14
+ import { ownerUnsubscribed } from "./email/templates/owner-unsubscribed"
15
+ import { snapshotCreated } from "./email/templates/snapshot-created"
16
+ import { snapshotReminder } from "./email/templates/snapshot-reminder"
17
+ import { datasetImportEmail } from "./email/templates/dataset-imported"
18
+ import { datasetImportFailed } from "./email/templates/dataset-import-failed"
20
19
 
21
20
  // public api ---------------------------------------------
22
21
 
@@ -25,7 +24,7 @@ const notifications = {
25
24
  * Send
26
25
  */
27
26
  send(notification) {
28
- if (notification.type === 'email') {
27
+ if (notification.type === "email") {
29
28
  emailSend(notification.email)
30
29
  }
31
30
  },
@@ -42,18 +41,20 @@ const notifications = {
42
41
  const tag = body.tag
43
42
  const uploaderId = uploader ? uploader.id : null
44
43
  const URI = getDatasetWorker(datasetId)
45
- const datasetDescriptionUrl = `${URI}/datasets/${datasetId}/snapshots/${tag}/files/dataset_description.json`
46
- const changesUrl = `${URI}/datasets/${datasetId}/snapshots/${tag}/files/CHANGES`
44
+ const datasetDescriptionUrl =
45
+ `${URI}/datasets/${datasetId}/snapshots/${tag}/files/dataset_description.json`
46
+ const changesUrl =
47
+ `${URI}/datasets/${datasetId}/snapshots/${tag}/files/CHANGES`
47
48
 
48
49
  // get the dataset description
49
50
  const descriptionResponse = await request.get(datasetDescriptionUrl)
50
51
  const description = descriptionResponse.body
51
- const datasetLabel = description.Name ? description.Name : 'Unnamed Dataset'
52
+ const datasetLabel = description.Name ? description.Name : "Unnamed Dataset"
52
53
 
53
54
  // get the snapshot changelog
54
55
  const changesResponse = await request
55
56
  .get(changesUrl)
56
- .responseType('application/octet-stream')
57
+ .responseType("application/octet-stream")
57
58
  const changelog = changesResponse.body
58
59
  ? changesResponse.body.toString()
59
60
  : null
@@ -62,25 +63,24 @@ const notifications = {
62
63
  datasetId: datasetId,
63
64
  }).exec()
64
65
  // create the email object for each user
65
- subscriptions.forEach(async subscription => {
66
+ subscriptions.forEach(async (subscription) => {
66
67
  const user = await User.findOne({ id: subscription.userId }).exec()
67
68
  if (user && user.id !== uploaderId) {
68
69
  const emailContent = {
69
- _id: datasetId + '_' + user._id + '_' + 'snapshot_created',
70
- type: 'email',
70
+ _id: datasetId + "_" + user._id + "_" + "snapshot_created",
71
+ type: "email",
71
72
  email: {
72
73
  to: user.email,
73
74
  name: user.name,
74
- subject: 'Snapshot Created',
75
+ subject: "Snapshot Created",
75
76
  html: snapshotCreated({
76
77
  name: user.name,
77
78
  datasetLabel: datasetLabel,
78
- datasetId: bidsId.decodeId(datasetId),
79
+ datasetId: datasetId,
79
80
  versionNumber: tag,
80
81
  changelog: changelog,
81
- siteUrl:
82
- url.parse(config.url).protocol +
83
- '//' +
82
+ siteUrl: url.parse(config.url).protocol +
83
+ "//" +
84
84
  url.parse(config.url).hostname,
85
85
  }),
86
86
  },
@@ -103,12 +103,13 @@ const notifications = {
103
103
  const datasetLabel = comment.datasetLabel
104
104
  ? comment.datasetLabel
105
105
  : comment.datasetId
106
- const userId =
107
- comment.user && comment.user.email ? comment.user.email : null
106
+ const userId = comment.user && comment.user.email
107
+ ? comment.user.email
108
+ : null
108
109
  const content = comment.text
109
110
  const commentId = comment._id ? comment._id : null
110
111
  const isReply = comment.parentId ? comment.parentId : null
111
- const commentStatus = isReply ? 'reply to a comment' : 'comment'
112
+ const commentStatus = isReply ? "reply to a comment" : "comment"
112
113
  const editorState = EditorState.createWithContent(
113
114
  convertFromRaw(JSON.parse(content)),
114
115
  )
@@ -118,44 +119,41 @@ const notifications = {
118
119
  // get all users that are subscribed to the dataset
119
120
  Subscription.find({ datasetId: datasetId })
120
121
  .exec()
121
- .then(subscriptions => {
122
+ .then((subscriptions) => {
122
123
  // create the email object for each user, using subscription userid and scitran
123
- subscriptions.forEach(subscription => {
124
+ subscriptions.forEach((subscription) => {
124
125
  User.findOne({ id: subscription.userId })
125
126
  .exec()
126
- .then(user => {
127
+ .then((user) => {
127
128
  if (user && user.email !== userId) {
128
129
  const emailContent = {
129
- _id:
130
- datasetId +
131
- '_' +
130
+ _id: datasetId +
131
+ "_" +
132
132
  subscription._id +
133
- '_' +
133
+ "_" +
134
134
  comment._id +
135
- '_' +
136
- 'comment_created',
137
- type: 'email',
135
+ "_" +
136
+ "comment_created",
137
+ type: "email",
138
138
  email: {
139
139
  to: user.email,
140
140
  name: user.name,
141
- from:
142
- 'reply-' +
141
+ from: "reply-" +
143
142
  encodeURIComponent(comment._id) +
144
- '-' +
143
+ "-" +
145
144
  encodeURIComponent(user._id),
146
- subject: 'Comment Created',
145
+ subject: "Comment Created",
147
146
  html: commentCreated({
148
147
  name: user.name,
149
- datasetName: bidsId.decodeId(datasetId),
148
+ datasetName: datasetId,
150
149
  datasetLabel: datasetLabel,
151
150
  commentUserId: userId,
152
151
  commentId: commentId,
153
- dateCreated: format(comment.createDate, 'MMMM Do'),
152
+ dateCreated: format(comment.createDate, "MMMM Do"),
154
153
  commentContent: htmlContent,
155
154
  commentStatus: commentStatus,
156
- siteUrl:
157
- url.parse(config.url).protocol +
158
- '//' +
155
+ siteUrl: url.parse(config.url).protocol +
156
+ "//" +
159
157
  url.parse(config.url).hostname,
160
158
  }),
161
159
  },
@@ -176,39 +174,34 @@ const notifications = {
176
174
  * them that a the dataset has been deleted.
177
175
  */
178
176
  datasetDeleted(datasetId) {
179
- console.log(
180
- 'datasetDeleted notification sent with datasetName:',
181
- bidsId.decodeId(datasetId),
182
- )
177
+ console.log("datasetDeleted notification sent with datasetName:", datasetId)
183
178
 
184
179
  // get all users that are subscribed to the dataset
185
180
  Subscription.find({ datasetId: datasetId })
186
181
  .exec()
187
- .then(subscriptions => {
182
+ .then((subscriptions) => {
188
183
  // create the email object for each user, using subscription userid and scitran
189
- subscriptions.forEach(subscription => {
184
+ subscriptions.forEach((subscription) => {
190
185
  User.findOne({ id: subscription.userId })
191
186
  .exec()
192
- .then(user => {
187
+ .then((user) => {
193
188
  if (user) {
194
189
  const emailContent = {
195
- _id:
196
- datasetId +
197
- '_' +
190
+ _id: datasetId +
191
+ "_" +
198
192
  subscription._id +
199
- '_' +
200
- 'dataset_deleted',
201
- type: 'email',
193
+ "_" +
194
+ "dataset_deleted",
195
+ type: "email",
202
196
  email: {
203
197
  to: user.email,
204
198
  name: user.name,
205
- subject: 'Dataset Deleted',
199
+ subject: "Dataset Deleted",
206
200
  html: datasetDeleted({
207
201
  name: user.name,
208
- datasetName: bidsId.decodeId(datasetId),
209
- siteUrl:
210
- url.parse(config.url).protocol +
211
- '//' +
202
+ datasetName: datasetId,
203
+ siteUrl: url.parse(config.url).protocol +
204
+ "//" +
212
205
  url.parse(config.url).hostname,
213
206
  }),
214
207
  },
@@ -229,38 +222,36 @@ const notifications = {
229
222
  */
230
223
  ownerUnsubscribed(datasetId) {
231
224
  console.log(
232
- 'ownerUnsubscribed notification sent with datasetName:',
233
- bidsId.decodeId(datasetId),
225
+ "ownerUnsubscribed notification sent with datasetName:",
226
+ datasetId,
234
227
  )
235
228
 
236
229
  // get all users that are subscribed to the dataset
237
230
  Subscription.find({ datasetId: datasetId })
238
231
  .exec()
239
- .then(subscriptions => {
232
+ .then((subscriptions) => {
240
233
  // create the email object for each user, using subscription userid and scitran
241
- subscriptions.forEach(subscription => {
234
+ subscriptions.forEach((subscription) => {
242
235
  User.findOne({ id: subscription.userId })
243
236
  .exec()
244
- .then(user => {
237
+ .then((user) => {
245
238
  if (user) {
246
239
  const emailContent = {
247
- _id:
248
- datasetId +
249
- '_' +
240
+ _id: datasetId +
241
+ "_" +
250
242
  subscription._id +
251
- '_' +
252
- 'owner_unsubscribed',
253
- type: 'email',
243
+ "_" +
244
+ "owner_unsubscribed",
245
+ type: "email",
254
246
  email: {
255
247
  to: user.email,
256
248
  name: user.name,
257
- subject: 'Owner Unsubscribed',
249
+ subject: "Owner Unsubscribed",
258
250
  html: ownerUnsubscribed({
259
251
  name: user.name,
260
- datasetName: bidsId.decodeId(datasetId),
261
- siteUrl:
262
- url.parse(config.url).protocol +
263
- '//' +
252
+ datasetName: datasetId,
253
+ siteUrl: url.parse(config.url).protocol +
254
+ "//" +
264
255
  url.parse(config.url).hostname,
265
256
  }),
266
257
  },
@@ -281,38 +272,36 @@ const notifications = {
281
272
  */
282
273
  async snapshotReminder(datasetId) {
283
274
  console.log(
284
- 'snapshotReminder notification sent with datasetName:',
285
- bidsId.decodeId(datasetId),
275
+ "snapshotReminder notification sent with datasetName:",
276
+ datasetId,
286
277
  )
287
278
 
288
279
  // get all users that are subscribed to the dataset
289
280
  await Subscription.find({ datasetId: datasetId })
290
281
  .exec()
291
- .then(subscriptions => {
282
+ .then((subscriptions) => {
292
283
  // create the email object for each user, using subscription userid and scitran
293
- subscriptions.forEach(subscription => {
284
+ subscriptions.forEach((subscription) => {
294
285
  User.findOne({ id: subscription.userId })
295
286
  .exec()
296
- .then(user => {
287
+ .then((user) => {
297
288
  if (user) {
298
289
  const emailContent = {
299
- _id:
300
- datasetId +
301
- '_' +
290
+ _id: datasetId +
291
+ "_" +
302
292
  subscription._id +
303
- '_' +
304
- 'snapshot_reminder',
305
- type: 'email',
293
+ "_" +
294
+ "snapshot_reminder",
295
+ type: "email",
306
296
  email: {
307
297
  to: user.email,
308
298
  name: user.name,
309
- subject: 'Snapshot Reminder',
299
+ subject: "Snapshot Reminder",
310
300
  html: snapshotReminder({
311
301
  name: user.name,
312
- datasetName: bidsId.decodeId(datasetId),
313
- siteUrl:
314
- url.parse(config.url).protocol +
315
- '//' +
302
+ datasetName: datasetId,
303
+ siteUrl: url.parse(config.url).protocol +
304
+ "//" +
316
305
  url.parse(config.url).hostname,
317
306
  datasetId,
318
307
  }),
@@ -340,30 +329,28 @@ const notifications = {
340
329
  html = datasetImportEmail({
341
330
  name: user.name,
342
331
  datasetId: datasetId,
343
- siteUrl:
344
- url.parse(config.url).protocol +
345
- '//' +
332
+ siteUrl: url.parse(config.url).protocol +
333
+ "//" +
346
334
  url.parse(config.url).hostname,
347
335
  })
348
336
  } else {
349
337
  html = datasetImportFailed({
350
338
  name: user.name,
351
339
  datasetId: datasetId,
352
- message: success ? '' : message,
353
- siteUrl:
354
- url.parse(config.url).protocol +
355
- '//' +
340
+ message: success ? "" : message,
341
+ siteUrl: url.parse(config.url).protocol +
342
+ "//" +
356
343
  url.parse(config.url).hostname,
357
344
  retryUrl: retryUrl,
358
345
  })
359
346
  }
360
347
  const emailContent = {
361
- _id: datasetId + '_' + user._id + '_' + 'dataset_imported',
362
- type: 'email',
348
+ _id: datasetId + "_" + user._id + "_" + "dataset_imported",
349
+ type: "email",
363
350
  email: {
364
351
  to: user.email,
365
352
  name: user.name,
366
- subject: `Dataset Import ${success ? 'Success' : 'Failed'}`,
353
+ subject: `Dataset Import ${success ? "Success" : "Failed"}`,
367
354
  html: html,
368
355
  },
369
356
  }
@@ -1,14 +1,14 @@
1
1
  // Camel case rule is disabled since ORCID API uses snake case variables
2
- import request from 'request'
3
- import xmldoc from 'xmldoc'
4
- import config from '../config'
2
+ import request from "request"
3
+ import xmldoc from "xmldoc"
4
+ import config from "../config"
5
5
 
6
6
  export default {
7
7
  getProfile(token) {
8
8
  return new Promise((resolve, reject) => {
9
- const data = token.split(':')
9
+ const data = token.split(":")
10
10
  if (data.length != 2) {
11
- reject('Invalid token')
11
+ reject("Invalid token")
12
12
  }
13
13
  const orcid = data[0]
14
14
  const accessToken = data[1]
@@ -22,7 +22,7 @@ export default {
22
22
  if (err) {
23
23
  return reject({
24
24
  message:
25
- 'An unexpected ORCID login failure occurred, please try again later.',
25
+ "An unexpected ORCID login failure occurred, please try again later.",
26
26
  })
27
27
  }
28
28
  let doc
@@ -31,36 +31,36 @@ export default {
31
31
  doc = new xmldoc.XmlDocument(res.body)
32
32
  } catch (err) {
33
33
  return reject({
34
- type: 'config',
34
+ type: "config",
35
35
  message:
36
- 'ORCID auth response invalid, most likely this is a misconfigured ORCID_API_ENDPOINT value',
36
+ "ORCID auth response invalid, most likely this is a misconfigured ORCID_API_ENDPOINT value",
37
37
  })
38
38
  }
39
39
  let name = doc.valueWithPath(
40
- 'person:person.person:name.personal-details:credit-name',
40
+ "person:person.person:name.personal-details:credit-name",
41
41
  )
42
42
  const firstname = doc.valueWithPath(
43
- 'person:person.person:name.personal-details:given-names',
43
+ "person:person.person:name.personal-details:given-names",
44
44
  )
45
45
  const lastname = doc.valueWithPath(
46
- 'person:person.person:name.personal-details:family-name',
46
+ "person:person.person:name.personal-details:family-name",
47
47
  )
48
48
  const email = doc.valueWithPath(
49
- 'person:person.email:emails.email:email.email:email',
49
+ "person:person.email:emails.email:email.email:email",
50
50
  )
51
51
 
52
52
  if (!name) {
53
53
  if (!firstname) {
54
54
  return reject({
55
- type: 'given',
55
+ type: "given",
56
56
  message:
57
- 'Your ORCID account does not have a given name, or it is not public. Please fix your account before continuing.',
57
+ "Your ORCID account does not have a given name, or it is not public. Please fix your account before continuing.",
58
58
  })
59
59
  } else if (!lastname) {
60
60
  return reject({
61
- type: 'family',
61
+ type: "family",
62
62
  message:
63
- 'Your ORCID account does not have a family name, or it is not public. Please fix your account before continuing.',
63
+ "Your ORCID account does not have a family name, or it is not public. Please fix your account before continuing.",
64
64
  })
65
65
  } else {
66
66
  name = `${firstname} ${lastname}`
@@ -69,9 +69,9 @@ export default {
69
69
 
70
70
  if (!email) {
71
71
  return reject({
72
- type: 'email',
72
+ type: "email",
73
73
  message:
74
- 'Your ORCID account does not have an e-mail, or your e-mail is not public. Please fix your account before continuing.',
74
+ "Your ORCID account does not have an e-mail, or your e-mail is not public. Please fix your account before continuing.",
75
75
  })
76
76
  }
77
77
 
@@ -92,7 +92,7 @@ export default {
92
92
  client_id: config.auth.orcid.clientID,
93
93
  client_secret: config.auth.orcid.clientSecret,
94
94
  redirect_uri: config.auth.orcid.redirectURI,
95
- grant_type: 'refresh_token',
95
+ grant_type: "refresh_token",
96
96
  refresh_token: refreshToken,
97
97
  },
98
98
  json: true,
@@ -115,7 +115,7 @@ export default {
115
115
  client_id: config.auth.orcid.clientID,
116
116
  client_secret: config.auth.orcid.clientSecret,
117
117
  redirect_uri: config.auth.orcid.redirectURI,
118
- grant_type: 'authorization_code',
118
+ grant_type: "authorization_code",
119
119
  code,
120
120
  },
121
121
  json: true,
@@ -1,14 +1,14 @@
1
1
  /*eslint no-console: ["error", { allow: ["log"] }] */
2
2
 
3
3
  // dependencies --------------------------------------------------
4
- import Redis from 'ioredis'
5
- import Redlock from 'redlock'
4
+ import Redis from "ioredis"
5
+ import Redlock from "redlock"
6
6
 
7
7
  let redis = null
8
8
  let redlock = null
9
9
 
10
- const connect = async config => {
11
- return new Promise(resolve => {
10
+ const connect = async (config) => {
11
+ return new Promise((resolve) => {
12
12
  if (!redis) {
13
13
  console.log(
14
14
  'Connecting to Redis "redis://%s:%d/0"',
@@ -17,7 +17,7 @@ const connect = async config => {
17
17
  )
18
18
  redis = new Redis(config)
19
19
  redlock = new Redlock([redis])
20
- redis.on('connect', () => {
20
+ redis.on("connect", () => {
21
21
  resolve(redis)
22
22
  })
23
23
  } else {
@@ -27,4 +27,4 @@ const connect = async config => {
27
27
  }
28
28
 
29
29
  export default { connect }
30
- export { redis, redlock, connect }
30
+ export { connect, redis, redlock }
@@ -1,30 +1,30 @@
1
- import { vi } from 'vitest'
2
- import IngestDataset from '../ingestDataset'
1
+ import { vi } from "vitest"
2
+ import IngestDataset from "../ingestDataset"
3
3
 
4
- vi.mock('ioredis')
4
+ vi.mock("ioredis")
5
5
 
6
- describe('IngestDataset model', () => {
7
- it('IngestDataset model fails if required fields are missing', () => {
6
+ describe("IngestDataset model", () => {
7
+ it("IngestDataset model fails if required fields are missing", () => {
8
8
  const model = new IngestDataset()
9
9
  const result = model.validateSync()
10
- expect(result.name).toEqual('ValidationError')
10
+ expect(result.name).toEqual("ValidationError")
11
11
  })
12
- it('IngestDataset model URL validation fails with a bad URL', async () => {
12
+ it("IngestDataset model URL validation fails with a bad URL", async () => {
13
13
  const badUrlModel = new IngestDataset({
14
- datasetId: 'ds00000',
15
- userId: 'b3df6399-d1be-4e07-b997-9f7aa3ed1f8e',
16
- url: 'this is not a valid URL',
14
+ datasetId: "ds00000",
15
+ userId: "b3df6399-d1be-4e07-b997-9f7aa3ed1f8e",
16
+ url: "this is not a valid URL",
17
17
  imported: false,
18
18
  notified: false,
19
19
  })
20
20
  const result = badUrlModel.validateSync()
21
- expect(result.name).toEqual('ValidationError')
21
+ expect(result.name).toEqual("ValidationError")
22
22
  })
23
- it('IngestDataset model URL validation succeeds with a good URL', async () => {
23
+ it("IngestDataset model URL validation succeeds with a good URL", async () => {
24
24
  const goodUrlModel = new IngestDataset({
25
- datasetId: 'ds00000',
26
- userId: 'b3df6399-d1be-4e07-b997-9f7aa3ed1f8e',
27
- url: 'https://example.com',
25
+ datasetId: "ds00000",
26
+ userId: "b3df6399-d1be-4e07-b997-9f7aa3ed1f8e",
27
+ url: "https://example.com",
28
28
  imported: false,
29
29
  notified: false,
30
30
  })
@@ -1,4 +1,4 @@
1
- import mongoose, { Document } from 'mongoose'
1
+ import mongoose, { Document } from "mongoose"
2
2
  const { Schema, model } = mongoose
3
3
 
4
4
  export interface AnalyticsDocument extends Document {
@@ -17,6 +17,6 @@ const analyticsSchema = new Schema({
17
17
  views: { type: Number, required: false },
18
18
  })
19
19
 
20
- const Analytics = model<AnalyticsDocument>('Analytics', analyticsSchema)
20
+ const Analytics = model<AnalyticsDocument>("Analytics", analyticsSchema)
21
21
 
22
22
  export default Analytics
@@ -1,5 +1,5 @@
1
- import mongoose, { Document } from 'mongoose'
2
- import { UserDocument } from './user'
1
+ import mongoose, { Document } from "mongoose"
2
+ import { UserDocument } from "./user"
3
3
  const ObjectId = mongoose.Schema.Types.ObjectId
4
4
 
5
5
  export interface BadAnnexObject extends Document {
@@ -24,17 +24,17 @@ const badAnnexObject = new mongoose.Schema(
24
24
  filepath: String,
25
25
  annexKey: String,
26
26
  removed: { type: Boolean, default: false },
27
- remover: { type: ObjectId, ref: 'User' },
27
+ remover: { type: ObjectId, ref: "User" },
28
28
  flagged: { type: Boolean, default: false },
29
- flagger: { type: ObjectId, ref: 'User' },
29
+ flagger: { type: ObjectId, ref: "User" },
30
30
  },
31
- { timestamps: { createdAt: 'created_at' } },
31
+ { timestamps: { createdAt: "created_at" } },
32
32
  )
33
33
 
34
34
  badAnnexObject.index({ datasetId: 1, annexKey: 1 }, { unique: true })
35
35
 
36
36
  const BadAnnexObject = mongoose.model<BadAnnexObject>(
37
- 'BadAnnexObject',
37
+ "BadAnnexObject",
38
38
  badAnnexObject,
39
39
  )
40
40
 
@@ -1,4 +1,4 @@
1
- import mongoose, { Document } from 'mongoose'
1
+ import mongoose, { Document } from "mongoose"
2
2
  const { Schema, model } = mongoose
3
3
 
4
4
  export interface CommentDocument extends Document {
@@ -26,21 +26,21 @@ const commentSchema = new Schema(
26
26
  )
27
27
 
28
28
  // Foreign key virtuals
29
- commentSchema.virtual('poster', {
30
- ref: 'User',
31
- localField: 'user._id',
32
- foreignField: 'id',
29
+ commentSchema.virtual("poster", {
30
+ ref: "User",
31
+ localField: "user._id",
32
+ foreignField: "id",
33
33
  justOne: true,
34
34
  })
35
35
 
36
36
  // Foreign key virtuals
37
- commentSchema.virtual('parent', {
38
- ref: 'Comment',
39
- localField: 'parentId',
40
- foreignField: '_id',
37
+ commentSchema.virtual("parent", {
38
+ ref: "Comment",
39
+ localField: "parentId",
40
+ foreignField: "_id",
41
41
  justOne: true,
42
42
  })
43
43
 
44
- const Comment = model<CommentDocument>('Comment', commentSchema)
44
+ const Comment = model<CommentDocument>("Comment", commentSchema)
45
45
 
46
46
  export default Comment