@contember/engine-s3-plugin 2.1.0-alpha.9 → 2.1.0-beta.2
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/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js.map +1 -1
- package/dist/development/src/Config.cjs.map +1 -1
- package/dist/development/src/Config.js.map +1 -1
- package/dist/development/src/S3ConfigProcessor.cjs.map +1 -1
- package/dist/development/src/S3ConfigProcessor.js.map +1 -1
- package/dist/development/src/S3ObjectAuthorizator.cjs.map +1 -1
- package/dist/development/src/S3ObjectAuthorizator.js.map +1 -1
- package/dist/development/src/S3SchemaContributor.cjs +2 -4
- package/dist/development/src/S3SchemaContributor.cjs.map +1 -1
- package/dist/development/src/S3SchemaContributor.js +4 -6
- package/dist/development/src/S3SchemaContributor.js.map +1 -1
- package/dist/development/src/S3SchemaTypes.cjs.map +1 -1
- package/dist/development/src/S3SchemaTypes.js.map +1 -1
- package/dist/development/src/S3Service.cjs.map +1 -1
- package/dist/development/src/S3Service.js.map +1 -1
- package/dist/development/src/S3Signer.cjs +1 -1
- package/dist/development/src/S3Signer.cjs.map +1 -1
- package/dist/development/src/S3Signer.js +2 -2
- package/dist/development/src/S3Signer.js.map +1 -1
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.js.map +1 -1
- package/dist/production/src/Config.cjs.map +1 -1
- package/dist/production/src/Config.js.map +1 -1
- package/dist/production/src/S3ConfigProcessor.cjs.map +1 -1
- package/dist/production/src/S3ConfigProcessor.js.map +1 -1
- package/dist/production/src/S3ObjectAuthorizator.cjs.map +1 -1
- package/dist/production/src/S3ObjectAuthorizator.js.map +1 -1
- package/dist/production/src/S3SchemaContributor.cjs +2 -4
- package/dist/production/src/S3SchemaContributor.cjs.map +1 -1
- package/dist/production/src/S3SchemaContributor.js +4 -6
- package/dist/production/src/S3SchemaContributor.js.map +1 -1
- package/dist/production/src/S3SchemaTypes.cjs.map +1 -1
- package/dist/production/src/S3SchemaTypes.js.map +1 -1
- package/dist/production/src/S3Service.cjs.map +1 -1
- package/dist/production/src/S3Service.js.map +1 -1
- package/dist/production/src/S3Signer.cjs +1 -1
- package/dist/production/src/S3Signer.cjs.map +1 -1
- package/dist/production/src/S3Signer.js +2 -2
- package/dist/production/src/S3Signer.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/Config.d.ts.map +1 -1
- package/dist/types/S3ConfigProcessor.d.ts.map +1 -1
- package/dist/types/S3ObjectAuthorizator.d.ts.map +1 -1
- package/dist/types/S3SchemaContributor.d.ts.map +1 -1
- package/dist/types/S3SchemaTypes.d.ts.map +1 -1
- package/dist/types/S3Service.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -14
- package/src/Config.ts +0 -1
- package/src/S3ConfigProcessor.ts +0 -1
- package/src/S3ObjectAuthorizator.ts +0 -1
- package/src/S3SchemaContributor.ts +2 -7
- package/src/S3SchemaTypes.ts +3 -10
- package/src/S3Service.ts +1 -2
- package/src/S3Signer.ts +1 -1
- package/tests/cases/authorizator.test.ts +1 -2
- package/tests/cases/signRequest.test.ts +54 -26
- package/types/picomatch/index.d.ts +1 -1
- package/vitest.config.ts +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/engine-s3-plugin",
|
|
3
|
-
"version": "2.1.0-
|
|
3
|
+
"version": "2.1.0-beta.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/production/index.js",
|
|
6
6
|
"typings": "./dist/types/index.d.ts",
|
|
@@ -23,22 +23,27 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@contember/engine-plugins": "2.1.0-
|
|
27
|
-
"@contember/graphql-utils": "2.1.0-
|
|
28
|
-
"@contember/typesafe": "2.1.0-
|
|
29
|
-
"mime-types": "^
|
|
30
|
-
"picomatch": "^4.0.
|
|
31
|
-
"qs": "^6.
|
|
32
|
-
"uuid": "^
|
|
26
|
+
"@contember/engine-plugins": "2.1.0-beta.1",
|
|
27
|
+
"@contember/graphql-utils": "2.1.0-beta.1",
|
|
28
|
+
"@contember/typesafe": "2.1.0-beta.1",
|
|
29
|
+
"mime-types": "^3.0.2",
|
|
30
|
+
"picomatch": "^4.0.3",
|
|
31
|
+
"qs": "^6.15.0",
|
|
32
|
+
"uuid": "^13.0.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/mime-types": "^
|
|
36
|
-
"@types/qs": "^6.
|
|
37
|
-
"graphql": "^16.
|
|
35
|
+
"@types/mime-types": "^3.0.1",
|
|
36
|
+
"@types/qs": "^6.15.0",
|
|
37
|
+
"graphql": "^16.13.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"graphql": "
|
|
41
|
-
"pg": "^8.
|
|
40
|
+
"graphql": "^16.13.1",
|
|
41
|
+
"pg": "^8.20.0"
|
|
42
42
|
},
|
|
43
|
-
"type": "module"
|
|
43
|
+
"type": "module",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/contember/contember.git",
|
|
47
|
+
"directory": "packages/engine-s3-plugin"
|
|
48
|
+
}
|
|
44
49
|
}
|
package/src/Config.ts
CHANGED
package/src/S3ConfigProcessor.ts
CHANGED
|
@@ -33,7 +33,6 @@ export type S3SchemaAcl = Record<
|
|
|
33
33
|
}
|
|
34
34
|
>
|
|
35
35
|
|
|
36
|
-
|
|
37
36
|
export class S3SchemaContributor implements GraphQLSchemaContributor {
|
|
38
37
|
constructor(
|
|
39
38
|
private readonly s3Factory: S3ServiceFactory,
|
|
@@ -48,10 +47,7 @@ export class S3SchemaContributor implements GraphQLSchemaContributor {
|
|
|
48
47
|
if (!context.project.s3) {
|
|
49
48
|
return undefined
|
|
50
49
|
}
|
|
51
|
-
const rules = context.identity.projectRoles.flatMap(it =>
|
|
52
|
-
Object.entries((context.schema.acl.roles[it]?.s3 as S3SchemaAcl) || {}),
|
|
53
|
-
)
|
|
54
|
-
|
|
50
|
+
const rules = context.identity.projectRoles.flatMap(it => Object.entries((context.schema.acl.roles[it]?.s3 as S3SchemaAcl) || {}))
|
|
55
51
|
|
|
56
52
|
const uploadRules = rules.filter(([, it]) => it.upload).map(([it, val]) => ({
|
|
57
53
|
pattern: it,
|
|
@@ -61,7 +57,7 @@ export class S3SchemaContributor implements GraphQLSchemaContributor {
|
|
|
61
57
|
pattern: it,
|
|
62
58
|
}))
|
|
63
59
|
|
|
64
|
-
if (uploadRules.length === 0 && readRules.length
|
|
60
|
+
if (uploadRules.length === 0 && readRules.length === 0) {
|
|
65
61
|
return undefined
|
|
66
62
|
}
|
|
67
63
|
|
|
@@ -89,7 +85,6 @@ export class S3SchemaContributor implements GraphQLSchemaContributor {
|
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
private createReadMutation(authorizator: S3ObjectAuthorizator): GraphQLFieldConfig<any, { project: Project3Config }, any> {
|
|
92
|
-
|
|
93
88
|
return {
|
|
94
89
|
type: new GraphQLNonNull(S3SignedRead),
|
|
95
90
|
args: {
|
package/src/S3SchemaTypes.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
GraphQLEnumType,
|
|
3
|
-
GraphQLInputObjectType,
|
|
4
|
-
GraphQLInt,
|
|
5
|
-
GraphQLList,
|
|
6
|
-
GraphQLNonNull,
|
|
7
|
-
GraphQLObjectType,
|
|
8
|
-
GraphQLString,
|
|
9
|
-
} from 'graphql'
|
|
1
|
+
import { GraphQLEnumType, GraphQLInputObjectType, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLString } from 'graphql'
|
|
10
2
|
|
|
11
3
|
export const S3Header = new GraphQLObjectType({
|
|
12
4
|
name: 'S3Header',
|
|
@@ -17,7 +9,8 @@ export const S3Header = new GraphQLObjectType({
|
|
|
17
9
|
})
|
|
18
10
|
|
|
19
11
|
export const S3ContentDisposition = new GraphQLEnumType({
|
|
20
|
-
name: 'S33ContentDisposition',
|
|
12
|
+
name: 'S33ContentDisposition',
|
|
13
|
+
values: {
|
|
21
14
|
ATTACHMENT: {},
|
|
22
15
|
INLINE: {},
|
|
23
16
|
},
|
package/src/S3Service.ts
CHANGED
|
@@ -23,7 +23,6 @@ type SignedUploadUrl = {
|
|
|
23
23
|
method: string
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
export class S3Service {
|
|
28
27
|
private readonly publicBaseUrl: string
|
|
29
28
|
|
|
@@ -96,7 +95,7 @@ export class S3Service {
|
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
97
|
|
|
99
|
-
public getSignedReadUrl({ objectKey, expiration }: { objectKey: string; expiration: number | null}): SignedReadUrl {
|
|
98
|
+
public getSignedReadUrl({ objectKey, expiration }: { objectKey: string; expiration: number | null }): SignedReadUrl {
|
|
100
99
|
const bucket = this.config.bucket
|
|
101
100
|
|
|
102
101
|
const publicPrefix = this.formatPublicUrl('')
|
package/src/S3Signer.ts
CHANGED
|
@@ -32,7 +32,7 @@ export class S3Signer {
|
|
|
32
32
|
const nowFormatted = this.providers
|
|
33
33
|
.now()
|
|
34
34
|
.toISOString()
|
|
35
|
-
.replace(/[
|
|
35
|
+
.replace(/[:-]|\.\d{3}/g, '')
|
|
36
36
|
const queryString = this.getQueryParams(request, nowFormatted)
|
|
37
37
|
const path = uris.basePath + '/' + request.key
|
|
38
38
|
const lines = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { expect, test } from 'bun:test'
|
|
2
2
|
import { S3ObjectAuthorizator } from '../../src'
|
|
3
3
|
|
|
4
4
|
test('required read pattern', () => {
|
|
@@ -13,7 +13,6 @@ test('required upload pattern', () => {
|
|
|
13
13
|
expect(() => authorizator.verifyUploadAccess({ key: 'lorem.jpg', size: null })).toThrow('Upload access forbidden for object key lorem.jpg')
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
test('max upload size', () => {
|
|
18
17
|
const authorizator = new S3ObjectAuthorizator([{ pattern: '**', maxSize: 1024 }], [])
|
|
19
18
|
expect(() => authorizator.verifyUploadAccess({ key: 'lorem.jpg', size: 1000 })).not.toThrow()
|
|
@@ -1,54 +1,82 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { expect, test } from 'bun:test'
|
|
2
2
|
import { S3ObjectAuthorizator, S3Service } from '../../src'
|
|
3
3
|
|
|
4
4
|
const mocked = new Date('2021-07-02T17:22Z')
|
|
5
5
|
const constantUuid = '9fce3907-ff2b-45bb-b4ce-eff5527dd315'
|
|
6
|
-
const createS3Service = (bucket: string, prefix = '') =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
const createS3Service = (bucket: string, prefix = '') =>
|
|
7
|
+
new S3Service(
|
|
8
|
+
{
|
|
9
|
+
bucket,
|
|
10
|
+
region: 'eu-central-1',
|
|
11
|
+
credentials: {
|
|
12
|
+
key: 'test',
|
|
13
|
+
secret: 'abcd',
|
|
14
|
+
},
|
|
15
|
+
prefix,
|
|
13
16
|
},
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
new S3ObjectAuthorizator([{ pattern: '**' }], [{ pattern: '**' }]),
|
|
21
|
-
)
|
|
22
|
-
|
|
17
|
+
{
|
|
18
|
+
uuid: () => constantUuid,
|
|
19
|
+
now: () => mocked,
|
|
20
|
+
},
|
|
21
|
+
new S3ObjectAuthorizator([{ pattern: '**' }], [{ pattern: '**' }]),
|
|
22
|
+
)
|
|
23
23
|
|
|
24
24
|
test('sign s3 request', () => {
|
|
25
25
|
const service = createS3Service('test')
|
|
26
26
|
const signed = service.getSignedReadUrl({ objectKey: 'foo.jpg', expiration: null })
|
|
27
|
-
expect(signed.url).toEqual(
|
|
27
|
+
expect(signed.url).toEqual(
|
|
28
|
+
'https://test.s3.eu-central-1.amazonaws.com/foo.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=test%2F20210702%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20210702T172200Z&X-Amz-Expires=3600&X-Amz-Signature=00e912fe0383066802fc6c0f93ffb223320ca143992385fe69070bbb87c758dc&X-Amz-SignedHeaders=host',
|
|
29
|
+
)
|
|
28
30
|
})
|
|
29
31
|
|
|
30
32
|
test('sign s3 request - prefix', () => {
|
|
31
33
|
const service = createS3Service('test', 'lorem')
|
|
32
34
|
const signed = service.getSignedReadUrl({ objectKey: 'lorem/foo.jpg', expiration: null })
|
|
33
|
-
expect(signed.url).toEqual(
|
|
35
|
+
expect(signed.url).toEqual(
|
|
36
|
+
'https://test.s3.eu-central-1.amazonaws.com/lorem/foo.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=test%2F20210702%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20210702T172200Z&X-Amz-Expires=3600&X-Amz-Signature=f6c69dc306422c2b3242c9d9d42147336817720ffae249af8bd91cc7062e9f6d&X-Amz-SignedHeaders=host',
|
|
37
|
+
)
|
|
34
38
|
})
|
|
35
39
|
|
|
36
40
|
test('sign upload', () => {
|
|
37
41
|
const service = createS3Service('test')
|
|
38
|
-
const signed = service.getSignedUploadUrl({
|
|
39
|
-
|
|
42
|
+
const signed = service.getSignedUploadUrl({
|
|
43
|
+
contentType: 'image/jpeg',
|
|
44
|
+
acl: 'PUBLIC_READ',
|
|
45
|
+
expiration: 1800,
|
|
46
|
+
contentDisposition: null,
|
|
47
|
+
extension: null,
|
|
48
|
+
fileName: null,
|
|
49
|
+
prefix: null,
|
|
50
|
+
suffix: null,
|
|
51
|
+
size: null,
|
|
52
|
+
})
|
|
53
|
+
expect(signed.url).toEqual(
|
|
54
|
+
'https://test.s3.eu-central-1.amazonaws.com/9fce3907-ff2b-45bb-b4ce-eff5527dd315.jpg?Cache-Control=immutable&Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=test%2F20210702%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20210702T172200Z&X-Amz-Expires=1800&X-Amz-Signature=b4d5ce6a36e7684f1367addb3259e8361a0ef1972986c05ce01536f2fd955a32&X-Amz-SignedHeaders=cache-control%3Bhost%3Bx-amz-acl&x-amz-acl=public-read',
|
|
55
|
+
)
|
|
40
56
|
})
|
|
41
57
|
|
|
42
58
|
test('sign upload #2', () => {
|
|
43
59
|
const service = createS3Service('test')
|
|
44
|
-
const signed = service.getSignedUploadUrl({
|
|
45
|
-
|
|
60
|
+
const signed = service.getSignedUploadUrl({
|
|
61
|
+
contentType: 'image/jpeg',
|
|
62
|
+
acl: 'PUBLIC_READ',
|
|
63
|
+
expiration: 1800,
|
|
64
|
+
contentDisposition: 'INLINE',
|
|
65
|
+
extension: 'jpeg',
|
|
66
|
+
fileName: 'foo-bar.jpeg',
|
|
67
|
+
prefix: 'foo',
|
|
68
|
+
suffix: 'bar',
|
|
69
|
+
size: null,
|
|
70
|
+
})
|
|
71
|
+
expect(signed.url).toEqual(
|
|
72
|
+
'https://test.s3.eu-central-1.amazonaws.com/foo/9fce3907-ff2b-45bb-b4ce-eff5527dd315bar.jpeg?Cache-Control=immutable&Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=test%2F20210702%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20210702T172200Z&X-Amz-Expires=1800&X-Amz-Signature=979a93bca65a98ce6b2bf97d2bf2afe7d5f2fa805f7d596187675416c86a3bd5&X-Amz-SignedHeaders=cache-control%3Bcontent-disposition%3Bhost%3Bx-amz-acl&x-amz-acl=public-read',
|
|
73
|
+
)
|
|
46
74
|
})
|
|
47
75
|
|
|
48
|
-
|
|
49
76
|
test('bucket with dot', () => {
|
|
50
77
|
const service = createS3Service('test.foo')
|
|
51
78
|
const signed = service.getSignedReadUrl({ objectKey: 'foo.jpg', expiration: null })
|
|
52
|
-
expect(signed.url).toEqual(
|
|
79
|
+
expect(signed.url).toEqual(
|
|
80
|
+
'https://s3.eu-central-1.amazonaws.com/test.foo/foo.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=test%2F20210702%2Feu-central-1%2Fs3%2Faws4_request&X-Amz-Date=20210702T172200Z&X-Amz-Expires=3600&X-Amz-Signature=811a809196e60413e0e54e51d3dd91ab73ad1482b61e5371864d25d43ba642ff&X-Amz-SignedHeaders=host',
|
|
81
|
+
)
|
|
53
82
|
})
|
|
54
|
-
|
package/vitest.config.ts
DELETED