@openneuro/server 4.2.5-alpha.0 → 4.3.0-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/Dockerfile CHANGED
@@ -11,7 +11,8 @@ WORKDIR /srv
11
11
  COPY --from=build /srv/packages/openneuro-server/package.json /srv/package.json
12
12
  COPY --from=build /srv/.yarnrc.yml /srv/.yarnrc.yml
13
13
  COPY --from=build /srv/.yarn /srv/.yarn
14
- COPY --from=build /srv/.pnp.js /srv/.pnp.js
14
+ COPY --from=build /srv/.pnp.cjs /srv/.pnp.cjs
15
+ COPY --from=build /srv/.pnp.loader.mjs /srv/.pnp.loader.mjs
15
16
  COPY --from=build /srv/packages/openneuro-server/dist /srv/packages/openneuro-server/dist
16
17
 
17
18
  HEALTHCHECK --interval=10s --retries=10 CMD curl -f 'http://localhost:8111' || exit 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openneuro/server",
3
- "version": "4.2.5-alpha.0",
3
+ "version": "4.3.0-alpha.3",
4
4
  "description": "Core service for the OpenNeuro platform.",
5
5
  "license": "MIT",
6
6
  "main": "src/server.js",
@@ -89,7 +89,6 @@
89
89
  "ioredis-mock": "^3.8.1",
90
90
  "jest": "^26.6.3",
91
91
  "mockingoose": "2.11.0",
92
- "mongo-mock": "3.7.1",
93
92
  "nodemon": "^2.0.7",
94
93
  "supertest": "^3.0.0",
95
94
  "ts-node-dev": "1.1.6",
@@ -104,5 +103,5 @@
104
103
  "publishConfig": {
105
104
  "access": "public"
106
105
  },
107
- "gitHead": "d72d3bbe43716e22497d07621736302c2330749f"
106
+ "gitHead": "28a399f30997634ecd417539006c188f4249c9a6"
108
107
  }
@@ -1,4 +1,3 @@
1
- jest.unmock('mongodb')
2
1
  import mongoose from 'mongoose'
3
2
 
4
3
  export default mongoose
@@ -3,24 +3,13 @@ import { users } from '../user.js'
3
3
  describe('user resolvers', () => {
4
4
  describe('users()', () => {
5
5
  it('throws an error for non-admins', () => {
6
- expect(() =>
6
+ expect(
7
7
  users(
8
8
  null,
9
9
  { id: '3311cfe8-9764-434d-b80e-1b1ee72c686d' },
10
10
  { userInfo: {} },
11
11
  ),
12
- ).toThrowError()
13
- })
14
- it('admins should be able to override restrictions', () => {
15
- expect(() =>
16
- users(
17
- null,
18
- { id: '3311cfe8-9764-434d-b80e-1b1ee72c686d' },
19
- {
20
- userInfo: { admin: true },
21
- },
22
- ),
23
- ).not.toThrowError()
12
+ ).rejects.toEqual(new Error('You must be a site admin to retrieve users'))
24
13
  })
25
14
  })
26
15
  })
@@ -15,6 +15,7 @@ import {
15
15
  createSnapshot,
16
16
  deleteSnapshot,
17
17
  deprecateSnapshot,
18
+ undoDeprecateSnapshot,
18
19
  } from './snapshots.js'
19
20
  import { removeUser, setAdmin, setBlocked } from './user.js'
20
21
  import { updateSummary } from './summary.js'
@@ -44,6 +45,7 @@ const Mutation = {
44
45
  flagAnnexObject,
45
46
  createSnapshot,
46
47
  deprecateSnapshot,
48
+ undoDeprecateSnapshot,
47
49
  deleteSnapshot,
48
50
  updateSummary,
49
51
  updateValidation,
@@ -9,10 +9,6 @@ import { getFiles, filterFiles } from '../../datalad/files.js'
9
9
  import DatasetModel from '../../models/dataset'
10
10
  import { filterRemovedAnnexObjects } from '../utils/file.js'
11
11
  import DeprecatedSnapshot from '../../models/deprecatedSnapshot'
12
- import { checkDatasetAdmin } from '../permissions.js'
13
- import SnapshotModel from '../../models/snapshot'
14
- import User from '../../models/user'
15
- import * as Sentry from '@sentry/node'
16
12
  import { redis } from '../../libs/redis'
17
13
  import CacheItem, { CacheType } from '../../cache/item'
18
14
  import { normalizeDOI } from '../../libs/doi/normalize'
@@ -34,15 +30,16 @@ export const snapshot = (obj, { datasetId, tag }, context) => {
34
30
  getFiles(datasetId, snapshot.hexsha)
35
31
  .then(filterFiles(prefix))
36
32
  .then(filterRemovedAnnexObjects(datasetId, context.userInfo)),
37
- deprecated: () => deprecated(snapshot),
33
+ deprecated: () => deprecated({ datasetId, tag }),
38
34
  related: () => related(datasetId),
39
35
  }))
40
36
  },
41
37
  )
42
38
  }
43
39
 
