@openneuro/server 3.36.5 → 3.36.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openneuro/server",
3
- "version": "3.36.5",
3
+ "version": "3.36.6-alpha.3",
4
4
  "description": "Core service for the OpenNeuro platform.",
5
5
  "license": "MIT",
6
6
  "main": "src/server.js",
@@ -61,6 +61,7 @@
61
61
  "react-dom": "^17.0.1",
62
62
  "redlock": "^4.0.0",
63
63
  "request": "^2.83.0",
64
+ "semver": "^5.5.0",
64
65
  "sitemap": "^2.1.0",
65
66
  "subscriptions-transport-ws": "0.9.18",
66
67
  "superagent": "^3.8.2",
@@ -81,6 +82,7 @@
81
82
  "@types/ioredis": "^4.17.1",
82
83
  "@types/jest": "^26.0.23",
83
84
  "@types/nodemailer": "^6.4.1",
85
+ "@types/semver": "^5",
84
86
  "apollo-link-schema": "^1.2.5",
85
87
  "babel-eslint": "^10.1.0",
86
88
  "core-js": "^3.10.1",
@@ -102,5 +104,5 @@
102
104
  "publishConfig": {
103
105
  "access": "public"
104
106
  },
105
- "gitHead": "2e33b51d4a281f1bf4442c873b48b297eb2ad883"
107
+ "gitHead": "6a4df10b0ebd14c63ce0ec4df651153cb353146d"
106
108
  }
@@ -27,16 +27,20 @@ describe('dataset resolvers', () => {
27
27
  })
28
28
  })
