@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.
- package/package.json +4 -6
- package/src/__mocks__/{config.js → config.ts} +5 -5
- package/src/app.ts +32 -31
- package/src/cache/item.ts +6 -7
- package/src/cache/types.ts +8 -8
- package/src/{config.js → config.ts} +6 -6
- package/src/datalad/__tests__/changelog.spec.ts +83 -0
- package/src/datalad/__tests__/dataset.spec.ts +109 -0
- package/src/datalad/__tests__/description.spec.ts +141 -0
- package/src/datalad/__tests__/files.spec.ts +77 -0
- package/src/datalad/__tests__/pagination.spec.ts +136 -0
- package/src/datalad/__tests__/{snapshots.spec.js → snapshots.spec.ts} +17 -17
- package/src/datalad/{analytics.js → analytics.ts} +4 -4
- package/src/datalad/{changelog.js → changelog.ts} +17 -14
- package/src/datalad/{dataset.js → dataset.ts} +95 -93
- package/src/datalad/{description.js → description.ts} +37 -37
- package/src/datalad/draft.ts +38 -0
- package/src/datalad/files.ts +26 -20
- package/src/datalad/{pagination.js → pagination.ts} +47 -47
- package/src/datalad/{readme.js → readme.ts} +13 -11
- package/src/datalad/{reexporter.js → reexporter.ts} +4 -4
- package/src/datalad/{snapshots.js → snapshots.ts} +56 -62
- package/src/datalad/{upload.js → upload.ts} +7 -5
- package/src/elasticsearch/elastic-client.ts +11 -0
- package/src/elasticsearch/reindex-dataset.ts +7 -7
- package/src/graphql/__tests__/__snapshots__/permissions.spec.ts.snap +5 -0
- package/src/graphql/__tests__/{comment.spec.js → comment.spec.ts} +17 -17
- package/src/graphql/__tests__/permissions.spec.ts +113 -0
- package/src/graphql/{permissions.js → permissions.ts} +14 -14
- package/src/graphql/resolvers/__tests__/brainlife.spec.ts +11 -11
- package/src/graphql/resolvers/__tests__/{dataset-search.spec.js → dataset-search.spec.ts} +25 -23
- package/src/graphql/resolvers/__tests__/dataset.spec.ts +175 -0
- package/src/graphql/resolvers/__tests__/derivatives.spec.ts +19 -19
- package/src/graphql/resolvers/__tests__/importRemoteDataset.spec.ts +20 -20
- package/src/graphql/resolvers/__tests__/permssions.spec.ts +35 -0
- package/src/graphql/resolvers/__tests__/snapshots.spec.ts +59 -0
- package/src/graphql/resolvers/__tests__/user.spec.ts +18 -0
- package/src/graphql/resolvers/brainlife.ts +4 -4
- package/src/graphql/resolvers/cache.ts +4 -4
- package/src/graphql/resolvers/{comment.js → comment.ts} +16 -16
- package/src/graphql/resolvers/{dataset-search.js → dataset-search.ts} +45 -43
- package/src/graphql/resolvers/{dataset.js → dataset.ts} +38 -52
- package/src/graphql/resolvers/datasetType.ts +3 -3
- package/src/graphql/resolvers/derivatives.ts +11 -11
- package/src/graphql/resolvers/description.ts +18 -0
- package/src/graphql/resolvers/{draft.js → draft.ts} +13 -13
- package/src/graphql/resolvers/{flaggedFiles.js → flaggedFiles.ts} +4 -4
- package/src/graphql/resolvers/{follow.js → follow.ts} +1 -1
- package/src/graphql/resolvers/git.ts +3 -3
- package/src/graphql/resolvers/history.ts +13 -0
- package/src/graphql/resolvers/importRemoteDataset.ts +12 -11
- package/src/graphql/resolvers/index.ts +25 -0
- package/src/graphql/resolvers/{issues.js → issues.ts} +9 -9
- package/src/graphql/resolvers/metadata.ts +8 -8
- package/src/graphql/resolvers/{mutation.js → mutation.ts} +26 -26
- package/src/graphql/resolvers/{newsletter.js → newsletter.ts} +2 -2
- package/src/graphql/resolvers/permissions.ts +15 -21
- package/src/graphql/resolvers/publish.ts +17 -0
- package/src/graphql/resolvers/query.ts +21 -0
- package/src/graphql/resolvers/{readme.js → readme.ts} +3 -3
- package/src/graphql/resolvers/{reexporter.js → reexporter.ts} +2 -2
- package/src/graphql/resolvers/relation.ts +5 -5
- package/src/graphql/resolvers/{reset.js → reset.ts} +2 -2
- package/src/graphql/resolvers/reviewer.ts +4 -4
- package/src/graphql/resolvers/{snapshots.js → snapshots.ts} +49 -49
- package/src/graphql/resolvers/{stars.js → stars.ts} +1 -1
- package/src/graphql/resolvers/summary.ts +3 -3
- package/src/graphql/resolvers/{upload.js → upload.ts} +5 -5
- package/src/graphql/resolvers/{user.js → user.ts} +16 -18
- package/src/graphql/resolvers/{validation.js → validation.ts} +12 -14
- package/src/graphql/{schema.js → schema.ts} +4 -6
- package/src/graphql/utils/{file.js → file.ts} +2 -2
- package/src/handlers/{comments.js → comments.ts} +11 -11
- package/src/handlers/{config.js → config.ts} +1 -1
- package/src/handlers/{datalad.js → datalad.ts} +22 -22
- package/src/handlers/{doi.js → doi.ts} +6 -6
- package/src/handlers/reviewer.ts +6 -6
- package/src/handlers/{sitemap.js → sitemap.ts} +19 -19
- package/src/handlers/stars.ts +11 -10
- package/src/handlers/{subscriptions.js → subscriptions.ts} +17 -16
- package/src/handlers/{users.js → users.ts} +3 -3
- package/src/libs/__tests__/apikey.spec.ts +25 -0
- package/src/libs/__tests__/datalad-service.spec.ts +27 -0
- package/src/libs/__tests__/{dataset.spec.js → dataset.spec.ts} +9 -9
- package/src/libs/{apikey.js → apikey.ts} +5 -5
- package/src/libs/authentication/__tests__/jwt.spec.ts +59 -0
- package/src/libs/authentication/{crypto.js → crypto.ts} +16 -16
- package/src/libs/authentication/google.ts +18 -0
- package/src/libs/authentication/jwt.ts +40 -33
- package/src/libs/authentication/{orcid.js → orcid.ts} +11 -11
- package/src/libs/authentication/{passport.js → passport.ts} +45 -30
- package/src/libs/authentication/{states.js → states.ts} +17 -20
- package/src/libs/{counter.js → counter.ts} +1 -1
- package/src/libs/{datalad-service.js → datalad-service.ts} +4 -4
- package/src/libs/dataset.ts +9 -0
- package/src/libs/doi/__tests__/__snapshots__/doi.spec.ts.snap +17 -0
- package/src/libs/doi/__tests__/doi.spec.ts +25 -0
- package/src/libs/doi/__tests__/normalize.spec.ts +19 -19
- package/src/libs/doi/{index.js → index.ts} +27 -21
- package/src/libs/doi/normalize.ts +2 -2
- package/src/libs/email/__tests__/index.spec.ts +14 -14
- package/src/libs/email/index.ts +4 -4
- package/src/libs/email/templates/__tests__/comment-created.spec.ts +12 -12
- package/src/libs/email/templates/__tests__/dataset-deleted.spec.ts +6 -6
- package/src/libs/email/templates/__tests__/owner-unsubscribed.spec.ts +6 -6
- package/src/libs/email/templates/__tests__/snapshot-created.spec.ts +9 -9
- package/src/libs/email/templates/__tests__/snapshot-reminder.spec.ts +7 -7
- package/src/libs/email/templates/comment-created.ts +2 -1
- package/src/libs/email/templates/dataset-deleted.ts +2 -1
- package/src/libs/email/templates/dataset-import-failed.ts +2 -1
- package/src/libs/email/templates/dataset-imported.ts +2 -1
- package/src/libs/email/templates/owner-unsubscribed.ts +2 -1
- package/src/libs/email/templates/snapshot-created.ts +2 -1
- package/src/libs/email/templates/snapshot-reminder.ts +2 -1
- package/src/libs/{notifications.js → notifications.ts} +100 -113
- package/src/libs/{orcid.js → orcid.ts} +20 -20
- package/src/libs/{redis.js → redis.ts} +6 -6
- package/src/models/__tests__/ingestDataset.spec.ts +15 -15
- package/src/models/analytics.ts +2 -2
- package/src/models/badAnnexObject.ts +6 -6
- package/src/models/comment.ts +10 -10
- package/src/models/counter.ts +2 -2
- package/src/models/dataset.ts +16 -16
- package/src/models/deletion.ts +3 -3
- package/src/models/deprecatedSnapshot.ts +2 -2
- package/src/models/doi.ts +2 -2
- package/src/models/file.ts +2 -2
- package/src/models/ingestDataset.ts +4 -4
- package/src/models/issue.ts +2 -2
- package/src/models/key.ts +2 -2
- package/src/models/mailgunIdentifier.ts +2 -2
- package/src/models/metadata.ts +3 -3
- package/src/models/newsletter.ts +3 -3
- package/src/models/notification.ts +2 -2
- package/src/models/permission.ts +4 -4
- package/src/models/reviewer.ts +7 -7
- package/src/models/snapshot.ts +2 -2
- package/src/models/stars.ts +6 -6
- package/src/models/subscription.ts +2 -2
- package/src/models/summary.ts +2 -2
- package/src/models/upload.ts +3 -3
- package/src/models/user.ts +4 -4
- package/src/{routes.js → routes.ts} +62 -62
- package/src/server.ts +9 -9
- package/src/utils/__tests__/datasetOrSnapshot.spec.ts +25 -25
- package/src/utils/__tests__/validateUrl.spec.ts +10 -10
- package/src/utils/datasetOrSnapshot.ts +2 -2
- package/src/utils/validateUrl.ts +1 -1
- package/src/datalad/__tests__/changelog.spec.js +0 -82
- package/src/datalad/__tests__/dataset.spec.js +0 -109
- package/src/datalad/__tests__/description.spec.js +0 -137
- package/src/datalad/__tests__/files.spec.js +0 -75
- package/src/datalad/__tests__/pagination.spec.js +0 -136
- package/src/datalad/draft.js +0 -37
- package/src/elasticsearch/elastic-client.js +0 -11
- package/src/graphql/__tests__/permissions.spec.js +0 -107
- package/src/graphql/pubsub.js +0 -5
- package/src/graphql/resolvers/__tests__/dataset.spec.js +0 -175
- package/src/graphql/resolvers/__tests__/permssions.spec.js +0 -34
- package/src/graphql/resolvers/__tests__/snapshots.spec.js +0 -58
- package/src/graphql/resolvers/__tests__/user.spec.js +0 -17
- package/src/graphql/resolvers/description.js +0 -29
- package/src/graphql/resolvers/history.js +0 -11
- package/src/graphql/resolvers/index.js +0 -25
- package/src/graphql/resolvers/publish.js +0 -17
- package/src/graphql/resolvers/query.js +0 -21
- package/src/graphql/resolvers/subscriptions.js +0 -81
- package/src/graphql/utils/publish-draft-update.js +0 -13
- package/src/libs/__tests__/apikey.spec.js +0 -24
- package/src/libs/__tests__/datalad-service.spec.js +0 -26
- package/src/libs/authentication/__tests__/jwt.spec.js +0 -23
- package/src/libs/authentication/globus.js +0 -11
- package/src/libs/authentication/google.js +0 -19
- package/src/libs/bidsId.js +0 -68
- package/src/libs/dataset.js +0 -9
- package/src/libs/doi/__tests__/doi.spec.js +0 -24
- package/src/libs/redis-pubsub.js +0 -5
- package/src/libs/request.js +0 -155
- package/src/libs/scitran.js +0 -25
- package/src/libs/subscription-server.js +0 -20
- package/src/libs/testing-utils.js +0 -17
- package/src/persistent/datasets/.gitignore +0 -3
- package/src/persistent/temp/.gitignore +0 -3
- /package/src/libs/__mocks__/{notifications.js → notifications.ts} +0 -0
- /package/src/libs/authentication/{verifyUser.js → verifyUser.ts} +0 -0
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { updatePermissions } from '../permissions'
|
|
2
|
-
|
|
3
|
-
vi.mock('ioredis')
|
|
4
|
-
vi.mock('../../permissions', () => ({
|
|
5
|
-
checkDatasetAdmin: async () => Promise.resolve(),
|
|
6
|
-
}))
|
|
7
|
-
|
|
8
|
-
const mockExec = vi.fn()
|
|
9
|
-
|
|
10
|
-
vi.mock('../../../models/user', () => ({
|
|
11
|
-
find: () => ({
|
|
12
|
-
exec: mockExec,
|
|
13
|
-
}),
|
|
14
|
-
}))
|
|
15
|
-
|
|
16
|
-
describe('permissions resolvers', () => {
|
|
17
|
-
describe('updatePermissions()', () => {
|
|
18
|
-
it('throws an error when no users are found', async () => {
|
|
19
|
-
mockExec.mockResolvedValue([])
|
|
20
|
-
let error
|
|
21
|
-
try {
|
|
22
|
-
await updatePermissions(
|
|
23
|
-
{},
|
|
24
|
-
{ datasetId: 'ds01234', userEmail: 'fake@test.com' },
|
|
25
|
-
{},
|
|
26
|
-
)
|
|
27
|
-
} catch (err) {
|
|
28
|
-
error = err
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return expect(error).toBeInstanceOf(Error)
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
})
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { matchKnownObjects, filterLatestSnapshot } from '../snapshots.js'
|
|
2
|
-
|
|
3
|
-
vi.mock('ioredis')
|
|
4
|
-
vi.mock('../../../config.js')
|
|
5
|
-
|
|
6
|
-
describe('snapshot resolvers', () => {
|
|
7
|
-
describe('matchKnownObjects()', () => {
|
|
8
|
-
it('should return NDA as a source when given a description containing 10.15154 DOIs', () => {
|
|
9
|
-
expect(
|
|
10
|
-
matchKnownObjects({
|
|
11
|
-
ReferencesAndLinks: [
|
|
12
|
-
'10.18112/openneuro.ds000001.v1.0.0',
|
|
13
|
-
'10.15154/1503209',
|
|
14
|
-
],
|
|
15
|
-
}).sort(),
|
|
16
|
-
).toEqual([
|
|
17
|
-
{
|
|
18
|
-
id: '10.18112/openneuro.ds000001.v1.0.0',
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
id: '10.15154/1503209',
|
|
22
|
-
source: 'NDA',
|
|
23
|
-
type: 'dataset',
|
|
24
|
-
},
|
|
25
|
-
])
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
describe('filterLatestSnapshot()', () => {
|
|
29
|
-
it('returns the latest snapshot', () => {
|
|
30
|
-
const testSnapshots = [
|
|
31
|
-
{
|
|
32
|
-
id: 'ds000247:00002',
|
|
33
|
-
created: '2018-07-18T02:27:39.000Z',
|
|
34
|
-
tag: '00002',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: 'ds000247:00001',
|
|
38
|
-
created: '2018-07-18T02:35:37.000Z',
|
|
39
|
-
tag: '00001',
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
id: 'ds000247:1.0.0',
|
|
43
|
-
created: '2021-07-05T15:58:18.000Z',
|
|
44
|
-
tag: '1.0.0',
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: 'ds000247:1.0.1',
|
|
48
|
-
created: '2021-08-25T23:37:53.000Z',
|
|
49
|
-
tag: '1.0.1',
|
|
50
|
-
},
|
|
51
|
-
]
|
|
52
|
-
expect(filterLatestSnapshot(testSnapshots)).toBe('1.0.1')
|
|
53
|
-
})
|
|
54
|
-
it('returns null with no snapshots', () => {
|
|
55
|
-
expect(filterLatestSnapshot([])).toBeNull()
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
})
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { users } from '../user.js'
|
|
2
|
-
|
|
3
|
-
vi.mock('ioredis')
|
|
4
|
-
|
|
5
|
-
describe('user resolvers', () => {
|
|
6
|
-
describe('users()', () => {
|
|
7
|
-
it('throws an error for non-admins', () => {
|
|
8
|
-
expect(
|
|
9
|
-
users(
|
|
10
|
-
null,
|
|
11
|
-
{ id: '3311cfe8-9764-434d-b80e-1b1ee72c686d' },
|
|
12
|
-
{ userInfo: {} },
|
|
13
|
-
),
|
|
14
|
-
).rejects.toEqual(new Error('You must be a site admin to retrieve users'))
|
|
15
|
-
})
|
|
16
|
-
})
|
|
17
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolver implementation for dataset_description.json
|
|
3
|
-
*/
|
|
4
|
-
import { setDescription } from '../../datalad/description.js'
|
|
5
|
-
import { checkDatasetWrite } from '../permissions.js'
|
|
6
|
-
export { description } from '../../datalad/description.js'
|
|
7
|
-
import pubsub from '../pubsub.js'
|
|
8
|
-
|
|
9
|
-
export const updateDescription = (
|
|
10
|
-
obj,
|
|
11
|
-
{ datasetId, field, value },
|
|
12
|
-
{ user, userInfo },
|
|
13
|
-
) => {
|
|
14
|
-
return checkDatasetWrite(datasetId, user, userInfo)
|
|
15
|
-
.then(() => setDescription(datasetId, userInfo, { [field]: value }))
|
|
16
|
-
.then(description => {
|
|
17
|
-
pubsub.publish('draftUpdated', {
|
|
18
|
-
datasetId: description.id,
|
|
19
|
-
draftUpdated: {
|
|
20
|
-
draft: {
|
|
21
|
-
description,
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
})
|
|
25
|
-
return description
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const updateDescriptionList = updateDescription
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { getDatasetWorker } from '../../libs/datalad-service.js'
|
|
2
|
-
|
|
3
|
-
export const history = async obj => {
|
|
4
|
-
const datasetId = obj.id
|
|
5
|
-
const historyUrl = `http://${getDatasetWorker(
|
|
6
|
-
datasetId,
|
|
7
|
-
)}/datasets/${datasetId}/history`
|
|
8
|
-
const resp = await fetch(historyUrl)
|
|
9
|
-
const { log } = await resp.json()
|
|
10
|
-
return log
|
|
11
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { GraphQLDate, GraphQLTime, GraphQLDateTime } from 'graphql-iso-date'
|
|
2
|
-
import GraphQLBigInt from 'graphql-bigint'
|
|
3
|
-
import Query from './query.js'
|
|
4
|
-
import Mutation from './mutation.js'
|
|
5
|
-
import Dataset from './dataset.js'
|
|
6
|
-
import Draft from './draft.js'
|
|
7
|
-
import Snapshot from './snapshots.js'
|
|
8
|
-
import User from './user.js'
|
|
9
|
-
import Comment from './comment.js'
|
|
10
|
-
|
|
11
|
-
export default {
|
|
12
|
-
// Scalars
|
|
13
|
-
Date: GraphQLDate,
|
|
14
|
-
Time: GraphQLTime,
|
|
15
|
-
DateTime: GraphQLDateTime,
|
|
16
|
-
BigInt: GraphQLBigInt,
|
|
17
|
-
// Complex types
|
|
18
|
-
Query,
|
|
19
|
-
Mutation,
|
|
20
|
-
User,
|
|
21
|
-
Dataset,
|
|
22
|
-
Draft,
|
|
23
|
-
Snapshot,
|
|
24
|
-
Comment,
|
|
25
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import config from '../../config'
|
|
2
|
-
import request from 'superagent'
|
|
3
|
-
import { updatePublic } from '../../datalad/dataset.js'
|
|
4
|
-
import { checkDatasetWrite } from '../permissions.js'
|
|
5
|
-
import { generateDataladCookie } from '../../libs/authentication/jwt'
|
|
6
|
-
import { getDatasetWorker } from '../../libs/datalad-service'
|
|
7
|
-
|
|
8
|
-
export const publishDataset = (obj, { datasetId }, { user, userInfo }) => {
|
|
9
|
-
return checkDatasetWrite(datasetId, user, userInfo).then(async () => {
|
|
10
|
-
await updatePublic(datasetId, true)
|
|
11
|
-
const uri = `${getDatasetWorker(datasetId)}/datasets/${datasetId}/publish`
|
|
12
|
-
return await request
|
|
13
|
-
.post(uri)
|
|
14
|
-
.set('Cookie', generateDataladCookie(config)(userInfo))
|
|
15
|
-
.then(() => true)
|
|
16
|
-
})
|
|
17
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Top level query
|
|
3
|
-
*/
|
|
4
|
-
import { dataset, datasets } from './dataset.js'
|
|
5
|
-
import { snapshot, participantCount } from './snapshots.js'
|
|
6
|
-
import { user, users } from './user.js'
|
|
7
|
-
import { flaggedFiles } from './flaggedFiles'
|
|
8
|
-
import { publicMetadata } from './metadata'
|
|
9
|
-
|
|
10
|
-
const Query = {
|
|
11
|
-
dataset,
|
|
12
|
-
datasets,
|
|
13
|
-
user,
|
|
14
|
-
users,
|
|
15
|
-
snapshot,
|
|
16
|
-
participantCount,
|
|
17
|
-
flaggedFiles,
|
|
18
|
-
publicMetadata,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default Query
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import pubsub from '../pubsub.js'
|
|
2
|
-
|
|
3
|
-
import { withFilter } from 'graphql-subscriptions'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Filter subscription to a specific dataset
|
|
7
|
-
* @param {object} payload
|
|
8
|
-
* @param {object} variables
|
|
9
|
-
* @returns {boolean}
|
|
10
|
-
*/
|
|
11
|
-
const filterDatasetId = (payload, variables) => {
|
|
12
|
-
const { datasetId, datasetIds } = variables
|
|
13
|
-
if (datasetId) return datasetId === payload.datasetId
|
|
14
|
-
if (datasetIds) return datasetIds.includes(payload.datasetId)
|
|
15
|
-
return false
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const datasetDeleted = () => ({
|
|
19
|
-
type: 'ID!',
|
|
20
|
-
subscribe: withFilter(
|
|
21
|
-
() => pubsub.asyncIterator('datasetDeleted'),
|
|
22
|
-
filterDatasetId,
|
|
23
|
-
),
|
|
24
|
-
args: {
|
|
25
|
-
datasetIds: '[ID!]',
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
export const snapshotsUpdated = {
|
|
30
|
-
type: 'Dataset',
|
|
31
|
-
subscribe: withFilter(
|
|
32
|
-
() => pubsub.asyncIterator('snapshotsUpdated'),
|
|
33
|
-
filterDatasetId,
|
|
34
|
-
),
|
|
35
|
-
args: {
|
|
36
|
-
datasetId: 'ID!',
|
|
37
|
-
},
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const draftUpdated = {
|
|
41
|
-
type: 'Dataset',
|
|
42
|
-
subscribe: withFilter(
|
|
43
|
-
() => pubsub.asyncIterator('draftUpdated'),
|
|
44
|
-
filterDatasetId,
|
|
45
|
-
),
|
|
46
|
-
args: {
|
|
47
|
-
datasetId: 'ID!',
|
|
48
|
-
},
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export const permissionsUpdated = {
|
|
52
|
-
type: 'Dataset',
|
|
53
|
-
subscribe: withFilter(
|
|
54
|
-
() => pubsub.asyncIterator('permissionsUpdated'),
|
|
55
|
-
filterDatasetId,
|
|
56
|
-
),
|
|
57
|
-
args: {
|
|
58
|
-
datasetIds: '[ID!]',
|
|
59
|
-
},
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export const filesUpdated = {
|
|
63
|
-
type: 'FilesUpdate',
|
|
64
|
-
subscribe: withFilter(
|
|
65
|
-
() => pubsub.asyncIterator('filesUpdated'),
|
|
66
|
-
filterDatasetId,
|
|
67
|
-
),
|
|
68
|
-
args: {
|
|
69
|
-
datasetId: 'ID!',
|
|
70
|
-
},
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const Subscription = {
|
|
74
|
-
datasetDeleted,
|
|
75
|
-
snapshotsUpdated,
|
|
76
|
-
permissionsUpdated,
|
|
77
|
-
draftUpdated,
|
|
78
|
-
filesUpdated,
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export default Subscription
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import pubsub from '../pubsub'
|
|
2
|
-
|
|
3
|
-
export default (datasetId, revision) => {
|
|
4
|
-
pubsub.publish('draftUpdated', {
|
|
5
|
-
datasetId: datasetId,
|
|
6
|
-
draftUpdated: {
|
|
7
|
-
__typename: 'Dataset',
|
|
8
|
-
id: datasetId,
|
|
9
|
-
head: revision,
|
|
10
|
-
modified: new Date(), // Set date to now
|
|
11
|
-
},
|
|
12
|
-
})
|
|
13
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import jwt from 'jsonwebtoken'
|
|
2
|
-
import { apiKeyFactory } from '../apikey.js'
|
|
3
|
-
import config from '../../config.js'
|
|
4
|
-
|
|
5
|
-
vi.mock('ioredis')
|
|
6
|
-
vi.mock('../../config.js')
|
|
7
|
-
|
|
8
|
-
const userMock = {
|
|
9
|
-
id: '1337',
|
|
10
|
-
name: 'Total Poser',
|
|
11
|
-
email: 'porkchopsandwich@gijoe.com',
|
|
12
|
-
admin: true,
|
|
13
|
-
provider: 'google',
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
describe('util/apikey.js', () => {
|
|
17
|
-
describe('apiKeyFactory', () => {
|
|
18
|
-
it('produces a valid JWT', () => {
|
|
19
|
-
const token = jwt.verify(apiKeyFactory(userMock), config.auth.jwt.secret)
|
|
20
|
-
expect(token.sub).toEqual(userMock.id)
|
|
21
|
-
expect(token.email).toEqual(userMock.email)
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
})
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { hashDatasetToRange } from '../datalad-service'
|
|
2
|
-
|
|
3
|
-
vi.mock('ioredis')
|
|
4
|
-
|
|
5
|
-
describe('datalad-service utils', () => {
|
|
6
|
-
describe('hashDatasetToRange()', () => {
|
|
7
|
-
it('is stable across a range of datasets', () => {
|
|
8
|
-
const range = 8
|
|
9
|
-
expect(hashDatasetToRange('ds000001', range)).toBe(4)
|
|
10
|
-
expect(hashDatasetToRange('ds000002', range)).toBe(5)
|
|
11
|
-
expect(hashDatasetToRange('ds000003', range)).toBe(4)
|
|
12
|
-
expect(hashDatasetToRange('ds000004', range)).toBe(6)
|
|
13
|
-
expect(hashDatasetToRange('ds001734', range)).toBe(1)
|
|
14
|
-
expect(hashDatasetToRange('ds001919', range)).toBe(6)
|
|
15
|
-
})
|
|
16
|
-
it('is comparable with a small range (4)', () => {
|
|
17
|
-
const range = 4
|
|
18
|
-
expect(hashDatasetToRange('ds000001', range)).toBe(0)
|
|
19
|
-
expect(hashDatasetToRange('ds000002', range)).toBe(1)
|
|
20
|
-
expect(hashDatasetToRange('ds000003', range)).toBe(0)
|
|
21
|
-
expect(hashDatasetToRange('ds000004', range)).toBe(2)
|
|
22
|
-
expect(hashDatasetToRange('ds001734', range)).toBe(1)
|
|
23
|
-
expect(hashDatasetToRange('ds001919', range)).toBe(2)
|
|
24
|
-
})
|
|
25
|
-
})
|
|
26
|
-
})
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import User from '../../../models/user'
|
|
2
|
-
import { addJWT } from '../jwt'
|
|
3
|
-
|
|
4
|
-
vi.mock('ioredis')
|
|
5
|
-
vi.mock('../../../config.js')
|
|
6
|
-
vi.unmock('mongoose')
|
|
7
|
-
|
|
8
|
-
describe('jwt auth', () => {
|
|
9
|
-
describe('addJWT()', () => {
|
|
10
|
-
it('Extends a User model with a valid token', () => {
|
|
11
|
-
const config = {
|
|
12
|
-
auth: {
|
|
13
|
-
jwt: {
|
|
14
|
-
secret: '1234',
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
}
|
|
18
|
-
const user = User({ email: 'test@example.com' })
|
|
19
|
-
const obj = addJWT(config)(user)
|
|
20
|
-
expect(obj).toHaveProperty('token')
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
})
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import passport from 'passport'
|
|
2
|
-
|
|
3
|
-
export const requestAuth = passport.authenticate('globus', {
|
|
4
|
-
scope: ['profile', 'email', 'openid'],
|
|
5
|
-
session: false,
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
export const authCallback = passport.authenticate('globus', {
|
|
9
|
-
failureRedirect: '/',
|
|
10
|
-
session: false,
|
|
11
|
-
})
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import passport from 'passport'
|
|
2
|
-
|
|
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
|
-
)
|
|
15
|
-
|
|
16
|
-
export const authCallback = passport.authenticate('google', {
|
|
17
|
-
failureRedirect: '/',
|
|
18
|
-
session: false,
|
|
19
|
-
})
|
package/src/libs/bidsId.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hex
|
|
3
|
-
*
|
|
4
|
-
* Utils for dealing with hex encoding
|
|
5
|
-
*/
|
|
6
|
-
export default {
|
|
7
|
-
hexToASCII(hexString) {
|
|
8
|
-
const hex = hexString.toString()
|
|
9
|
-
let str = ''
|
|
10
|
-
for (let n = 0; n < hex.length; n += 2) {
|
|
11
|
-
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16))
|
|
12
|
-
}
|
|
13
|
-
return str
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
hexFromASCII(string) {
|
|
17
|
-
return string
|
|
18
|
-
.split('')
|
|
19
|
-
.map(c => {
|
|
20
|
-
return ('0' + c.charCodeAt(0).toString(16)).slice(-2)
|
|
21
|
-
})
|
|
22
|
-
.join('')
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
encodeId(id) {
|
|
26
|
-
if (/ds\d{6}/.test(id)) {
|
|
27
|
-
return this.hexFromASCII(' ' + id)
|
|
28
|
-
} else if (/\d{6}-\d{5}/.test(id)) {
|
|
29
|
-
return this.hexFromASCII(id)
|
|
30
|
-
} else {
|
|
31
|
-
return id
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
decodeId(id) {
|
|
36
|
-
const decodedId = this.hexToASCII(id)
|
|
37
|
-
if (/\s{4}ds\d{6}/.test(decodedId)) {
|
|
38
|
-
return decodedId.slice(4)
|
|
39
|
-
} else if (/\d{6}-\d{5}/.test(decodedId)) {
|
|
40
|
-
return decodedId.slice(7)
|
|
41
|
-
}
|
|
42
|
-
return id
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
decode(id) {
|
|
46
|
-
const decodedId = this.hexToASCII(id)
|
|
47
|
-
let datasetId = null
|
|
48
|
-
let tag = null
|
|
49
|
-
// decodes the two different formats of storing dataset + snapshot tag
|
|
50
|
-
if (/\s{4}ds\d{6}/.test(decodedId)) {
|
|
51
|
-
datasetId = decodedId.slice(4)
|
|
52
|
-
} else if (/\d{6}-\d{5}/.test(decodedId)) {
|
|
53
|
-
tag = decodedId.slice(7)
|
|
54
|
-
datasetId = 'ds' + decodedId.slice(0, 6)
|
|
55
|
-
} else {
|
|
56
|
-
// handles all these old dataset ids that start with 57 or 58
|
|
57
|
-
if (id.startsWith('57') || id.startsWith('58')) {
|
|
58
|
-
datasetId = id
|
|
59
|
-
} else {
|
|
60
|
-
// if the id is of the proper length but has no ds, add ds.
|
|
61
|
-
// otherwise, add it is short and needs a 0 as well
|
|
62
|
-
const beginning = id.length == 6 ? 'ds' : 'ds0'
|
|
63
|
-
datasetId = beginning + id
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return { datasetId, tag }
|
|
67
|
-
},
|
|
68
|
-
}
|
package/src/libs/dataset.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { template, formatBasicAuth } from '../index.js'
|
|
2
|
-
|
|
3
|
-
vi.mock('ioredis')
|
|
4
|
-
|
|
5
|
-
describe('DOI minting utils', () => {
|
|
6
|
-
describe('auth()', () => {
|
|
7
|
-
it('returns a base64 basic auth string', () => {
|
|
8
|
-
const doiConfig = { username: 'test', password: '12345' }
|
|
9
|
-
expect(formatBasicAuth(doiConfig)).toBe('Basic dGVzdDoxMjM0NQ==')
|
|
10
|
-
})
|
|
11
|
-
})
|
|
12
|
-
describe('template()', () => {
|
|
13
|
-
it('accepts expected arguments', () => {
|
|
14
|
-
const context = {
|
|
15
|
-
doi: '12345',
|
|
16
|
-
creators: ['A. User', 'B. User'],
|
|
17
|
-
title: 'Test Dataset',
|
|
18
|
-
year: '1999',
|
|
19
|
-
resourceType: 'fMRI',
|
|
20
|
-
}
|
|
21
|
-
expect(template(context)).toMatchSnapshot()
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
})
|
package/src/libs/redis-pubsub.js
DELETED
package/src/libs/request.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import request from 'request'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Parse Options
|
|
5
|
-
*
|
|
6
|
-
* Normalizes request options.
|
|
7
|
-
*/
|
|
8
|
-
function parseOptions(req, options) {
|
|
9
|
-
if (options.query) {
|
|
10
|
-
req.qs = options.query
|
|
11
|
-
}
|
|
12
|
-
if (options.body) {
|
|
13
|
-
req.json = options.body
|
|
14
|
-
}
|
|
15
|
-
if (options.hasOwnProperty('encoding')) {
|
|
16
|
-
req.encoding = options.encoding
|
|
17
|
-
}
|
|
18
|
-
if (options.headers) {
|
|
19
|
-
for (const key in options.headers) {
|
|
20
|
-
req.headers[key] = options.headers[key]
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return req
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Handle Request
|
|
28
|
-
*
|
|
29
|
-
* Processes all requests before they fire.
|
|
30
|
-
*/
|
|
31
|
-
function handleRequest(url, options, callback) {
|
|
32
|
-
let req = {
|
|
33
|
-
url: url,
|
|
34
|
-
headers: {},
|
|
35
|
-
qs: {},
|
|
36
|
-
json: {},
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
req = parseOptions(req, options)
|
|
40
|
-
callback(req)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Handle Response
|
|
45
|
-
*
|
|
46
|
-
* Process all responses before they return
|
|
47
|
-
* to the callback.
|
|
48
|
-
*/
|
|
49
|
-
function handleResponse(err, res, callback) {
|
|
50
|
-
callback(err, res)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Request
|
|
55
|
-
*
|
|
56
|
-
* A wrapper of npm 'request' to allow for
|
|
57
|
-
* genericizing request and response manipulations.
|
|
58
|
-
*/
|
|
59
|
-
export default {
|
|
60
|
-
get(url, options, callback) {
|
|
61
|
-
handleRequest(url, options, req => {
|
|
62
|
-
request.get(req, (err, res) => {
|
|
63
|
-
handleResponse(err, res, callback)
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* GET CACHE
|
|
70
|
-
*
|
|
71
|
-
* Functions the same as request but takes a
|
|
72
|
-
* cache function, checks to see if the response is
|
|
73
|
-
* already cached. If so, responds with the cached data.
|
|
74
|
-
* If not, stores the response in the cache before responding.
|
|
75
|
-
*/
|
|
76
|
-
getCache(url, cache, options, callback) {
|
|
77
|
-
handleRequest(url, options, req => {
|
|
78
|
-
cache.get(req, (err, res1) => {
|
|
79
|
-
if (res1) {
|
|
80
|
-
handleResponse(err, res1, callback)
|
|
81
|
-
} else {
|
|
82
|
-
request.get(req, (err, res2) => {
|
|
83
|
-
if (err) {
|
|
84
|
-
handleResponse(err, res2, callback)
|
|
85
|
-
} else {
|
|
86
|
-
const data = res2.body
|
|
87
|
-
cache.store(data, () => {
|
|
88
|
-
handleResponse(err, res2, callback)
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
})
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
postCache(url, cache, options, callback) {
|
|
98
|
-
handleRequest(url, options, req => {
|
|
99
|
-
request.post(req, (err, res) => {
|
|
100
|
-
if (err) {
|
|
101
|
-
handleResponse(err, res, callback)
|
|
102
|
-
} else {
|
|
103
|
-
const data = req.json
|
|
104
|
-
cache.store(data, () => {
|
|
105
|
-
handleResponse(err, res, callback)
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* GET PROXY
|
|
114
|
-
*
|
|
115
|
-
* Functions the same as a get request but takes a
|
|
116
|
-
* response object instead of a callback and pipes
|
|
117
|
-
* the request response to the response object.
|
|
118
|
-
*/
|
|
119
|
-
getProxy(url, options, res) {
|
|
120
|
-
handleRequest(url, options, req => {
|
|
121
|
-
request
|
|
122
|
-
.get(req)
|
|
123
|
-
.on('data', resp => {
|
|
124
|
-
if (options.status) {
|
|
125
|
-
resp.statusCode = options.status
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
.pipe(res)
|
|
129
|
-
})
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
post(url, options, callback) {
|
|
133
|
-
handleRequest(url, options, req => {
|
|
134
|
-
request.post(req, (err, res) => {
|
|
135
|
-
handleResponse(err, res, callback)
|
|
136
|
-
})
|
|
137
|
-
})
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
put(url, options, callback) {
|
|
141
|
-
handleRequest(url, options, req => {
|
|
142
|
-
request.put(req, (err, res) => {
|
|
143
|
-
handleResponse(err, res, callback)
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
del(url, options, callback) {
|
|
149
|
-
handleRequest(url, options, req => {
|
|
150
|
-
request.del(req, (err, res) => {
|
|
151
|
-
handleResponse(err, res, callback)
|
|
152
|
-
})
|
|
153
|
-
})
|
|
154
|
-
},
|
|
155
|
-
}
|