@openneuro/server 5.1.0 → 5.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openneuro/server",
3
- "version": "5.1.0",
3
+ "version": "5.1.1",
4
4
  "description": "Core service for the OpenNeuro platform.",
5
5
  "license": "MIT",
6
6
  "main": "src/server.js",
@@ -22,7 +22,7 @@
22
22
  "@elastic/elasticsearch": "8.13.1",
23
23
  "@graphql-tools/schema": "^10.0.0",
24
24
  "@keyv/redis": "^4.5.0",
25
- "@openneuro/search": "^5.1.0",
25
+ "@openneuro/search": "^5.1.1",
26
26
  "@pothos/core": "^4.12.0",
27
27
  "@pothos/plugin-directives": "^4.3.0",
28
28
  "@pothos/plugin-simple-objects": "^4.1.3",
@@ -95,5 +95,5 @@
95
95
  "publishConfig": {
96
96
  "access": "public"
97
97
  },
98
- "gitHead": "e3444f63f43cb7e9d3ecfac51d2a42cdcc4f4e60"
98
+ "gitHead": "035b0b4544d4b287506ea00aff3b424ed816611a"
99
99
  }
@@ -23,7 +23,7 @@ describe("dataset model operations", () => {
23
23
  connect(mongod.getUri())
24
24
  })