29
29
  describe('snapshotCreationComparison()', () => {
30
- it('sorts array of objects by the "created" property', () => {
30
+ it('sorts array of objects by the "created" and "tag" properties', () => {
31
31
  const testArray = [
32
- { id: 2, created: new Date('2018-11-20T00:05:43.473Z') },
33
- { id: 1, created: new Date('2018-11-19T00:05:43.473Z') },
34
- { id: 3, created: new Date('2018-11-23T00:05:43.473Z') },
32
+ { id: 2, created: new Date('2018-11-20T00:05:43.473Z'), tag: '1.0.0' },
33
+ { id: 1, created: new Date('2018-11-19T00:05:43.473Z'), tag: '1.0.1' },
34
+ { id: 3, created: new Date('2018-11-23T00:05:43.473Z'), tag: '1.0.2' },
35
+ { id: 5, created: new Date('2018-11-23T00:05:43.473Z'), tag: '1.0.10' },
36
+ { id: 4, created: new Date('2018-11-23T00:05:43.473Z'), tag: '1.0.3' },
35
37
  ]
36
38
  const sorted = testArray.sort(ds.snapshotCreationComparison)
37
39
  expect(sorted[0].id).toBe(1)
38
40
  expect(sorted[1].id).toBe(2)
39
41
  expect(sorted[2].id).toBe(3)
42
+ expect(sorted[3].id).toBe(4)
43
+ expect(sorted[4].id).toBe(5)
40
44
  })
41
45
  it('sorts array of objects by the "created" property as strings', () => {
42
46
  const testArray = [
@@ -60,18 +64,16 @@ describe('dataset resolvers', () => {
60
64
  mockingoose.Dataset.toReturn(true, 'count')
61
65
  // capture and check datalad delete request
62
66
  request.del = url => ({
63
- set: (header1, headerValue1) => ({
67
+ set: (header1, headerValue1) => ({
64
68
  set: () => ({
65
- send: ({ filenames}) => {
66
- expect(url).toEqual(
67
- 'http://datalad-0/datasets/ds999999/files',
68
- )
69
+ send: ({ filenames }) => {
70
+ expect(url).toEqual('http://datalad-0/datasets/ds999999/files')
69
71
  expect(filenames).toEqual([':sub-99'])
70
72
  expect(header1).toEqual('Cookie')
71
73
  expect(headerValue1).toMatch(/^accessToken=/)
72
- }
73
- }),
74
+ },
74
75
  }),
76
+ }),
75
77
  })
76
78
 
77
79
  ds.deleteFiles(
@@ -194,6 +194,7 @@ const parseQuery = async (query, datasetType, datasetStatus, userId) => {
194
194
  * @param {any} obj
195
195
  * @param {object} args
196
196
  * @param {object} args.query Stringified Query (DSL) argument for ElasticSearch
197
+ * @param {boolean} args.allDatasets Admin option for returning all datasets (overrides datasetType and datasetStatus, but keeps other search parameters) (default = false)
197
198
  * @param {string} args.datasetType Stringified Query (DSL) argument for ElasticSearch
198
199
  * @param {string} args.datasetStatus Stringified Query (DSL) argument for ElasticSearch
199
200
  * @param {object} args.sortBy Stringified Query (DSL) argument for ElasticSearch
@@ -202,7 +203,7 @@ const parseQuery = async (query, datasetType, datasetStatus, userId) => {
202
203
  */
203
204
  export const advancedDatasetSearchConnection = async (
204
205
  obj,
205
- { query, datasetType, datasetStatus, sortBy, after, first = 25 },
206
+ { query, allDatasets = false, datasetType, datasetStatus, sortBy, after, first = 25 },
206
207
  { user, userInfo },
207
208
  ) => {
208
209
  const searchId = hashObject({
@@ -216,7 +217,9 @@ export const advancedDatasetSearchConnection = async (
216
217
  if (sortBy) sort.unshift(sortBy)
217
218
  const requestBody = {
218
219
  sort,
219
- query: await parseQuery(query, datasetType, datasetStatus, user),
220
+ query: allDatasets
221
+ ? query
222
+ : await parseQuery(query, datasetType, datasetStatus, user),
220
223
  }
221
224
  if (after) {
222
225
  try {
@@ -246,6 +249,7 @@ export const advancedDatasetSearch = {
246
249
  resolve: advancedDatasetSearchConnection,
247
250
  args: {
248
251
  query: { type: 'JSON!' },
252
+ allDatasets: { type: 'Boolean' },
249
253
  datasetType: { type: 'String' },
250
254
  datasetStatus: { type: 'String' },
251
255
  sortBy: { type: 'JSON' },
@@ -23,6 +23,7 @@ import { UpdatedFile } from '../utils/file.js'
23
23
  import { getDatasetWorker } from '../../libs/datalad-service.js'
24
24
  import { getDraftHead } from '../../datalad/dataset.js'
25
25
  import { getFileName } from '../../datalad/files.js'
26
+ import semver from 'semver'
26
27
 
27
28
  export const dataset = async (obj, { id }, { user, userInfo }) => {
28
29
  await checkDatasetRead(id, user, userInfo)
@@ -41,8 +42,14 @@ export const datasets = (parent, args, { user, userInfo }) => {
41
42
  }
42
43
  }
43
44
 
44
- export const snapshotCreationComparison = ({ created: a }, { created: b }) => {
45
- return new Date(a).getTime() - new Date(b).getTime()
45
+ export const snapshotCreationComparison = (
46
+ { created: a, tag: a_tag },
47
+ { created: b, tag: b_tag },
48
+ ) => {
49
+ return (
50
+ new Date(a).getTime() - new Date(b).getTime() ||
51
+ semver.compare(a_tag, b_tag)
52
+ )
46
53
  }
47
54
 
48
55
  /**
@@ -10,9 +10,13 @@ export const summary = async dataset => {
10
10
  datasetId: dataset.id,
11
11
  }).exec()
12
12
  )?.toObject()
13
- return {
14
- ...datasetSummary,
15
- primaryModality: datasetSummary?.modalities[0],
13
+ if (datasetSummary) {
14
+ return {
15
+ ...datasetSummary,
16
+ primaryModality: datasetSummary?.modalities[0],
17
+ }
18
+ } else {
19
+ return null
16
20
  }
17
21
  }
18
22
 
@@ -1,14 +1,17 @@
1
1
  import passport from 'passport'
2
2
 
3
- export const requestAuth = passport.authenticate('google', {
4
- scope: [
5
- 'https://www.googleapis.com/auth/userinfo.email',
6
- 'https://www.googleapis.com/auth/userinfo.profile',
7
- ],
8
- session: false,
9
- accessType: 'offline',
10
- prompt: 'consent',
11
- })
3
+ export const requestAuth = (req, res, next) => (
4
+ passport.authenticate('google', {
5
+ scope: [
6
+ 'https://www.googleapis.com/auth/userinfo.email',
7
+ 'https://www.googleapis.com/auth/userinfo.profile',
8
+ ],
9
+ session: false,
10
+ accessType: 'offline',
11
+ prompt: 'consent',
12
+ state: req.query.redirectPath || null
13
+ })(req, res, next)
14
+ )
12
15
 
13
16
  export const authCallback = passport.authenticate('google', {
14
17
  failureRedirect: '/',
@@ -153,10 +153,13 @@ export const authenticate = (req, res, next) => {
153
153
  }
154
154
 
155
155
  export const authSuccessHandler = (req, res, next) => {
156
+ const redirectPath = req.query.state
157
+ ? Buffer.from(req.query.state, 'base64').toString()
158
+ : '/'
156
159
  if (req.user) {
157
160
  // Set the JWT associated with this login on a cookie
158
161
  res.cookie('accessToken', req.user.token, { sameSite: 'Strict' })
159
- res.redirect('/')
162
+ res.redirect(redirectPath)
160
163
  } else {
161
164
  res.status(401)
162
165
  }
@@ -8,6 +8,7 @@ const subscriptionServerFactory = httpserver =>
8
8
  execute,
9
9
  subscribe,
10
10
  schema,
11
+ keepAlive: 30000,
11
12
  },
12
13
  {
13
14
  server: httpserver,