44
- export const deprecated = snapshot => {
45
- return DeprecatedSnapshot.findOne({ id: snapshot.hexsha }).populate('user')
40
+ export const deprecated = ({ datasetId, tag }) => {
41
+ const id = `${datasetId}:${tag}`
42
+ return DeprecatedSnapshot.findOne({ id }).lean().exec()
46
43
  }
47
44
 
48
45
  /**
@@ -89,22 +86,41 @@ export const deprecateSnapshot = async (
89
86
  { datasetId, tag, reason },
90
87
  { user, userInfo },
91
88
  ) => {
92
- try {
93
- await checkDatasetAdmin(datasetId, user, userInfo)
94
- const [snapshot, userDoc] = await Promise.all([
95
- SnapshotModel.findOne({ datasetId, tag }),
96
- User.findOne({ id: user }),
97
- ])
98
- await DeprecatedSnapshot.create({
99
- id: snapshot.hexsha,
100
- user: userDoc._id,
101
- cause: reason,
102
- timestamp: new Date(),
103
- })
104
- return true
105
- } catch (err) {
106
- Sentry.captureException(err)
107
- throw err
89
+ const id = `${datasetId}:${tag}`
90
+ await checkDatasetWrite(datasetId, user, userInfo)
91
+ const timestamp = new Date()
92
+ await DeprecatedSnapshot.updateOne(
93
+ { id },
94
+ {
95
+ id,
96
+ user,
97
+ reason,
98
+ timestamp,
99
+ },
100
+ { upsert: true },
101
+ )
102
+ return {
103
+ id,
104
+ deprecated: {
105
+ id,
106
+ user,
107
+ reason,
108
+ timestamp,
109
+ },
110
+ }
111
+ }
112
+
113
+ export const undoDeprecateSnapshot = async (
114
+ obj,
115
+ { datasetId, tag },
116
+ { user, userInfo },
117
+ ) => {
118
+ const id = `${datasetId}:${tag}`
119
+ await checkDatasetWrite(datasetId, user, userInfo)
120
+ await DeprecatedSnapshot.findOneAndDelete({ id })
121
+ return {
122
+ id,
123
+ deprecated: null,
108
124
  }
109
125
  }
110
126
 
@@ -13,7 +13,9 @@ export const users = (obj, args, { userInfo }) => {
13
13
  if (userInfo.admin) {
14
14
  return User.find().exec()
15
15
  } else {
16
- throw new Error('You must be a site admin to retrieve users')
16
+ return Promise.reject(
17
+ new Error('You must be a site admin to retrieve users'),
18
+ )
17
19
  }
18
20
  }
19
21
 
@@ -21,7 +23,7 @@ export const removeUser = (obj, { id }, { userInfo }) => {
21
23
  if (userInfo.admin) {
22
24
  return User.findByIdAndRemove(id).exec()
23
25
  } else {
24
- throw new Error('You must be a site admin to remove users')
26
+ return Promise.reject(new Error('You must be a site admin to remove users'))
25
27
  }
26
28
  }
27
29
 
@@ -29,7 +31,9 @@ export const setAdmin = (obj, { id, admin }, { userInfo }) => {
29
31
  if (userInfo.admin) {
30
32
  return User.findOneAndUpdate({ id }, { admin }).exec()
31
33
  } else {
32
- throw new Error('You must be a site admin to modify this value')
34
+ return Promise.reject(
35
+ new Error('You must be a site admin to modify this value'),
36
+ )
33
37
  }
34
38
  }
35
39
 
@@ -37,7 +41,7 @@ export const setBlocked = (obj, { id, blocked }, { userInfo }) => {
37
41
  if (userInfo.admin) {
38
42
  return User.findOneAndUpdate({ id }, { blocked }).exec()
39
43
  } else {
40
- throw new Error('You must be a site admin to block a user')
44
+ return Promise.reject(new Error('You must be a site admin to block a user'))
41
45
  }
42
46
  }
43
47
 
@@ -176,7 +176,9 @@ export const typeDefs = `
176
176
  # Reset draft commit
177
177
  resetDraft(datasetId: ID!, ref: String!): Boolean
178
178
  # Flag snapshot as deprecated
179
- deprecateSnapshot(datasetId: ID!, tag: String!, reason: String!): Boolean
179
+ deprecateSnapshot(datasetId: ID!, tag: String!, reason: String!): Snapshot
180
+ # Unflag snapshot as deprecated
181
+ undoDeprecateSnapshot(datasetId: ID!, tag: String!): Snapshot
180
182
  # Create anonymous read only reviewer
181
183
  createReviewer(datasetId: ID!): DatasetReviewer
182
184
  # Remove reviewer
@@ -485,9 +487,9 @@ export const typeDefs = `
485
487
  # hexsha of deprecated snapshots
486
488
  id: ID!
487
489
  # ID of user who flagged snapshot as deprecated
488
- user: User
490
+ user: String
489
491
  # Reason for deprecating snaphot
490
- cause: String
492
+ reason: String
491
493
  # Timestamp of snapshot deprecation
492
494
  timestamp: Date
493
495
  }
@@ -4,7 +4,7 @@ const { Schema, model } = mongoose
4
4
  export interface DeprecatedSnapshotDocument extends Document {
5
5
  id: string // snapshot hexsha
6
6
  user: string
7
- cause: string
7
+ reason: string
8
8
  timestamp: Date
9
9
  }
10
10
 
@@ -13,9 +13,8 @@ const deprecatedSnapshotSchema = new Schema({
13
13
  user: {
14
14
  type: String,
15
15
  required: true,
16
- ref: 'User',
17
16
  },
18
- cause: {
17
+ reason: {
19
18
  type: String,
20
19
  required: true,
21
20
  },
@@ -1,5 +0,0 @@
1
- import mongodb from 'mongo-mock'
2
-
3
- mongodb.max_delay = 0
4
-
5
- module.exports = mongodb