25
25
  it("resolves to dataset id string", async () => {
26
- const user = { id: "1234" }
26
+ const user = { id: "1234", userId: "1234", admin: false }
27
27
  const { id: dsId } = await createDataset(user.id, user, {
28
28
  affirmedDefaced: true,
29
29
  affirmedConsent: true,
@@ -32,7 +32,7 @@ describe("dataset model operations", () => {
32
32
  expect(dsId.slice(0, 2)).toBe("ds")
33
33
  })
34
34
  it("posts to the DataLad /datasets/{dsId} endpoint", async () => {
35
- const user = { id: "1234" }
35
+ const user = { id: "1234", userId: "1234", admin: false }
36
36
  // Reset call count for request.post
37
37
  request.post.mockClear()
38
38
  const { id: dsId } = await createDataset(user.id, user, {
@@ -34,7 +34,7 @@ describe("snapshot model operations", () => {
34
34
  connect(mongod.getUri())
35
35
  })
36
36
  it("posts to the DataLad /datasets/{dsId}/snapshots/{snapshot} endpoint", async () => {
37
- const user = { id: "1234" }
37
+ const user = { id: "1234", userId: "1234", admin: false }
38
38
  const tag = "snapshot"
39
39
  const { id: dsId } = await createDataset(user.id, user, {
40
40
  affirmedDefaced: true,
@@ -28,8 +28,9 @@ import { getDatasetWorker } from "../libs/datalad-service"
28
28
  import { createEvent, updateEvent } from "../libs/events"
29
29
  import Doi from "../models/doi"
30
30
  import { hideDoi, publishDoi } from "../libs/doi/index"
31
+ import type { UserInfo } from "../graphql/builder"
31
32
 
32
- export const giveUploaderPermission = (datasetId, userId) => {
33
+ export const giveUploaderPermission = (datasetId: string, userId: string) => {
33
34
  const permission = new Permission({ datasetId, userId, level: "admin" })
34
35
  return permission.save()
35
36
  }
@@ -46,8 +47,11 @@ export const giveUploaderPermission = (datasetId, userId) => {
46
47
  */
47
48
  export const createDataset = async (
48
49
  uploader: string,
49
- userInfo,
50
- { affirmedDefaced, affirmedConsent },
50
+ userInfo: UserInfo,
51
+ { affirmedDefaced, affirmedConsent }: {
52
+ affirmedDefaced: boolean
53
+ affirmedConsent: boolean
54
+ },
51
55
  ) => {
52
56
  // Obtain an accession number
53
57
  const datasetId = await getAccessionNumber()
@@ -87,7 +91,9 @@ type DatasetWithRevision = Mongoose.FlattenMaps<DatasetDocument> & {
87
91
  /**
88
92
  * Fetch dataset document and related fields
89
93
  */
90
- export const getDataset = async (id): Promise<DatasetWithRevision | null> => {
94
+ export const getDataset = async (
95
+ id: string,
96
+ ): Promise<DatasetWithRevision | null> => {
91
97
  const dataset = await Dataset.findOne({ id }).lean()
92
98
  return dataset && {
93
99
  ...dataset,
@@ -98,7 +104,7 @@ export const getDataset = async (id): Promise<DatasetWithRevision | null> => {
98
104
  /**
99
105
  * Delete dataset and associated documents
100
106
  */
101
- export const deleteDataset = async (datasetId, user) => {
107
+ export const deleteDataset = async (datasetId: string, user: UserInfo) => {
102
108
  const event = await createEvent(
103
109
  datasetId,
104
110
  user.id,
@@ -498,7 +504,11 @@ export const flagAnnexObject = (
498
504
  /**
499
505
  * Update public state and transition DOI states accordingly.
500
506
  */
501
- export async function updatePublic(datasetId, publicFlag, user) {
507
+ export async function updatePublic(
508
+ datasetId: string,
509
+ publicFlag: boolean,
510
+ user: UserInfo,
511
+ ): Promise<boolean> {
502
512
  const event = await createEvent(
503
513
  datasetId,
504
514
  user.id,
@@ -535,6 +545,8 @@ export async function updatePublic(datasetId, publicFlag, user) {
535
545
  } catch (err) {
536
546
  Sentry.captureException(err)
537
547
  }
548
+ // Return the new public state
549
+ return publicFlag
538
550
  }
539
551
 
540
552
  export const getDatasetAnalytics = (datasetId, _tag) => {
@@ -33,4 +33,15 @@ describe("GraphQL derivatives", () => {
33
33
  })
34
34
  })
35
35
  })
36
+ it("returns expected values for fitlins", () => {
37
+ expect(derivativeObject("ds000002", "fitlins")).toEqual({
38
+ dataladUrl: new URL(
39
+ "https://github.com/OpenNeuroDerivatives/ds000002-fitlins.git",
40
+ ),
41
+ local: false,
42
+ name: "ds000002-fitlins",
43
+ s3Url: new URL("s3://openneuro-derivatives/fitlins/ds000002-fitlins"),
44
+ })
45
+ })
46
+
36
47
  })
@@ -220,7 +220,7 @@ export const updatePublic = (
220
220
  { user, userInfo }: GraphQLContext,
221
221
  ) => {
222
222
  return checkDatasetWrite(datasetId, user, userInfo).then(() => {
223
- return datalad.updatePublic(datasetId, publicFlag, user)
223
+ return datalad.updatePublic(datasetId, publicFlag, userInfo)
224
224
  })
225
225
  }
226
226
 
@@ -6,7 +6,7 @@ const S3_BUCKET = "openneuro-derivatives"
6
6
  const GITHUB_ORGANIZATION = "OpenNeuroDerivatives"
7
7
 
8
8
  // Available derivatives at this time
9
- type GitHubDerivative = "mriqc" | "fmriprep"
9
+ type GitHubDerivative = "mriqc" | "fmriprep" | "fitlins"
10
10
 
11
11
  /**
12
12
  * Test for a derivative on GitHub via API
@@ -90,5 +90,9 @@ export const derivatives = async (
90
90
  if (await githubDerivative(datasetId, "fmriprep")) {
91
91
  available.push(derivativeObject(datasetId, "fmriprep"))
92
92
  }
93
+ if (await githubDerivative(datasetId, "fitlins")) {
94
+ available.push(derivativeObject(datasetId, "fitlins"))
95
+ }
96
+
93
97
  return available
94
98
  }
@@ -25,6 +25,7 @@ export type GraphQLUserType = {
25
25
  githubSynced: Date
26
26
  links: string[]
27
27
  orcidConsent: boolean | null
28
+ profilePrivate: boolean
28
29
  }
29
30
 
30
31
  export async function user(
@@ -50,6 +51,7 @@ export async function user(
50
51
  githubSynced: oneWeekAgo,
51
52
  links: [],
52
53
  orcidConsent: true,
54
+ profilePrivate: false,
53
55
  created: oneWeekAgo,
54
56
  lastSeen: new Date(),
55
57
  updatedAt: oneWeekAgo,
@@ -232,12 +234,13 @@ export const setBlocked = (
232
234
 
233
235
  export const updateUser = async (
234
236
  obj: unknown,
235
- { id, location, institution, links, orcidConsent }: {
237
+ { id, location, institution, links, orcidConsent, profilePrivate }: {
236
238
  id: string
237
239
  location?: string
238
240
  institution?: string
239
241
  links?: string[]
240
242
  orcidConsent?: boolean
243
+ profilePrivate?: boolean
241
244
  },
242
245
  { userInfo }: GraphQLContext,
243
246
  ) => {
@@ -270,6 +273,7 @@ export const updateUser = async (
270
273
  if (institution !== undefined) user.institution = institution
271
274
  if (links !== undefined) user.links = links
272
275
  if (orcidConsent !== undefined) user.orcidConsent = orcidConsent
276
+ if (profilePrivate !== undefined) user.profilePrivate = profilePrivate
273
277
 
274
278
  await user.save()
275
279
 
@@ -25,7 +25,7 @@ import {
25
25
  ValidatorInput,
26
26
  } from "./inputs"
27
27
 
28
- import Mutation from '../resolvers/mutation'
28
+ import Mutation from "../resolvers/mutation"
29
29
 
30
30
  builder.mutationType({
31
31
  fields: (t) => ({
@@ -142,7 +142,8 @@ builder.mutationType({
142
142
  datasetId: t.arg.id({ required: true }),
143
143
  userId: t.arg.string({ required: true }),
144
144
  },
145
- resolve: (root, args) => Mutation.removePermissions(root, args as never) as never,
145
+ resolve: (root, args) =>
146
+ Mutation.removePermissions(root, args as never) as never,
146
147
  }),
147
148
  removeUser: t.boolean({
148
149
  args: {
@@ -177,6 +178,7 @@ builder.mutationType({
177
178
  institution: t.arg.string(),
178
179
  links: t.arg.stringList(),
179
180
  orcidConsent: t.arg.boolean(),
181
+ profilePrivate: t.arg.boolean(),
180
182
  },
181
183
  resolve: (root, args, ctx) =>
182
184
  Mutation.updateUser(root, args as never, ctx),
@@ -47,6 +47,7 @@ UserRef.implement({
47
47
  resolve: (obj, args, ctx) => notifications(obj, args, ctx),
48
48
  }),
49
49
  orcidConsent: t.boolean({ resolve: (obj) => obj.orcidConsent }),
50
+ profilePrivate: t.boolean({ resolve: (obj) => obj.profilePrivate }),
50
51
  }),
51
52
  })
52
53
 
@@ -45,6 +45,8 @@ export interface UserDocument extends Document {
45
45
  githubSynced: Date
46
46
  // Defaults to NULL populated from ORCID Consent Form Mutation
47
47
  orcidConsent?: boolean | null
48
+ // Whether the user has opted out of public profile visibility
49
+ profilePrivate?: boolean
48
50
  givenName?: string
49
51
  familyName?: string
50
52
  }
@@ -73,6 +75,10 @@ const userSchema = new Schema({
73
75
  type: Boolean,
74
76
  default: null,
75
77
  },
78
+ profilePrivate: {
79
+ type: Boolean,
80
+ default: false,
81
+ },
76
82
  }, { timestamps: { createdAt: false, updatedAt: true } })
77
83
 
78
84
  userSchema.index({ id: 1, provider: 1 }, { unique: true })