@openneuro/server 4.37.0 → 4.38.0-alpha.0
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": "4.
|
|
3
|
+
"version": "4.38.0-alpha.0",
|
|
4
4
|
"description": "Core service for the OpenNeuro platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src/server.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@elastic/elasticsearch": "8.13.1",
|
|
22
22
|
"@graphql-tools/schema": "^10.0.0",
|
|
23
23
|
"@keyv/redis": "^4.5.0",
|
|
24
|
-
"@openneuro/search": "^4.
|
|
24
|
+
"@openneuro/search": "^4.38.0-alpha.0",
|
|
25
25
|
"@sentry/node": "^8.25.0",
|
|
26
26
|
"@sentry/profiling-node": "^8.25.0",
|
|
27
27
|
"base64url": "^3.0.0",
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"publishConfig": {
|
|
89
89
|
"access": "public"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "96bbcd19e83fab719a0976be7747eeabc5036ff3"
|
|
92
92
|
}
|
|
@@ -138,13 +138,18 @@ export const checkDatasetWrite = async (
|
|
|
138
138
|
// Quick path for anonymous writes
|
|
139
139
|
throw new Error(state.errorMessage)
|
|
140
140
|
}
|
|
141
|
-
if (userId && !(userInfo.email)) {
|
|
142
|
-
throw new Error("Connect an email to make contributions to OpenNeuro.")
|
|
143
|
-
}
|
|
144
141
|
if (userId && userInfo.admin) {
|
|
145
142
|
// Always allow site admins
|
|
146
143
|
return true
|
|
147
144
|
}
|
|
145
|
+
// Allow worker scoped tokens to make admin actions on specific datasets
|
|
146
|
+
if (userId && userInfo?.worker && datasetId === userInfo?.dataset) {
|
|
147
|
+
return true
|
|
148
|
+
}
|
|
149
|
+
if (userId && !(userInfo.email)) {
|
|
150
|
+
throw new Error("Connect an email to make contributions to OpenNeuro.")
|
|
151
|
+
}
|
|
152
|
+
// Finally check the permissions model if other checks have not returned
|
|
148
153
|
const permission = await Permission.findOne({ datasetId, userId }).exec()
|
|
149
154
|
if (checkPermissionLevel(permission, state)) {
|
|
150
155
|
return true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import FileCheck from "../../models/fileCheck"
|
|
2
|
+
import { checkDatasetAdmin } from "../permissions"
|
|
3
|
+
|
|
4
|
+
export const updateFileCheck = async (
|
|
5
|
+
obj,
|
|
6
|
+
{ datasetId, hexsha, refs, remote, annexFsck },
|
|
7
|
+
{ user, userInfo },
|
|
8
|
+
) => {
|
|
9
|
+
await checkDatasetAdmin(datasetId, user, userInfo)
|
|
10
|
+
return await FileCheck.findOneAndUpdate(
|
|
11
|
+
{ datasetId, hexsha },
|
|
12
|
+
{ datasetId, hexsha, remote, refs, annexFsck },
|
|
13
|
+
{ upsert: true, new: true },
|
|
14
|
+
)
|
|
15
|
+
.lean()
|
|
16
|
+
.exec()
|
|
17
|
+
}
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
} from "./importRemoteDataset"
|
|
46
46
|
import { saveAdminNote } from "./datasetEvents"
|
|
47
47
|
import { createGitEvent } from "./gitEvents"
|
|
48
|
+
import { updateFileCheck } from "./fileCheck"
|
|
48
49
|
|
|
49
50
|
const Mutation = {
|
|
50
51
|
createDataset,
|
|
@@ -93,6 +94,7 @@ const Mutation = {
|
|
|
93
94
|
updateUser,
|
|
94
95
|
saveAdminNote,
|
|
95
96
|
createGitEvent,
|
|
97
|
+
updateFileCheck,
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
export default Mutation
|
package/src/graphql/schema.ts
CHANGED
|
@@ -205,6 +205,14 @@ export const typeDefs = `
|
|
|
205
205
|
saveAdminNote(id: ID, datasetId: ID!, note: String!): DatasetEvent
|
|
206
206
|
# Create a git event log for dataset changes
|
|
207
207
|
createGitEvent(datasetId: ID!, commit: String!, reference: String!): DatasetEvent
|
|
208
|
+
# Create or update a fileCheck document
|
|
209
|
+
updateFileCheck(
|
|
210
|
+
datasetId: ID!
|
|
211
|
+
hexsha: String!
|
|
212
|
+
refs: [String!]!
|
|
213
|
+
annexFsck: [AnnexFsckInput!]!
|
|
214
|
+
remote: String
|
|
215
|
+
): FileCheck
|
|
208
216
|
}
|
|
209
217
|
|
|
210
218
|
# Anonymous dataset reviewer
|
|
@@ -900,6 +908,33 @@ export const typeDefs = `
|
|
|
900
908
|
# Notes associated with the event
|
|
901
909
|
note: String
|
|
902
910
|
}
|
|
911
|
+
|
|
912
|
+
type FileCheck {
|
|
913
|
+
datasetId: String!
|
|
914
|
+
hexsha: String!
|
|
915
|
+
refs: [String!]!
|
|
916
|
+
annexFsck: [AnnexFsck!]
|
|
917
|
+
remote: String
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
type AnnexFsck {
|
|
921
|
+
command: String
|
|
922
|
+
errorMessages: [String]
|
|
923
|
+
file: String
|
|
924
|
+
key: String
|
|
925
|
+
note: String
|
|
926
|
+
success: Boolean
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
input AnnexFsckInput {
|
|
930
|
+
command: String
|
|
931
|
+
errorMessages: [String]
|
|
932
|
+
file: String
|
|
933
|
+
key: String
|
|
934
|
+
note: String
|
|
935
|
+
success: Boolean
|
|
936
|
+
}
|
|
937
|
+
|
|
903
938
|
`
|
|
904
939
|
|
|
905
940
|
schemaComposer.addTypeDefs(typeDefs)
|
|
@@ -120,6 +120,14 @@ export const setupPassportAuth = () => {
|
|
|
120
120
|
(jwt, done) => {
|
|
121
121
|
if (jwt.scopes?.includes("dataset:indexing")) {
|
|
122
122
|
done(null, { admin: false, blocked: false, indexer: true })
|
|
123
|
+
} else if (jwt.scopes?.includes("dataset:worker")) {
|
|
124
|
+
done(null, {
|
|
125
|
+
id: jwt.sub,
|
|
126
|
+
admin: false,
|
|
127
|
+
blocked: false,
|
|
128
|
+
worker: true,
|
|
129
|
+
dataset: jwt.dataset,
|
|
130
|
+
})
|
|
123
131
|
} else if (jwt.scopes?.includes("dataset:reviewer")) {
|
|
124
132
|
done(null, {
|
|
125
133
|
admin: false,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import mongoose from "mongoose"
|
|
2
|
+
import type { Document } from "mongoose"
|
|
3
|
+
const { Schema, model } = mongoose
|
|
4
|
+
|
|
5
|
+
export interface FileCheckDocument extends Document {
|
|
6
|
+
datasetId: string
|
|
7
|
+
hexsha: string
|
|
8
|
+
refs: string[]
|
|
9
|
+
remote: string
|
|
10
|
+
annexFsck: {
|
|
11
|
+
command: string
|
|
12
|
+
"error-messages": string[]
|
|
13
|
+
file: string
|
|
14
|
+
key: string
|
|
15
|
+
note: string
|
|
16
|
+
success: boolean
|
|
17
|
+
}[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const fileCheckSchema = new Schema({
|
|
21
|
+
datasetId: { type: String, required: true },
|
|
22
|
+
hexsha: { type: String, required: true },
|
|
23
|
+
refs: { type: [String], required: true },
|
|
24
|
+
remote: { type: String, default: "local", required: true },
|
|
25
|
+
annexFsck: [{
|
|
26
|
+
command: String,
|
|
27
|
+
"error-messages": [String],
|
|
28
|
+
file: String,
|
|
29
|
+
key: String,
|
|
30
|
+
note: String,
|
|
31
|
+
success: Boolean,
|
|
32
|
+
}],
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const FileCheck = model<FileCheckDocument>("FileCheck", fileCheckSchema)
|
|
36
|
+
|
|
37
|
+
export default FileCheck
|