diff options
46 files changed, 1752 insertions, 844 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 59840d076..65e1acec6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml | |||
@@ -46,6 +46,8 @@ jobs: | |||
46 | PGHOST: localhost | 46 | PGHOST: localhost |
47 | NODE_PENDING_JOB_WAIT: 250 | 47 | NODE_PENDING_JOB_WAIT: 250 |
48 | ENABLE_OBJECT_STORAGE_TESTS: true | 48 | ENABLE_OBJECT_STORAGE_TESTS: true |
49 | OBJECT_STORAGE_SCALEWAY_KEY_ID: ${{ secrets.OBJECT_STORAGE_SCALEWAY_KEY_ID }} | ||
50 | OBJECT_STORAGE_SCALEWAY_ACCESS_KEY: ${{ secrets.OBJECT_STORAGE_SCALEWAY_ACCESS_KEY }} | ||
49 | 51 | ||
50 | steps: | 52 | steps: |
51 | - uses: actions/checkout@v3 | 53 | - uses: actions/checkout@v3 |
diff --git a/config/default.yaml b/config/default.yaml index f94ec6209..7753821da 100644 --- a/config/default.yaml +++ b/config/default.yaml | |||
@@ -148,8 +148,11 @@ object_storage: | |||
148 | 148 | ||
149 | region: 'us-east-1' | 149 | region: 'us-east-1' |
150 | 150 | ||
151 | # Set this ACL on each uploaded object | 151 | upload_acl: |
152 | upload_acl: 'public-read' | 152 | # Set this ACL on each uploaded object of public/unlisted videos |
153 | public: 'public-read' | ||
154 | # Set this ACL on each uploaded object of private/internal videos | ||
155 | private: 'private' | ||
153 | 156 | ||
154 | credentials: | 157 | credentials: |
155 | # You can also use AWS_ACCESS_KEY_ID env variable | 158 | # You can also use AWS_ACCESS_KEY_ID env variable |
diff --git a/config/production.yaml.example b/config/production.yaml.example index 48613e1c3..167d23af8 100644 --- a/config/production.yaml.example +++ b/config/production.yaml.example | |||
@@ -146,8 +146,11 @@ object_storage: | |||
146 | 146 | ||
147 | region: 'us-east-1' | 147 | region: 'us-east-1' |
148 | 148 | ||
149 | # Set this ACL on each uploaded object | 149 | upload_acl: |
150 | upload_acl: 'public-read' | 150 | # Set this ACL on each uploaded object of public/unlisted videos |
151 | public: 'public-read' | ||
152 | # Set this ACL on each uploaded object of private/internal videos | ||
153 | private: 'private' | ||
151 | 154 | ||
152 | credentials: | 155 | credentials: |
153 | # You can also use AWS_ACCESS_KEY_ID env variable | 156 | # You can also use AWS_ACCESS_KEY_ID env variable |
diff --git a/package.json b/package.json index 23cd9e112..249455068 100644 --- a/package.json +++ b/package.json | |||
@@ -78,9 +78,9 @@ | |||
78 | "jpeg-js": "0.4.4" | 78 | "jpeg-js": "0.4.4" |
79 | }, | 79 | }, |
80 | "dependencies": { | 80 | "dependencies": { |
81 | "@aws-sdk/client-s3": "^3.23.0", | 81 | "@aws-sdk/client-s3": "^3.190.0", |
82 | "@aws-sdk/lib-storage": "^3.72.0", | 82 | "@aws-sdk/lib-storage": "^3.190.0", |
83 | "@aws-sdk/node-http-handler": "^3.82.0", | 83 | "@aws-sdk/node-http-handler": "^3.190.0", |
84 | "@babel/parser": "^7.17.8", | 84 | "@babel/parser": "^7.17.8", |
85 | "@node-oauth/oauth2-server": "^4.2.0", | 85 | "@node-oauth/oauth2-server": "^4.2.0", |
86 | "@opentelemetry/api": "^1.1.0", | 86 | "@opentelemetry/api": "^1.1.0", |
@@ -107,6 +107,7 @@ import { | |||
107 | wellKnownRouter, | 107 | wellKnownRouter, |
108 | lazyStaticRouter, | 108 | lazyStaticRouter, |
109 | servicesRouter, | 109 | servicesRouter, |
110 | objectStorageProxyRouter, | ||
110 | pluginsRouter, | 111 | pluginsRouter, |
111 | webfingerRouter, | 112 | webfingerRouter, |
112 | trackerRouter, | 113 | trackerRouter, |
@@ -240,6 +241,7 @@ app.use('/', wellKnownRouter) | |||
240 | app.use('/', miscRouter) | 241 | app.use('/', miscRouter) |
241 | app.use('/', downloadRouter) | 242 | app.use('/', downloadRouter) |
242 | app.use('/', lazyStaticRouter) | 243 | app.use('/', lazyStaticRouter) |
244 | app.use('/', objectStorageProxyRouter) | ||
243 | 245 | ||
244 | // Client files, last valid routes! | 246 | // Client files, last valid routes! |
245 | const cliOptions = cli.opts<{ client: boolean, plugins: boolean }>() | 247 | const cliOptions = cli.opts<{ client: boolean, plugins: boolean }>() |
diff --git a/server/controllers/download.ts b/server/controllers/download.ts index abd1df26f..d9f34109f 100644 --- a/server/controllers/download.ts +++ b/server/controllers/download.ts | |||
@@ -5,6 +5,7 @@ import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache | |||
5 | import { Hooks } from '@server/lib/plugins/hooks' | 5 | import { Hooks } from '@server/lib/plugins/hooks' |
6 | import { VideoPathManager } from '@server/lib/video-path-manager' | 6 | import { VideoPathManager } from '@server/lib/video-path-manager' |
7 | import { MStreamingPlaylist, MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' | 7 | import { MStreamingPlaylist, MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' |
8 | import { addQueryParams } from '@shared/core-utils' | ||
8 | import { HttpStatusCode, VideoStorage, VideoStreamingPlaylistType } from '@shared/models' | 9 | import { HttpStatusCode, VideoStorage, VideoStreamingPlaylistType } from '@shared/models' |
9 | import { STATIC_DOWNLOAD_PATHS } from '../initializers/constants' | 10 | import { STATIC_DOWNLOAD_PATHS } from '../initializers/constants' |
10 | import { asyncMiddleware, optionalAuthenticate, videosDownloadValidator } from '../middlewares' | 11 | import { asyncMiddleware, optionalAuthenticate, videosDownloadValidator } from '../middlewares' |
@@ -84,7 +85,7 @@ async function downloadVideoFile (req: express.Request, res: express.Response) { | |||
84 | if (!checkAllowResult(res, allowParameters, allowedResult)) return | 85 | if (!checkAllowResult(res, allowParameters, allowedResult)) return |
85 | 86 | ||
86 | if (videoFile.storage === VideoStorage.OBJECT_STORAGE) { | 87 | if (videoFile.storage === VideoStorage.OBJECT_STORAGE) { |
87 | return res.redirect(videoFile.getObjectStorageUrl()) | 88 | return redirectToObjectStorage({ req, res, video, file: videoFile }) |
88 | } | 89 | } |
89 | 90 | ||
90 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), path => { | 91 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), path => { |
@@ -120,7 +121,7 @@ async function downloadHLSVideoFile (req: express.Request, res: express.Response | |||
120 | if (!checkAllowResult(res, allowParameters, allowedResult)) return | 121 | if (!checkAllowResult(res, allowParameters, allowedResult)) return |
121 | 122 | ||
122 | if (videoFile.storage === VideoStorage.OBJECT_STORAGE) { | 123 | if (videoFile.storage === VideoStorage.OBJECT_STORAGE) { |
123 | return res.redirect(videoFile.getObjectStorageUrl()) | 124 | return redirectToObjectStorage({ req, res, video, file: videoFile }) |
124 | } | 125 | } |
125 | 126 | ||
126 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(streamingPlaylist), path => { | 127 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(streamingPlaylist), path => { |
@@ -174,3 +175,20 @@ function checkAllowResult (res: express.Response, allowParameters: any, result?: | |||
174 | 175 | ||
175 | return true | 176 | return true |
176 | } | 177 | } |
178 | |||
179 | function redirectToObjectStorage (options: { | ||
180 | req: express.Request | ||
181 | res: express.Response | ||
182 | video: MVideo | ||
183 | file: MVideoFile | ||
184 | }) { | ||
185 | const { req, res, video, file } = options | ||
186 | |||
187 | const baseUrl = file.getObjectStorageUrl(video) | ||
188 | |||
189 | const url = video.hasPrivateStaticPath() && req.query.videoFileToken | ||
190 | ? addQueryParams(baseUrl, { videoFileToken: req.query.videoFileToken }) | ||
191 | : baseUrl | ||
192 | |||
193 | return res.redirect(url) | ||
194 | } | ||
diff --git a/server/controllers/index.ts b/server/controllers/index.ts index 8574a9e7b..eaa2dd7c8 100644 --- a/server/controllers/index.ts +++ b/server/controllers/index.ts | |||
@@ -1,14 +1,15 @@ | |||
1 | export * from './activitypub' | 1 | export * from './activitypub' |
2 | export * from './api' | 2 | export * from './api' |
3 | export * from './bots' | ||
3 | export * from './client' | 4 | export * from './client' |
4 | export * from './download' | 5 | export * from './download' |
5 | export * from './feeds' | 6 | export * from './feeds' |
6 | export * from './services' | ||
7 | export * from './static' | ||
8 | export * from './lazy-static' | 7 | export * from './lazy-static' |
9 | export * from './misc' | 8 | export * from './misc' |
10 | export * from './webfinger' | 9 | export * from './object-storage-proxy' |
11 | export * from './tracker' | ||
12 | export * from './bots' | ||
13 | export * from './plugins' | 10 | export * from './plugins' |
11 | export * from './services' | ||
12 | export * from './static' | ||
13 | export * from './tracker' | ||
14 | export * from './webfinger' | ||
14 | export * from './well-known' | 15 | export * from './well-known' |
diff --git a/server/controllers/object-storage-proxy.ts b/server/controllers/object-storage-proxy.ts new file mode 100644 index 000000000..6fedcfd8f --- /dev/null +++ b/server/controllers/object-storage-proxy.ts | |||
@@ -0,0 +1,78 @@ | |||
1 | import cors from 'cors' | ||
2 | import express from 'express' | ||
3 | import { OBJECT_STORAGE_PROXY_PATHS } from '@server/initializers/constants' | ||
4 | import { getHLSFileReadStream, getWebTorrentFileReadStream } from '@server/lib/object-storage' | ||
5 | import { | ||
6 | asyncMiddleware, | ||
7 | ensureCanAccessPrivateVideoHLSFiles, | ||
8 | ensureCanAccessVideoPrivateWebTorrentFiles, | ||
9 | optionalAuthenticate | ||
10 | } from '@server/middlewares' | ||
11 | import { HttpStatusCode } from '@shared/models' | ||
12 | |||
13 | const objectStorageProxyRouter = express.Router() | ||
14 | |||
15 | objectStorageProxyRouter.use(cors()) | ||
16 | |||
17 | objectStorageProxyRouter.get(OBJECT_STORAGE_PROXY_PATHS.PRIVATE_WEBSEED + ':filename', | ||
18 | optionalAuthenticate, | ||
19 | asyncMiddleware(ensureCanAccessVideoPrivateWebTorrentFiles), | ||
20 | asyncMiddleware(proxifyWebTorrent) | ||
21 | ) | ||
22 | |||
23 | objectStorageProxyRouter.get(OBJECT_STORAGE_PROXY_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS + ':videoUUID/:filename', | ||
24 | optionalAuthenticate, | ||
25 | asyncMiddleware(ensureCanAccessPrivateVideoHLSFiles), | ||
26 | asyncMiddleware(proxifyHLS) | ||
27 | ) | ||
28 | |||
29 | // --------------------------------------------------------------------------- | ||
30 | |||
31 | export { | ||
32 | objectStorageProxyRouter | ||
33 | } | ||
34 | |||
35 | async function proxifyWebTorrent (req: express.Request, res: express.Response) { | ||
36 | const filename = req.params.filename | ||
37 | |||
38 | try { | ||
39 | const stream = await getWebTorrentFileReadStream({ | ||
40 | filename, | ||
41 | rangeHeader: req.header('range') | ||
42 | }) | ||
43 | |||
44 | return stream.pipe(res) | ||
45 | } catch (err) { | ||
46 | return handleObjectStorageFailure(res, err) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | async function proxifyHLS (req: express.Request, res: express.Response) { | ||
51 | const playlist = res.locals.videoStreamingPlaylist | ||
52 | const video = res.locals.onlyVideo | ||
53 | const filename = req.params.filename | ||
54 | |||
55 | try { | ||
56 | const stream = await getHLSFileReadStream({ | ||
57 | playlist: playlist.withVideo(video), | ||
58 | filename, | ||
59 | rangeHeader: req.header('range') | ||
60 | }) | ||
61 | |||
62 | return stream.pipe(res) | ||
63 | } catch (err) { | ||
64 | return handleObjectStorageFailure(res, err) | ||
65 | } | ||
66 | } | ||
67 | |||
68 | function handleObjectStorageFailure (res: express.Response, err: Error) { | ||
69 | if (err.name === 'NoSuchKey') { | ||
70 | return res.sendStatus(HttpStatusCode.NOT_FOUND_404) | ||
71 | } | ||
72 | |||
73 | return res.fail({ | ||
74 | status: HttpStatusCode.INTERNAL_SERVER_ERROR_500, | ||
75 | message: err.message, | ||
76 | type: err.name | ||
77 | }) | ||
78 | } | ||
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts index 6d87c74f7..b458e86d2 100644 --- a/server/helpers/webtorrent.ts +++ b/server/helpers/webtorrent.ts | |||
@@ -165,7 +165,7 @@ function generateMagnetUri ( | |||
165 | const xs = videoFile.getTorrentUrl() | 165 | const xs = videoFile.getTorrentUrl() |
166 | const announce = trackerUrls | 166 | const announce = trackerUrls |
167 | 167 | ||
168 | let urlList = video.requiresAuth(video.uuid) | 168 | let urlList = video.hasPrivateStaticPath() |
169 | ? [] | 169 | ? [] |
170 | : [ videoFile.getFileUrl(video) ] | 170 | : [ videoFile.getFileUrl(video) ] |
171 | 171 | ||
@@ -243,7 +243,7 @@ function buildAnnounceList () { | |||
243 | } | 243 | } |
244 | 244 | ||
245 | function buildUrlList (video: MVideo, videoFile: MVideoFile) { | 245 | function buildUrlList (video: MVideo, videoFile: MVideoFile) { |
246 | if (video.requiresAuth(video.uuid)) return [] | 246 | if (video.hasPrivateStaticPath()) return [] |
247 | 247 | ||
248 | return [ videoFile.getFileUrl(video) ] | 248 | return [ videoFile.getFileUrl(video) ] |
249 | } | 249 | } |
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts index c83fef425..09e878eee 100644 --- a/server/initializers/checker-after-init.ts +++ b/server/initializers/checker-after-init.ts | |||
@@ -278,6 +278,14 @@ function checkObjectStorageConfig () { | |||
278 | 'Object storage bucket prefixes should be set to different values when the same bucket is used for both types of video.' | 278 | 'Object storage bucket prefixes should be set to different values when the same bucket is used for both types of video.' |
279 | ) | 279 | ) |
280 | } | 280 | } |
281 | |||
282 | if (!CONFIG.OBJECT_STORAGE.UPLOAD_ACL.PUBLIC) { | ||
283 | throw new Error('object_storage.upload_acl.public must be set') | ||
284 | } | ||
285 | |||
286 | if (!CONFIG.OBJECT_STORAGE.UPLOAD_ACL.PRIVATE) { | ||
287 | throw new Error('object_storage.upload_acl.private must be set') | ||
288 | } | ||
281 | } | 289 | } |
282 | } | 290 | } |
283 | 291 | ||
diff --git a/server/initializers/config.ts b/server/initializers/config.ts index a5a0d4e46..ab5e645ad 100644 --- a/server/initializers/config.ts +++ b/server/initializers/config.ts | |||
@@ -118,7 +118,10 @@ const CONFIG = { | |||
118 | MAX_UPLOAD_PART: bytes.parse(config.get<string>('object_storage.max_upload_part')), | 118 | MAX_UPLOAD_PART: bytes.parse(config.get<string>('object_storage.max_upload_part')), |
119 | ENDPOINT: config.get<string>('object_storage.endpoint'), | 119 | ENDPOINT: config.get<string>('object_storage.endpoint'), |
120 | REGION: config.get<string>('object_storage.region'), | 120 | REGION: config.get<string>('object_storage.region'), |
121 | UPLOAD_ACL: config.get<string>('object_storage.upload_acl'), | 121 | UPLOAD_ACL: { |
122 | PUBLIC: config.get<string>('object_storage.upload_acl.public'), | ||
123 | PRIVATE: config.get<string>('object_storage.upload_acl.private') | ||
124 | }, | ||
122 | CREDENTIALS: { | 125 | CREDENTIALS: { |
123 | ACCESS_KEY_ID: config.get<string>('object_storage.credentials.access_key_id'), | 126 | ACCESS_KEY_ID: config.get<string>('object_storage.credentials.access_key_id'), |
124 | SECRET_ACCESS_KEY: config.get<string>('object_storage.credentials.secret_access_key') | 127 | SECRET_ACCESS_KEY: config.get<string>('object_storage.credentials.secret_access_key') |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 88bdd07fe..66eb31230 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -685,6 +685,13 @@ const LAZY_STATIC_PATHS = { | |||
685 | VIDEO_CAPTIONS: '/lazy-static/video-captions/', | 685 | VIDEO_CAPTIONS: '/lazy-static/video-captions/', |
686 | TORRENTS: '/lazy-static/torrents/' | 686 | TORRENTS: '/lazy-static/torrents/' |
687 | } | 687 | } |
688 | const OBJECT_STORAGE_PROXY_PATHS = { | ||
689 | PRIVATE_WEBSEED: '/object-storage-proxy/webseed/private/', | ||
690 | |||
691 | STREAMING_PLAYLISTS: { | ||
692 | PRIVATE_HLS: '/object-storage-proxy/streaming-playlists/hls/private/' | ||
693 | } | ||
694 | } | ||
688 | 695 | ||
689 | // Cache control | 696 | // Cache control |
690 | const STATIC_MAX_AGE = { | 697 | const STATIC_MAX_AGE = { |
@@ -995,6 +1002,7 @@ export { | |||
995 | VIDEO_LIVE, | 1002 | VIDEO_LIVE, |
996 | PEERTUBE_VERSION, | 1003 | PEERTUBE_VERSION, |
997 | LAZY_STATIC_PATHS, | 1004 | LAZY_STATIC_PATHS, |
1005 | OBJECT_STORAGE_PROXY_PATHS, | ||
998 | SEARCH_INDEX, | 1006 | SEARCH_INDEX, |
999 | DIRECTORIES, | 1007 | DIRECTORIES, |
1000 | RESUMABLE_UPLOAD_SESSION_LIFETIME, | 1008 | RESUMABLE_UPLOAD_SESSION_LIFETIME, |
diff --git a/server/lib/live/live-segment-sha-store.ts b/server/lib/live/live-segment-sha-store.ts index faf03dccf..4d03754a9 100644 --- a/server/lib/live/live-segment-sha-store.ts +++ b/server/lib/live/live-segment-sha-store.ts | |||
@@ -5,6 +5,7 @@ import { logger, loggerTagsFactory } from '@server/helpers/logger' | |||
5 | import { MStreamingPlaylistVideo } from '@server/types/models' | 5 | import { MStreamingPlaylistVideo } from '@server/types/models' |
6 | import { buildSha256Segment } from '../hls' | 6 | import { buildSha256Segment } from '../hls' |
7 | import { storeHLSFileFromPath } from '../object-storage' | 7 | import { storeHLSFileFromPath } from '../object-storage' |
8 | import PQueue from 'p-queue' | ||
8 | 9 | ||
9 | const lTags = loggerTagsFactory('live') | 10 | const lTags = loggerTagsFactory('live') |
10 | 11 | ||
@@ -16,6 +17,7 @@ class LiveSegmentShaStore { | |||
16 | private readonly sha256Path: string | 17 | private readonly sha256Path: string |
17 | private readonly streamingPlaylist: MStreamingPlaylistVideo | 18 | private readonly streamingPlaylist: MStreamingPlaylistVideo |
18 | private readonly sendToObjectStorage: boolean | 19 | private readonly sendToObjectStorage: boolean |
20 | private readonly writeQueue = new PQueue({ concurrency: 1 }) | ||
19 | 21 | ||
20 | constructor (options: { | 22 | constructor (options: { |
21 | videoUUID: string | 23 | videoUUID: string |
@@ -37,7 +39,11 @@ class LiveSegmentShaStore { | |||
37 | const segmentName = basename(segmentPath) | 39 | const segmentName = basename(segmentPath) |
38 | this.segmentsSha256.set(segmentName, shaResult) | 40 | this.segmentsSha256.set(segmentName, shaResult) |
39 | 41 | ||
40 | await this.writeToDisk() | 42 | try { |
43 | await this.writeToDisk() | ||
44 | } catch (err) { | ||
45 | logger.error('Cannot write sha segments to disk.', { err }) | ||
46 | } | ||
41 | } | 47 | } |
42 | 48 | ||
43 | async removeSegmentSha (segmentPath: string) { | 49 | async removeSegmentSha (segmentPath: string) { |
@@ -55,19 +61,20 @@ class LiveSegmentShaStore { | |||
55 | await this.writeToDisk() | 61 | await this.writeToDisk() |
56 | } | 62 | } |
57 | 63 | ||
58 | private async writeToDisk () { | 64 | private writeToDisk () { |
59 | await writeJson(this.sha256Path, mapToJSON(this.segmentsSha256)) | 65 | return this.writeQueue.add(async () => { |
66 | await writeJson(this.sha256Path, mapToJSON(this.segmentsSha256)) | ||
60 | 67 | ||
61 | if (this.sendToObjectStorage) { | 68 | if (this.sendToObjectStorage) { |
62 | const url = await storeHLSFileFromPath(this.streamingPlaylist, this.sha256Path) | 69 | const url = await storeHLSFileFromPath(this.streamingPlaylist, this.sha256Path) |
63 | 70 | ||
64 | if (this.streamingPlaylist.segmentsSha256Url !== url) { | 71 | if (this.streamingPlaylist.segmentsSha256Url !== url) { |
65 | this.streamingPlaylist.segmentsSha256Url = url | 72 | this.streamingPlaylist.segmentsSha256Url = url |
66 | await this.streamingPlaylist.save() | 73 | await this.streamingPlaylist.save() |
74 | } | ||
67 | } | 75 | } |
68 | } | 76 | }) |
69 | } | 77 | } |
70 | |||
71 | } | 78 | } |
72 | 79 | ||
73 | export { | 80 | export { |
diff --git a/server/lib/object-storage/shared/object-storage-helpers.ts b/server/lib/object-storage/shared/object-storage-helpers.ts index c131977e8..05b52f412 100644 --- a/server/lib/object-storage/shared/object-storage-helpers.ts +++ b/server/lib/object-storage/shared/object-storage-helpers.ts | |||
@@ -2,18 +2,21 @@ import { createReadStream, createWriteStream, ensureDir, ReadStream } from 'fs-e | |||
2 | import { dirname } from 'path' | 2 | import { dirname } from 'path' |
3 | import { Readable } from 'stream' | 3 | import { Readable } from 'stream' |
4 | import { | 4 | import { |
5 | _Object, | ||
5 | CompleteMultipartUploadCommandOutput, | 6 | CompleteMultipartUploadCommandOutput, |
6 | DeleteObjectCommand, | 7 | DeleteObjectCommand, |
7 | GetObjectCommand, | 8 | GetObjectCommand, |
8 | ListObjectsV2Command, | 9 | ListObjectsV2Command, |
9 | PutObjectCommandInput | 10 | PutObjectAclCommand, |
11 | PutObjectCommandInput, | ||
12 | S3Client | ||
10 | } from '@aws-sdk/client-s3' | 13 | } from '@aws-sdk/client-s3' |
11 | import { Upload } from '@aws-sdk/lib-storage' | 14 | import { Upload } from '@aws-sdk/lib-storage' |
12 | import { pipelinePromise } from '@server/helpers/core-utils' | 15 | import { pipelinePromise } from '@server/helpers/core-utils' |
13 | import { isArray } from '@server/helpers/custom-validators/misc' | 16 | import { isArray } from '@server/helpers/custom-validators/misc' |
14 | import { logger } from '@server/helpers/logger' | 17 | import { logger } from '@server/helpers/logger' |
15 | import { CONFIG } from '@server/initializers/config' | 18 | import { CONFIG } from '@server/initializers/config' |
16 | import { getPrivateUrl } from '../urls' | 19 | import { getInternalUrl } from '../urls' |
17 | import { getClient } from './client' | 20 | import { getClient } from './client' |
18 | import { lTags } from './logger' | 21 | import { lTags } from './logger' |
19 | 22 | ||
@@ -44,69 +47,91 @@ async function storeObject (options: { | |||
44 | inputPath: string | 47 | inputPath: string |
45 | objectStorageKey: string | 48 | objectStorageKey: string |
46 | bucketInfo: BucketInfo | 49 | bucketInfo: BucketInfo |
50 | isPrivate: boolean | ||
47 | }): Promise<string> { | 51 | }): Promise<string> { |
48 | const { inputPath, objectStorageKey, bucketInfo } = options | 52 | const { inputPath, objectStorageKey, bucketInfo, isPrivate } = options |
49 | 53 | ||
50 | logger.debug('Uploading file %s to %s%s in bucket %s', inputPath, bucketInfo.PREFIX, objectStorageKey, bucketInfo.BUCKET_NAME, lTags()) | 54 | logger.debug('Uploading file %s to %s%s in bucket %s', inputPath, bucketInfo.PREFIX, objectStorageKey, bucketInfo.BUCKET_NAME, lTags()) |
51 | 55 | ||
52 | const fileStream = createReadStream(inputPath) | 56 | const fileStream = createReadStream(inputPath) |
53 | 57 | ||
54 | return uploadToStorage({ objectStorageKey, content: fileStream, bucketInfo }) | 58 | return uploadToStorage({ objectStorageKey, content: fileStream, bucketInfo, isPrivate }) |
55 | } | 59 | } |
56 | 60 | ||
57 | // --------------------------------------------------------------------------- | 61 | // --------------------------------------------------------------------------- |
58 | 62 | ||
59 | async function removeObject (filename: string, bucketInfo: BucketInfo) { | 63 | function updateObjectACL (options: { |
60 | const command = new DeleteObjectCommand({ | 64 | objectStorageKey: string |
65 | bucketInfo: BucketInfo | ||
66 | isPrivate: boolean | ||
67 | }) { | ||
68 | const { objectStorageKey, bucketInfo, isPrivate } = options | ||
69 | |||
70 | const key = buildKey(objectStorageKey, bucketInfo) | ||
71 | |||
72 | logger.debug('Updating ACL file %s in bucket %s', key, bucketInfo.BUCKET_NAME, lTags()) | ||
73 | |||
74 | const command = new PutObjectAclCommand({ | ||
61 | Bucket: bucketInfo.BUCKET_NAME, | 75 | Bucket: bucketInfo.BUCKET_NAME, |
62 | Key: buildKey(filename, bucketInfo) | 76 | Key: key, |
77 | ACL: getACL(isPrivate) | ||
63 | }) | 78 | }) |
64 | 79 | ||
65 | return getClient().send(command) | 80 | return getClient().send(command) |
66 | } | 81 | } |
67 | 82 | ||
68 | async function removePrefix (prefix: string, bucketInfo: BucketInfo) { | 83 | function updatePrefixACL (options: { |
69 | const s3Client = getClient() | 84 | prefix: string |
70 | 85 | bucketInfo: BucketInfo | |
71 | const commandPrefix = bucketInfo.PREFIX + prefix | 86 | isPrivate: boolean |
72 | const listCommand = new ListObjectsV2Command({ | 87 | }) { |
73 | Bucket: bucketInfo.BUCKET_NAME, | 88 | const { prefix, bucketInfo, isPrivate } = options |
74 | Prefix: commandPrefix | 89 | |
90 | logger.debug('Updating ACL of files in prefix %s in bucket %s', prefix, bucketInfo.BUCKET_NAME, lTags()) | ||
91 | |||
92 | return applyOnPrefix({ | ||
93 | prefix, | ||
94 | bucketInfo, | ||
95 | commandBuilder: obj => { | ||
96 | return new PutObjectAclCommand({ | ||
97 | Bucket: bucketInfo.BUCKET_NAME, | ||
98 | Key: obj.Key, | ||
99 | ACL: getACL(isPrivate) | ||
100 | }) | ||
101 | } | ||
75 | }) | 102 | }) |
103 | } | ||
76 | 104 | ||
77 | const listedObjects = await s3Client.send(listCommand) | 105 | // --------------------------------------------------------------------------- |
78 | 106 | ||
79 | // FIXME: use bulk delete when s3ninja will support this operation | 107 | function removeObject (objectStorageKey: string, bucketInfo: BucketInfo) { |
80 | // const deleteParams = { | 108 | const key = buildKey(objectStorageKey, bucketInfo) |
81 | // Bucket: bucketInfo.BUCKET_NAME, | ||
82 | // Delete: { Objects: [] } | ||
83 | // } | ||
84 | 109 | ||
85 | if (isArray(listedObjects.Contents) !== true) { | 110 | logger.debug('Removing file %s in bucket %s', key, bucketInfo.BUCKET_NAME, lTags()) |
86 | const message = `Cannot remove ${commandPrefix} prefix in bucket ${bucketInfo.BUCKET_NAME}: no files listed.` | ||
87 | 111 | ||
88 | logger.error(message, { response: listedObjects, ...lTags() }) | 112 | const command = new DeleteObjectCommand({ |
89 | throw new Error(message) | 113 | Bucket: bucketInfo.BUCKET_NAME, |
90 | } | 114 | Key: key |
91 | 115 | }) | |
92 | for (const object of listedObjects.Contents) { | ||
93 | const command = new DeleteObjectCommand({ | ||
94 | Bucket: bucketInfo.BUCKET_NAME, | ||
95 | Key: object.Key | ||
96 | }) | ||
97 | |||
98 | await s3Client.send(command) | ||
99 | 116 | ||
100 | // FIXME: use bulk delete when s3ninja will support this operation | 117 | return getClient().send(command) |
101 | // deleteParams.Delete.Objects.push({ Key: object.Key }) | 118 | } |
102 | } | ||
103 | 119 | ||
120 | function removePrefix (prefix: string, bucketInfo: BucketInfo) { | ||
104 | // FIXME: use bulk delete when s3ninja will support this operation | 121 | // FIXME: use bulk delete when s3ninja will support this operation |
105 | // const deleteCommand = new DeleteObjectsCommand(deleteParams) | ||
106 | // await s3Client.send(deleteCommand) | ||
107 | 122 | ||
108 | // Repeat if not all objects could be listed at once (limit of 1000?) | 123 | logger.debug('Removing prefix %s in bucket %s', prefix, bucketInfo.BUCKET_NAME, lTags()) |
109 | if (listedObjects.IsTruncated) await removePrefix(prefix, bucketInfo) | 124 | |
125 | return applyOnPrefix({ | ||
126 | prefix, | ||
127 | bucketInfo, | ||
128 | commandBuilder: obj => { | ||
129 | return new DeleteObjectCommand({ | ||
130 | Bucket: bucketInfo.BUCKET_NAME, | ||
131 | Key: obj.Key | ||
132 | }) | ||
133 | } | ||
134 | }) | ||
110 | } | 135 | } |
111 | 136 | ||
112 | // --------------------------------------------------------------------------- | 137 | // --------------------------------------------------------------------------- |
@@ -138,14 +163,42 @@ function buildKey (key: string, bucketInfo: BucketInfo) { | |||
138 | 163 | ||
139 | // --------------------------------------------------------------------------- | 164 | // --------------------------------------------------------------------------- |
140 | 165 | ||
166 | async function createObjectReadStream (options: { | ||
167 | key: string | ||
168 | bucketInfo: BucketInfo | ||
169 | rangeHeader: string | ||
170 | }) { | ||
171 | const { key, bucketInfo, rangeHeader } = options | ||
172 | |||
173 | const command = new GetObjectCommand({ | ||
174 | Bucket: bucketInfo.BUCKET_NAME, | ||
175 | Key: buildKey(key, bucketInfo), | ||
176 | Range: rangeHeader | ||
177 | }) | ||
178 | |||
179 | const response = await getClient().send(command) | ||
180 | |||
181 | return response.Body as Readable | ||
182 | } | ||
183 | |||
184 | // --------------------------------------------------------------------------- | ||
185 | |||
141 | export { | 186 | export { |
142 | BucketInfo, | 187 | BucketInfo, |
143 | buildKey, | 188 | buildKey, |
189 | |||
144 | storeObject, | 190 | storeObject, |
191 | |||
145 | removeObject, | 192 | removeObject, |
146 | removePrefix, | 193 | removePrefix, |
194 | |||
147 | makeAvailable, | 195 | makeAvailable, |
148 | listKeysOfPrefix | 196 | |
197 | updateObjectACL, | ||
198 | updatePrefixACL, | ||
199 | |||
200 | listKeysOfPrefix, | ||
201 | createObjectReadStream | ||
149 | } | 202 | } |
150 | 203 | ||
151 | // --------------------------------------------------------------------------- | 204 | // --------------------------------------------------------------------------- |
@@ -154,17 +207,15 @@ async function uploadToStorage (options: { | |||
154 | content: ReadStream | 207 | content: ReadStream |
155 | objectStorageKey: string | 208 | objectStorageKey: string |
156 | bucketInfo: BucketInfo | 209 | bucketInfo: BucketInfo |
210 | isPrivate: boolean | ||
157 | }) { | 211 | }) { |
158 | const { content, objectStorageKey, bucketInfo } = options | 212 | const { content, objectStorageKey, bucketInfo, isPrivate } = options |
159 | 213 | ||
160 | const input: PutObjectCommandInput = { | 214 | const input: PutObjectCommandInput = { |
161 | Body: content, | 215 | Body: content, |
162 | Bucket: bucketInfo.BUCKET_NAME, | 216 | Bucket: bucketInfo.BUCKET_NAME, |
163 | Key: buildKey(objectStorageKey, bucketInfo) | 217 | Key: buildKey(objectStorageKey, bucketInfo), |
164 | } | 218 | ACL: getACL(isPrivate) |
165 | |||
166 | if (CONFIG.OBJECT_STORAGE.UPLOAD_ACL) { | ||
167 | input.ACL = CONFIG.OBJECT_STORAGE.UPLOAD_ACL | ||
168 | } | 219 | } |
169 | 220 | ||
170 | const parallelUploads3 = new Upload({ | 221 | const parallelUploads3 = new Upload({ |
@@ -194,5 +245,50 @@ async function uploadToStorage (options: { | |||
194 | bucketInfo.PREFIX, objectStorageKey, bucketInfo.BUCKET_NAME, lTags() | 245 | bucketInfo.PREFIX, objectStorageKey, bucketInfo.BUCKET_NAME, lTags() |
195 | ) | 246 | ) |
196 | 247 | ||
197 | return getPrivateUrl(bucketInfo, objectStorageKey) | 248 | return getInternalUrl(bucketInfo, objectStorageKey) |
249 | } | ||
250 | |||
251 | async function applyOnPrefix (options: { | ||
252 | prefix: string | ||
253 | bucketInfo: BucketInfo | ||
254 | commandBuilder: (obj: _Object) => Parameters<S3Client['send']>[0] | ||
255 | |||
256 | continuationToken?: string | ||
257 | }) { | ||
258 | const { prefix, bucketInfo, commandBuilder, continuationToken } = options | ||
259 | |||
260 | const s3Client = getClient() | ||
261 | |||
262 | const commandPrefix = bucketInfo.PREFIX + prefix | ||
263 | const listCommand = new ListObjectsV2Command({ | ||
264 | Bucket: bucketInfo.BUCKET_NAME, | ||
265 | Prefix: commandPrefix, | ||
266 | ContinuationToken: continuationToken | ||
267 | }) | ||
268 | |||
269 | const listedObjects = await s3Client.send(listCommand) | ||
270 | |||
271 | if (isArray(listedObjects.Contents) !== true) { | ||
272 | const message = `Cannot apply function on ${commandPrefix} prefix in bucket ${bucketInfo.BUCKET_NAME}: no files listed.` | ||
273 | |||
274 | logger.error(message, { response: listedObjects, ...lTags() }) | ||
275 | throw new Error(message) | ||
276 | } | ||
277 | |||
278 | for (const object of listedObjects.Contents) { | ||
279 | const command = commandBuilder(object) | ||
280 | |||
281 | await s3Client.send(command) | ||
282 | } | ||
283 | |||
284 | // Repeat if not all objects could be listed at once (limit of 1000?) | ||
285 | if (listedObjects.IsTruncated) { | ||
286 | await applyOnPrefix({ ...options, continuationToken: listedObjects.ContinuationToken }) | ||
287 | } | ||
288 | } | ||
289 | |||
290 | function getACL (isPrivate: boolean) { | ||
291 | return isPrivate | ||
292 | ? CONFIG.OBJECT_STORAGE.UPLOAD_ACL.PRIVATE | ||
293 | : CONFIG.OBJECT_STORAGE.UPLOAD_ACL.PUBLIC | ||
198 | } | 294 | } |
diff --git a/server/lib/object-storage/urls.ts b/server/lib/object-storage/urls.ts index 2a889190b..a47a98b98 100644 --- a/server/lib/object-storage/urls.ts +++ b/server/lib/object-storage/urls.ts | |||
@@ -1,10 +1,14 @@ | |||
1 | import { CONFIG } from '@server/initializers/config' | 1 | import { CONFIG } from '@server/initializers/config' |
2 | import { OBJECT_STORAGE_PROXY_PATHS, WEBSERVER } from '@server/initializers/constants' | ||
3 | import { MVideoUUID } from '@server/types/models' | ||
2 | import { BucketInfo, buildKey, getEndpointParsed } from './shared' | 4 | import { BucketInfo, buildKey, getEndpointParsed } from './shared' |
3 | 5 | ||
4 | function getPrivateUrl (config: BucketInfo, keyWithoutPrefix: string) { | 6 | function getInternalUrl (config: BucketInfo, keyWithoutPrefix: string) { |
5 | return getBaseUrl(config) + buildKey(keyWithoutPrefix, config) | 7 | return getBaseUrl(config) + buildKey(keyWithoutPrefix, config) |
6 | } | 8 | } |
7 | 9 | ||
10 | // --------------------------------------------------------------------------- | ||
11 | |||
8 | function getWebTorrentPublicFileUrl (fileUrl: string) { | 12 | function getWebTorrentPublicFileUrl (fileUrl: string) { |
9 | const baseUrl = CONFIG.OBJECT_STORAGE.VIDEOS.BASE_URL | 13 | const baseUrl = CONFIG.OBJECT_STORAGE.VIDEOS.BASE_URL |
10 | if (!baseUrl) return fileUrl | 14 | if (!baseUrl) return fileUrl |
@@ -19,11 +23,28 @@ function getHLSPublicFileUrl (fileUrl: string) { | |||
19 | return replaceByBaseUrl(fileUrl, baseUrl) | 23 | return replaceByBaseUrl(fileUrl, baseUrl) |
20 | } | 24 | } |
21 | 25 | ||
26 | // --------------------------------------------------------------------------- | ||
27 | |||
28 | function getHLSPrivateFileUrl (video: MVideoUUID, filename: string) { | ||
29 | return WEBSERVER.URL + OBJECT_STORAGE_PROXY_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS + video.uuid + `/${filename}` | ||
30 | } | ||
31 | |||
32 | function getWebTorrentPrivateFileUrl (filename: string) { | ||
33 | return WEBSERVER.URL + OBJECT_STORAGE_PROXY_PATHS.PRIVATE_WEBSEED + filename | ||
34 | } | ||
35 | |||
36 | // --------------------------------------------------------------------------- | ||
37 | |||
22 | export { | 38 | export { |
23 | getPrivateUrl, | 39 | getInternalUrl, |
40 | |||
24 | getWebTorrentPublicFileUrl, | 41 | getWebTorrentPublicFileUrl, |
25 | replaceByBaseUrl, | 42 | getHLSPublicFileUrl, |
26 | getHLSPublicFileUrl | 43 | |
44 | getHLSPrivateFileUrl, | ||
45 | getWebTorrentPrivateFileUrl, | ||
46 | |||
47 | replaceByBaseUrl | ||
27 | } | 48 | } |
28 | 49 | ||
29 | // --------------------------------------------------------------------------- | 50 | // --------------------------------------------------------------------------- |
diff --git a/server/lib/object-storage/videos.ts b/server/lib/object-storage/videos.ts index e323baaa2..003807826 100644 --- a/server/lib/object-storage/videos.ts +++ b/server/lib/object-storage/videos.ts | |||
@@ -5,7 +5,17 @@ import { MStreamingPlaylistVideo, MVideo, MVideoFile } from '@server/types/model | |||
5 | import { getHLSDirectory } from '../paths' | 5 | import { getHLSDirectory } from '../paths' |
6 | import { VideoPathManager } from '../video-path-manager' | 6 | import { VideoPathManager } from '../video-path-manager' |
7 | import { generateHLSObjectBaseStorageKey, generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys' | 7 | import { generateHLSObjectBaseStorageKey, generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys' |
8 | import { listKeysOfPrefix, lTags, makeAvailable, removeObject, removePrefix, storeObject } from './shared' | 8 | import { |
9 | createObjectReadStream, | ||
10 | listKeysOfPrefix, | ||
11 | lTags, | ||
12 | makeAvailable, | ||
13 | removeObject, | ||
14 | removePrefix, | ||
15 | storeObject, | ||
16 | updateObjectACL, | ||
17 | updatePrefixACL | ||
18 | } from './shared' | ||
9 | 19 | ||
10 | function listHLSFileKeysOf (playlist: MStreamingPlaylistVideo) { | 20 | function listHLSFileKeysOf (playlist: MStreamingPlaylistVideo) { |
11 | return listKeysOfPrefix(generateHLSObjectBaseStorageKey(playlist), CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS) | 21 | return listKeysOfPrefix(generateHLSObjectBaseStorageKey(playlist), CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS) |
@@ -17,7 +27,8 @@ function storeHLSFileFromFilename (playlist: MStreamingPlaylistVideo, filename: | |||
17 | return storeObject({ | 27 | return storeObject({ |
18 | inputPath: join(getHLSDirectory(playlist.Video), filename), | 28 | inputPath: join(getHLSDirectory(playlist.Video), filename), |
19 | objectStorageKey: generateHLSObjectStorageKey(playlist, filename), | 29 | objectStorageKey: generateHLSObjectStorageKey(playlist, filename), |
20 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS | 30 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS, |
31 | isPrivate: playlist.Video.hasPrivateStaticPath() | ||
21 | }) | 32 | }) |
22 | } | 33 | } |
23 | 34 | ||
@@ -25,7 +36,8 @@ function storeHLSFileFromPath (playlist: MStreamingPlaylistVideo, path: string) | |||
25 | return storeObject({ | 36 | return storeObject({ |
26 | inputPath: path, | 37 | inputPath: path, |
27 | objectStorageKey: generateHLSObjectStorageKey(playlist, basename(path)), | 38 | objectStorageKey: generateHLSObjectStorageKey(playlist, basename(path)), |
28 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS | 39 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS, |
40 | isPrivate: playlist.Video.hasPrivateStaticPath() | ||
29 | }) | 41 | }) |
30 | } | 42 | } |
31 | 43 | ||
@@ -35,7 +47,26 @@ function storeWebTorrentFile (video: MVideo, file: MVideoFile) { | |||
35 | return storeObject({ | 47 | return storeObject({ |
36 | inputPath: VideoPathManager.Instance.getFSVideoFileOutputPath(video, file), | 48 | inputPath: VideoPathManager.Instance.getFSVideoFileOutputPath(video, file), |
37 | objectStorageKey: generateWebTorrentObjectStorageKey(file.filename), | 49 | objectStorageKey: generateWebTorrentObjectStorageKey(file.filename), |
38 | bucketInfo: CONFIG.OBJECT_STORAGE.VIDEOS | 50 | bucketInfo: CONFIG.OBJECT_STORAGE.VIDEOS, |
51 | isPrivate: video.hasPrivateStaticPath() | ||
52 | }) | ||
53 | } | ||
54 | |||
55 | // --------------------------------------------------------------------------- | ||
56 | |||
57 | function updateWebTorrentFileACL (video: MVideo, file: MVideoFile) { | ||
58 | return updateObjectACL({ | ||
59 | objectStorageKey: generateWebTorrentObjectStorageKey(file.filename), | ||
60 | bucketInfo: CONFIG.OBJECT_STORAGE.VIDEOS, | ||
61 | isPrivate: video.hasPrivateStaticPath() | ||
62 | }) | ||
63 | } | ||
64 | |||
65 | function updateHLSFilesACL (playlist: MStreamingPlaylistVideo) { | ||
66 | return updatePrefixACL({ | ||
67 | prefix: generateHLSObjectBaseStorageKey(playlist), | ||
68 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS, | ||
69 | isPrivate: playlist.Video.hasPrivateStaticPath() | ||
39 | }) | 70 | }) |
40 | } | 71 | } |
41 | 72 | ||
@@ -87,6 +118,39 @@ async function makeWebTorrentFileAvailable (filename: string, destination: strin | |||
87 | 118 | ||
88 | // --------------------------------------------------------------------------- | 119 | // --------------------------------------------------------------------------- |
89 | 120 | ||
121 | function getWebTorrentFileReadStream (options: { | ||
122 | filename: string | ||
123 | rangeHeader: string | ||
124 | }) { | ||
125 | const { filename, rangeHeader } = options | ||
126 | |||
127 | const key = generateWebTorrentObjectStorageKey(filename) | ||
128 | |||
129 | return createObjectReadStream({ | ||
130 | key, | ||
131 | bucketInfo: CONFIG.OBJECT_STORAGE.VIDEOS, | ||
132 | rangeHeader | ||
133 | }) | ||
134 | } | ||
135 | |||
136 | function getHLSFileReadStream (options: { | ||
137 | playlist: MStreamingPlaylistVideo | ||
138 | filename: string | ||
139 | rangeHeader: string | ||
140 | }) { | ||
141 | const { playlist, filename, rangeHeader } = options | ||
142 | |||
143 | const key = generateHLSObjectStorageKey(playlist, filename) | ||
144 | |||
145 | return createObjectReadStream({ | ||
146 | key, | ||
147 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS, | ||
148 | rangeHeader | ||
149 | }) | ||
150 | } | ||
151 | |||
152 | // --------------------------------------------------------------------------- | ||
153 | |||
90 | export { | 154 | export { |
91 | listHLSFileKeysOf, | 155 | listHLSFileKeysOf, |
92 | 156 | ||
@@ -94,10 +158,16 @@ export { | |||
94 | storeHLSFileFromFilename, | 158 | storeHLSFileFromFilename, |
95 | storeHLSFileFromPath, | 159 | storeHLSFileFromPath, |
96 | 160 | ||
161 | updateWebTorrentFileACL, | ||
162 | updateHLSFilesACL, | ||
163 | |||
97 | removeHLSObjectStorage, | 164 | removeHLSObjectStorage, |
98 | removeHLSFileObjectStorage, | 165 | removeHLSFileObjectStorage, |
99 | removeWebTorrentObjectStorage, | 166 | removeWebTorrentObjectStorage, |
100 | 167 | ||
101 | makeWebTorrentFileAvailable, | 168 | makeWebTorrentFileAvailable, |
102 | makeHLSFileAvailable | 169 | makeHLSFileAvailable, |
170 | |||
171 | getWebTorrentFileReadStream, | ||
172 | getHLSFileReadStream | ||
103 | } | 173 | } |
diff --git a/server/lib/video-privacy.ts b/server/lib/video-privacy.ts index 1a4a5a22d..41f9d62b3 100644 --- a/server/lib/video-privacy.ts +++ b/server/lib/video-privacy.ts | |||
@@ -2,8 +2,9 @@ import { move } from 'fs-extra' | |||
2 | import { join } from 'path' | 2 | import { join } from 'path' |
3 | import { logger } from '@server/helpers/logger' | 3 | import { logger } from '@server/helpers/logger' |
4 | import { DIRECTORIES } from '@server/initializers/constants' | 4 | import { DIRECTORIES } from '@server/initializers/constants' |
5 | import { MVideo, MVideoFullLight } from '@server/types/models' | 5 | import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' |
6 | import { VideoPrivacy } from '@shared/models' | 6 | import { VideoPrivacy, VideoStorage } from '@shared/models' |
7 | import { updateHLSFilesACL, updateWebTorrentFileACL } from './object-storage' | ||
7 | 8 | ||
8 | function setVideoPrivacy (video: MVideo, newPrivacy: VideoPrivacy) { | 9 | function setVideoPrivacy (video: MVideo, newPrivacy: VideoPrivacy) { |
9 | if (video.privacy === VideoPrivacy.PRIVATE && newPrivacy !== VideoPrivacy.PRIVATE) { | 10 | if (video.privacy === VideoPrivacy.PRIVATE && newPrivacy !== VideoPrivacy.PRIVATE) { |
@@ -50,47 +51,77 @@ export { | |||
50 | 51 | ||
51 | // --------------------------------------------------------------------------- | 52 | // --------------------------------------------------------------------------- |
52 | 53 | ||
54 | type MoveType = 'private-to-public' | 'public-to-private' | ||
55 | |||
53 | async function moveFiles (options: { | 56 | async function moveFiles (options: { |
54 | type: 'private-to-public' | 'public-to-private' | 57 | type: MoveType |
55 | video: MVideoFullLight | 58 | video: MVideoFullLight |
56 | }) { | 59 | }) { |
57 | const { type, video } = options | 60 | const { type, video } = options |
58 | 61 | ||
59 | const directories = type === 'private-to-public' | 62 | for (const file of video.VideoFiles) { |
60 | ? { | 63 | if (file.storage === VideoStorage.FILE_SYSTEM) { |
61 | webtorrent: { old: DIRECTORIES.VIDEOS.PRIVATE, new: DIRECTORIES.VIDEOS.PUBLIC }, | 64 | await moveWebTorrentFileOnFS(type, video, file) |
62 | hls: { old: DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE, new: DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC } | 65 | } else { |
66 | await updateWebTorrentFileACL(video, file) | ||
63 | } | 67 | } |
64 | : { | 68 | } |
65 | webtorrent: { old: DIRECTORIES.VIDEOS.PUBLIC, new: DIRECTORIES.VIDEOS.PRIVATE }, | 69 | |
66 | hls: { old: DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC, new: DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE } | 70 | const hls = video.getHLSPlaylist() |
71 | |||
72 | if (hls) { | ||
73 | if (hls.storage === VideoStorage.FILE_SYSTEM) { | ||
74 | await moveHLSFilesOnFS(type, video) | ||
75 | } else { | ||
76 | await updateHLSFilesACL(hls) | ||
67 | } | 77 | } |
78 | } | ||
79 | } | ||
68 | 80 | ||
69 | for (const file of video.VideoFiles) { | 81 | async function moveWebTorrentFileOnFS (type: MoveType, video: MVideo, file: MVideoFile) { |
70 | const source = join(directories.webtorrent.old, file.filename) | 82 | const directories = getWebTorrentDirectories(type) |
71 | const destination = join(directories.webtorrent.new, file.filename) | ||
72 | 83 | ||
73 | try { | 84 | const source = join(directories.old, file.filename) |
74 | logger.info('Moving WebTorrent files of %s after privacy change (%s -> %s).', video.uuid, source, destination) | 85 | const destination = join(directories.new, file.filename) |
75 | 86 | ||
76 | await move(source, destination) | 87 | try { |
77 | } catch (err) { | 88 | logger.info('Moving WebTorrent files of %s after privacy change (%s -> %s).', video.uuid, source, destination) |
78 | logger.error('Cannot move webtorrent file %s to %s after privacy change', source, destination, { err }) | 89 | |
79 | } | 90 | await move(source, destination) |
91 | } catch (err) { | ||
92 | logger.error('Cannot move webtorrent file %s to %s after privacy change', source, destination, { err }) | ||
93 | } | ||
94 | } | ||
95 | |||
96 | function getWebTorrentDirectories (moveType: MoveType) { | ||
97 | if (moveType === 'private-to-public') { | ||
98 | return { old: DIRECTORIES.VIDEOS.PRIVATE, new: DIRECTORIES.VIDEOS.PUBLIC } | ||
80 | } | 99 | } |
81 | 100 | ||
82 | const hls = video.getHLSPlaylist() | 101 | return { old: DIRECTORIES.VIDEOS.PUBLIC, new: DIRECTORIES.VIDEOS.PRIVATE } |
102 | } | ||
83 | 103 | ||
84 | if (hls) { | 104 | // --------------------------------------------------------------------------- |
85 | const source = join(directories.hls.old, video.uuid) | ||
86 | const destination = join(directories.hls.new, video.uuid) | ||
87 | 105 | ||
88 | try { | 106 | async function moveHLSFilesOnFS (type: MoveType, video: MVideo) { |
89 | logger.info('Moving HLS files of %s after privacy change (%s -> %s).', video.uuid, source, destination) | 107 | const directories = getHLSDirectories(type) |
90 | 108 | ||
91 | await move(source, destination) | 109 | const source = join(directories.old, video.uuid) |
92 | } catch (err) { | 110 | const destination = join(directories.new, video.uuid) |
93 | logger.error('Cannot move HLS file %s to %s after privacy change', source, destination, { err }) | 111 | |
94 | } | 112 | try { |
113 | logger.info('Moving HLS files of %s after privacy change (%s -> %s).', video.uuid, source, destination) | ||
114 | |||
115 | await move(source, destination) | ||
116 | } catch (err) { | ||
117 | logger.error('Cannot move HLS file %s to %s after privacy change', source, destination, { err }) | ||
118 | } | ||
119 | } | ||
120 | |||
121 | function getHLSDirectories (moveType: MoveType) { | ||
122 | if (moveType === 'private-to-public') { | ||
123 | return { old: DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE, new: DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC } | ||
95 | } | 124 | } |
125 | |||
126 | return { old: DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC, new: DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE } | ||
96 | } | 127 | } |
diff --git a/server/middlewares/validators/shared/videos.ts b/server/middlewares/validators/shared/videos.ts index c29751eca..ebbfc0a0a 100644 --- a/server/middlewares/validators/shared/videos.ts +++ b/server/middlewares/validators/shared/videos.ts | |||
@@ -111,7 +111,7 @@ async function checkCanSeeVideo (options: { | |||
111 | }) { | 111 | }) { |
112 | const { req, res, video, paramId } = options | 112 | const { req, res, video, paramId } = options |
113 | 113 | ||
114 | if (video.requiresAuth(paramId)) { | 114 | if (video.requiresAuth({ urlParamId: paramId, checkBlacklist: true })) { |
115 | return checkCanSeeAuthVideo(req, res, video) | 115 | return checkCanSeeAuthVideo(req, res, video) |
116 | } | 116 | } |
117 | 117 | ||
@@ -174,13 +174,13 @@ async function checkCanAccessVideoStaticFiles (options: { | |||
174 | res: Response | 174 | res: Response |
175 | paramId: string | 175 | paramId: string |
176 | }) { | 176 | }) { |
177 | const { video, req, res, paramId } = options | 177 | const { video, req, res } = options |
178 | 178 | ||
179 | if (res.locals.oauth?.token.User) { | 179 | if (res.locals.oauth?.token.User) { |
180 | return checkCanSeeVideo(options) | 180 | return checkCanSeeVideo(options) |
181 | } | 181 | } |
182 | 182 | ||
183 | if (!video.requiresAuth(paramId)) return true | 183 | if (!video.hasPrivateStaticPath()) return true |
184 | 184 | ||
185 | const videoFileToken = req.query.videoFileToken | 185 | const videoFileToken = req.query.videoFileToken |
186 | if (!videoFileToken) { | 186 | if (!videoFileToken) { |
diff --git a/server/middlewares/validators/static.ts b/server/middlewares/validators/static.ts index ff9e6ae6e..13fde6dd1 100644 --- a/server/middlewares/validators/static.ts +++ b/server/middlewares/validators/static.ts | |||
@@ -7,10 +7,17 @@ import { logger } from '@server/helpers/logger' | |||
7 | import { LRU_CACHE } from '@server/initializers/constants' | 7 | import { LRU_CACHE } from '@server/initializers/constants' |
8 | import { VideoModel } from '@server/models/video/video' | 8 | import { VideoModel } from '@server/models/video/video' |
9 | import { VideoFileModel } from '@server/models/video/video-file' | 9 | import { VideoFileModel } from '@server/models/video/video-file' |
10 | import { MStreamingPlaylist, MVideoFile, MVideoThumbnail } from '@server/types/models' | ||
10 | import { HttpStatusCode } from '@shared/models' | 11 | import { HttpStatusCode } from '@shared/models' |
11 | import { areValidationErrors, checkCanAccessVideoStaticFiles } from './shared' | 12 | import { areValidationErrors, checkCanAccessVideoStaticFiles } from './shared' |
12 | 13 | ||
13 | const staticFileTokenBypass = new LRUCache<string, boolean>({ | 14 | type LRUValue = { |
15 | allowed: boolean | ||
16 | video?: MVideoThumbnail | ||
17 | file?: MVideoFile | ||
18 | playlist?: MStreamingPlaylist } | ||
19 | |||
20 | const staticFileTokenBypass = new LRUCache<string, LRUValue>({ | ||
14 | max: LRU_CACHE.STATIC_VIDEO_FILES_RIGHTS_CHECK.MAX_SIZE, | 21 | max: LRU_CACHE.STATIC_VIDEO_FILES_RIGHTS_CHECK.MAX_SIZE, |
15 | ttl: LRU_CACHE.STATIC_VIDEO_FILES_RIGHTS_CHECK.TTL | 22 | ttl: LRU_CACHE.STATIC_VIDEO_FILES_RIGHTS_CHECK.TTL |
16 | }) | 23 | }) |
@@ -27,18 +34,26 @@ const ensureCanAccessVideoPrivateWebTorrentFiles = [ | |||
27 | const cacheKey = token + '-' + req.originalUrl | 34 | const cacheKey = token + '-' + req.originalUrl |
28 | 35 | ||
29 | if (staticFileTokenBypass.has(cacheKey)) { | 36 | if (staticFileTokenBypass.has(cacheKey)) { |
30 | const allowedFromCache = staticFileTokenBypass.get(cacheKey) | 37 | const { allowed, file, video } = staticFileTokenBypass.get(cacheKey) |
38 | |||
39 | if (allowed === true) { | ||
40 | res.locals.onlyVideo = video | ||
41 | res.locals.videoFile = file | ||
31 | 42 | ||
32 | if (allowedFromCache === true) return next() | 43 | return next() |
44 | } | ||
33 | 45 | ||
34 | return res.sendStatus(HttpStatusCode.FORBIDDEN_403) | 46 | return res.sendStatus(HttpStatusCode.FORBIDDEN_403) |
35 | } | 47 | } |
36 | 48 | ||
37 | const allowed = await isWebTorrentAllowed(req, res) | 49 | const result = await isWebTorrentAllowed(req, res) |
50 | |||
51 | staticFileTokenBypass.set(cacheKey, result) | ||
38 | 52 | ||
39 | staticFileTokenBypass.set(cacheKey, allowed) | 53 | if (result.allowed !== true) return |
40 | 54 | ||
41 | if (allowed !== true) return | 55 | res.locals.onlyVideo = result.video |
56 | res.locals.videoFile = result.file | ||
42 | 57 | ||
43 | return next() | 58 | return next() |
44 | } | 59 | } |
@@ -64,18 +79,28 @@ const ensureCanAccessPrivateVideoHLSFiles = [ | |||
64 | const cacheKey = token + '-' + videoUUID | 79 | const cacheKey = token + '-' + videoUUID |
65 | 80 | ||
66 | if (staticFileTokenBypass.has(cacheKey)) { | 81 | if (staticFileTokenBypass.has(cacheKey)) { |
67 | const allowedFromCache = staticFileTokenBypass.get(cacheKey) | 82 | const { allowed, file, playlist, video } = staticFileTokenBypass.get(cacheKey) |
68 | 83 | ||
69 | if (allowedFromCache === true) return next() | 84 | if (allowed === true) { |
85 | res.locals.onlyVideo = video | ||
86 | res.locals.videoFile = file | ||
87 | res.locals.videoStreamingPlaylist = playlist | ||
88 | |||
89 | return next() | ||
90 | } | ||
70 | 91 | ||
71 | return res.sendStatus(HttpStatusCode.FORBIDDEN_403) | 92 | return res.sendStatus(HttpStatusCode.FORBIDDEN_403) |
72 | } | 93 | } |
73 | 94 | ||
74 | const allowed = await isHLSAllowed(req, res, videoUUID) | 95 | const result = await isHLSAllowed(req, res, videoUUID) |
96 | |||
97 | staticFileTokenBypass.set(cacheKey, result) | ||
75 | 98 | ||
76 | staticFileTokenBypass.set(cacheKey, allowed) | 99 | if (result.allowed !== true) return |
77 | 100 | ||
78 | if (allowed !== true) return | 101 | res.locals.onlyVideo = result.video |
102 | res.locals.videoFile = result.file | ||
103 | res.locals.videoStreamingPlaylist = result.playlist | ||
79 | 104 | ||
80 | return next() | 105 | return next() |
81 | } | 106 | } |
@@ -96,25 +121,38 @@ async function isWebTorrentAllowed (req: express.Request, res: express.Response) | |||
96 | logger.debug('Unknown static file %s to serve', req.originalUrl, { filename }) | 121 | logger.debug('Unknown static file %s to serve', req.originalUrl, { filename }) |
97 | 122 | ||
98 | res.sendStatus(HttpStatusCode.FORBIDDEN_403) | 123 | res.sendStatus(HttpStatusCode.FORBIDDEN_403) |
99 | return false | 124 | return { allowed: false } |
100 | } | 125 | } |
101 | 126 | ||
102 | const video = file.getVideo() | 127 | const video = await VideoModel.load(file.getVideo().id) |
103 | 128 | ||
104 | return checkCanAccessVideoStaticFiles({ req, res, video, paramId: video.uuid }) | 129 | return { |
130 | file, | ||
131 | video, | ||
132 | allowed: await checkCanAccessVideoStaticFiles({ req, res, video, paramId: video.uuid }) | ||
133 | } | ||
105 | } | 134 | } |
106 | 135 | ||
107 | async function isHLSAllowed (req: express.Request, res: express.Response, videoUUID: string) { | 136 | async function isHLSAllowed (req: express.Request, res: express.Response, videoUUID: string) { |
108 | const video = await VideoModel.load(videoUUID) | 137 | const filename = basename(req.path) |
138 | |||
139 | const video = await VideoModel.loadWithFiles(videoUUID) | ||
109 | 140 | ||
110 | if (!video) { | 141 | if (!video) { |
111 | logger.debug('Unknown static file %s to serve', req.originalUrl, { videoUUID }) | 142 | logger.debug('Unknown static file %s to serve', req.originalUrl, { videoUUID }) |
112 | 143 | ||
113 | res.sendStatus(HttpStatusCode.FORBIDDEN_403) | 144 | res.sendStatus(HttpStatusCode.FORBIDDEN_403) |
114 | return false | 145 | return { allowed: false } |
115 | } | 146 | } |
116 | 147 | ||
117 | return checkCanAccessVideoStaticFiles({ req, res, video, paramId: video.uuid }) | 148 | const file = await VideoFileModel.loadByFilename(filename) |
149 | |||
150 | return { | ||
151 | file, | ||
152 | video, | ||
153 | playlist: video.getHLSPlaylist(), | ||
154 | allowed: await checkCanAccessVideoStaticFiles({ req, res, video, paramId: video.uuid }) | ||
155 | } | ||
118 | } | 156 | } |
119 | 157 | ||
120 | function extractTokenOrDie (req: express.Request, res: express.Response) { | 158 | function extractTokenOrDie (req: express.Request, res: express.Response) { |
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts index 1a608932f..c20c90c1b 100644 --- a/server/models/video/video-file.ts +++ b/server/models/video/video-file.ts | |||
@@ -22,7 +22,12 @@ import validator from 'validator' | |||
22 | import { logger } from '@server/helpers/logger' | 22 | import { logger } from '@server/helpers/logger' |
23 | import { extractVideo } from '@server/helpers/video' | 23 | import { extractVideo } from '@server/helpers/video' |
24 | import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url' | 24 | import { buildRemoteVideoBaseUrl } from '@server/lib/activitypub/url' |
25 | import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' | 25 | import { |
26 | getHLSPrivateFileUrl, | ||
27 | getHLSPublicFileUrl, | ||
28 | getWebTorrentPrivateFileUrl, | ||
29 | getWebTorrentPublicFileUrl | ||
30 | } from '@server/lib/object-storage' | ||
26 | import { getFSTorrentFilePath } from '@server/lib/paths' | 31 | import { getFSTorrentFilePath } from '@server/lib/paths' |
27 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' | 32 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' |
28 | import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' | 33 | import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' |
@@ -503,7 +508,25 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel> | |||
503 | return !!this.videoStreamingPlaylistId | 508 | return !!this.videoStreamingPlaylistId |
504 | } | 509 | } |
505 | 510 | ||
506 | getObjectStorageUrl () { | 511 | // --------------------------------------------------------------------------- |
512 | |||
513 | getObjectStorageUrl (video: MVideo) { | ||
514 | if (video.hasPrivateStaticPath()) { | ||
515 | return this.getPrivateObjectStorageUrl(video) | ||
516 | } | ||
517 | |||
518 | return this.getPublicObjectStorageUrl() | ||
519 | } | ||
520 | |||
521 | private getPrivateObjectStorageUrl (video: MVideo) { | ||
522 | if (this.isHLS()) { | ||
523 | return getHLSPrivateFileUrl(video, this.filename) | ||
524 | } | ||
525 | |||
526 | return getWebTorrentPrivateFileUrl(this.filename) | ||
527 | } | ||
528 | |||
529 | private getPublicObjectStorageUrl () { | ||
507 | if (this.isHLS()) { | 530 | if (this.isHLS()) { |
508 | return getHLSPublicFileUrl(this.fileUrl) | 531 | return getHLSPublicFileUrl(this.fileUrl) |
509 | } | 532 | } |
@@ -511,26 +534,29 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel> | |||
511 | return getWebTorrentPublicFileUrl(this.fileUrl) | 534 | return getWebTorrentPublicFileUrl(this.fileUrl) |
512 | } | 535 | } |
513 | 536 | ||
537 | // --------------------------------------------------------------------------- | ||
538 | |||
514 | getFileUrl (video: MVideo) { | 539 | getFileUrl (video: MVideo) { |
515 | if (this.storage === VideoStorage.OBJECT_STORAGE) { | 540 | if (video.isOwned()) { |
516 | return this.getObjectStorageUrl() | 541 | if (this.storage === VideoStorage.OBJECT_STORAGE) { |
517 | } | 542 | return this.getObjectStorageUrl(video) |
543 | } | ||
518 | 544 | ||
519 | if (!this.Video) this.Video = video as VideoModel | 545 | return WEBSERVER.URL + this.getFileStaticPath(video) |
520 | if (video.isOwned()) return WEBSERVER.URL + this.getFileStaticPath(video) | 546 | } |
521 | 547 | ||
522 | return this.fileUrl | 548 | return this.fileUrl |
523 | } | 549 | } |
524 | 550 | ||
551 | // --------------------------------------------------------------------------- | ||
552 | |||
525 | getFileStaticPath (video: MVideo) { | 553 | getFileStaticPath (video: MVideo) { |
526 | if (this.isHLS()) { | 554 | if (this.isHLS()) return this.getHLSFileStaticPath(video) |
527 | if (isVideoInPrivateDirectory(video.privacy)) { | ||
528 | return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.filename) | ||
529 | } | ||
530 | 555 | ||
531 | return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.filename) | 556 | return this.getWebTorrentFileStaticPath(video) |
532 | } | 557 | } |
533 | 558 | ||
559 | private getWebTorrentFileStaticPath (video: MVideo) { | ||
534 | if (isVideoInPrivateDirectory(video.privacy)) { | 560 | if (isVideoInPrivateDirectory(video.privacy)) { |
535 | return join(STATIC_PATHS.PRIVATE_WEBSEED, this.filename) | 561 | return join(STATIC_PATHS.PRIVATE_WEBSEED, this.filename) |
536 | } | 562 | } |
@@ -538,6 +564,16 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel> | |||
538 | return join(STATIC_PATHS.WEBSEED, this.filename) | 564 | return join(STATIC_PATHS.WEBSEED, this.filename) |
539 | } | 565 | } |
540 | 566 | ||
567 | private getHLSFileStaticPath (video: MVideo) { | ||
568 | if (isVideoInPrivateDirectory(video.privacy)) { | ||
569 | return join(STATIC_PATHS.STREAMING_PLAYLISTS.PRIVATE_HLS, video.uuid, this.filename) | ||
570 | } | ||
571 | |||
572 | return join(STATIC_PATHS.STREAMING_PLAYLISTS.HLS, video.uuid, this.filename) | ||
573 | } | ||
574 | |||
575 | // --------------------------------------------------------------------------- | ||
576 | |||
541 | getFileDownloadUrl (video: MVideoWithHost) { | 577 | getFileDownloadUrl (video: MVideoWithHost) { |
542 | const path = this.isHLS() | 578 | const path = this.isHLS() |
543 | ? join(STATIC_DOWNLOAD_PATHS.HLS_VIDEOS, `${video.uuid}-${this.resolution}-fragmented${this.extname}`) | 579 | ? join(STATIC_DOWNLOAD_PATHS.HLS_VIDEOS, `${video.uuid}-${this.resolution}-fragmented${this.extname}`) |
diff --git a/server/models/video/video-streaming-playlist.ts b/server/models/video/video-streaming-playlist.ts index b919046ed..1318a4dae 100644 --- a/server/models/video/video-streaming-playlist.ts +++ b/server/models/video/video-streaming-playlist.ts | |||
@@ -15,7 +15,7 @@ import { | |||
15 | Table, | 15 | Table, |
16 | UpdatedAt | 16 | UpdatedAt |
17 | } from 'sequelize-typescript' | 17 | } from 'sequelize-typescript' |
18 | import { getHLSPublicFileUrl } from '@server/lib/object-storage' | 18 | import { getHLSPrivateFileUrl, getHLSPublicFileUrl } from '@server/lib/object-storage' |
19 | import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths' | 19 | import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename } from '@server/lib/paths' |
20 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' | 20 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' |
21 | import { VideoFileModel } from '@server/models/video/video-file' | 21 | import { VideoFileModel } from '@server/models/video/video-file' |
@@ -245,10 +245,12 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi | |||
245 | this.p2pMediaLoaderInfohashes = VideoStreamingPlaylistModel.buildP2PMediaLoaderInfoHashes(masterPlaylistUrl, files) | 245 | this.p2pMediaLoaderInfohashes = VideoStreamingPlaylistModel.buildP2PMediaLoaderInfoHashes(masterPlaylistUrl, files) |
246 | } | 246 | } |
247 | 247 | ||
248 | // --------------------------------------------------------------------------- | ||
249 | |||
248 | getMasterPlaylistUrl (video: MVideo) { | 250 | getMasterPlaylistUrl (video: MVideo) { |
249 | if (video.isOwned()) { | 251 | if (video.isOwned()) { |
250 | if (this.storage === VideoStorage.OBJECT_STORAGE) { | 252 | if (this.storage === VideoStorage.OBJECT_STORAGE) { |
251 | return getHLSPublicFileUrl(this.playlistUrl) | 253 | return this.getMasterPlaylistObjectStorageUrl(video) |
252 | } | 254 | } |
253 | 255 | ||
254 | return WEBSERVER.URL + this.getMasterPlaylistStaticPath(video) | 256 | return WEBSERVER.URL + this.getMasterPlaylistStaticPath(video) |
@@ -257,10 +259,20 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi | |||
257 | return this.playlistUrl | 259 | return this.playlistUrl |
258 | } | 260 | } |
259 | 261 | ||
262 | private getMasterPlaylistObjectStorageUrl (video: MVideo) { | ||
263 | if (video.hasPrivateStaticPath()) { | ||
264 | return getHLSPrivateFileUrl(video, this.playlistFilename) | ||
265 | } | ||
266 | |||
267 | return getHLSPublicFileUrl(this.playlistUrl) | ||
268 | } | ||
269 | |||
270 | // --------------------------------------------------------------------------- | ||
271 | |||
260 | getSha256SegmentsUrl (video: MVideo) { | 272 | getSha256SegmentsUrl (video: MVideo) { |
261 | if (video.isOwned()) { | 273 | if (video.isOwned()) { |
262 | if (this.storage === VideoStorage.OBJECT_STORAGE) { | 274 | if (this.storage === VideoStorage.OBJECT_STORAGE) { |
263 | return getHLSPublicFileUrl(this.segmentsSha256Url) | 275 | return this.getSha256SegmentsObjectStorageUrl(video) |
264 | } | 276 | } |
265 | 277 | ||
266 | return WEBSERVER.URL + this.getSha256SegmentsStaticPath(video) | 278 | return WEBSERVER.URL + this.getSha256SegmentsStaticPath(video) |
@@ -269,6 +281,16 @@ export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<Vi | |||
269 | return this.segmentsSha256Url | 281 | return this.segmentsSha256Url |
270 | } | 282 | } |
271 | 283 | ||
284 | private getSha256SegmentsObjectStorageUrl (video: MVideo) { | ||
285 | if (video.hasPrivateStaticPath()) { | ||
286 | return getHLSPrivateFileUrl(video, this.segmentsSha256Filename) | ||
287 | } | ||
288 | |||
289 | return getHLSPublicFileUrl(this.segmentsSha256Url) | ||
290 | } | ||
291 | |||
292 | // --------------------------------------------------------------------------- | ||
293 | |||
272 | getStringType () { | 294 | getStringType () { |
273 | if (this.type === VideoStreamingPlaylistType.HLS) return 'hls' | 295 | if (this.type === VideoStreamingPlaylistType.HLS) return 'hls' |
274 | 296 | ||
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 82362917e..c568075d8 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -30,6 +30,7 @@ import { removeHLSFileObjectStorage, removeHLSObjectStorage, removeWebTorrentObj | |||
30 | import { tracer } from '@server/lib/opentelemetry/tracing' | 30 | import { tracer } from '@server/lib/opentelemetry/tracing' |
31 | import { getHLSDirectory, getHLSRedundancyDirectory, getHlsResolutionPlaylistFilename } from '@server/lib/paths' | 31 | import { getHLSDirectory, getHLSRedundancyDirectory, getHlsResolutionPlaylistFilename } from '@server/lib/paths' |
32 | import { VideoPathManager } from '@server/lib/video-path-manager' | 32 | import { VideoPathManager } from '@server/lib/video-path-manager' |
33 | import { isVideoInPrivateDirectory } from '@server/lib/video-privacy' | ||
33 | import { getServerActor } from '@server/models/application/application' | 34 | import { getServerActor } from '@server/models/application/application' |
34 | import { ModelCache } from '@server/models/model-cache' | 35 | import { ModelCache } from '@server/models/model-cache' |
35 | import { buildVideoEmbedPath, buildVideoWatchPath, pick } from '@shared/core-utils' | 36 | import { buildVideoEmbedPath, buildVideoWatchPath, pick } from '@shared/core-utils' |
@@ -1764,9 +1765,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> { | |||
1764 | const playlist = this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) | 1765 | const playlist = this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) |
1765 | if (!playlist) return undefined | 1766 | if (!playlist) return undefined |
1766 | 1767 | ||
1767 | playlist.Video = this | 1768 | return playlist.withVideo(this) |
1768 | |||
1769 | return playlist | ||
1770 | } | 1769 | } |
1771 | 1770 | ||
1772 | setHLSPlaylist (playlist: MStreamingPlaylist) { | 1771 | setHLSPlaylist (playlist: MStreamingPlaylist) { |
@@ -1868,16 +1867,39 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> { | |||
1868 | return setAsUpdated('video', this.id, transaction) | 1867 | return setAsUpdated('video', this.id, transaction) |
1869 | } | 1868 | } |
1870 | 1869 | ||
1871 | requiresAuth (paramId: string) { | 1870 | // --------------------------------------------------------------------------- |
1871 | |||
1872 | requiresAuth (options: { | ||
1873 | urlParamId: string | ||
1874 | checkBlacklist: boolean | ||
1875 | }) { | ||
1876 | const { urlParamId, checkBlacklist } = options | ||
1877 | |||
1878 | if (this.privacy === VideoPrivacy.PRIVATE || this.privacy === VideoPrivacy.INTERNAL) { | ||
1879 | return true | ||
1880 | } | ||
1881 | |||
1872 | if (this.privacy === VideoPrivacy.UNLISTED) { | 1882 | if (this.privacy === VideoPrivacy.UNLISTED) { |
1873 | if (!isUUIDValid(paramId)) return true | 1883 | if (urlParamId && !isUUIDValid(urlParamId)) return true |
1874 | 1884 | ||
1875 | return false | 1885 | return false |
1876 | } | 1886 | } |
1877 | 1887 | ||
1878 | return this.privacy === VideoPrivacy.PRIVATE || this.privacy === VideoPrivacy.INTERNAL || !!this.VideoBlacklist | 1888 | if (checkBlacklist && this.VideoBlacklist) return true |
1889 | |||
1890 | if (this.privacy !== VideoPrivacy.PUBLIC) { | ||
1891 | throw new Error(`Unknown video privacy ${this.privacy} to know if the video requires auth`) | ||
1892 | } | ||
1893 | |||
1894 | return false | ||
1879 | } | 1895 | } |
1880 | 1896 | ||
1897 | hasPrivateStaticPath () { | ||
1898 | return isVideoInPrivateDirectory(this.privacy) | ||
1899 | } | ||
1900 | |||
1901 | // --------------------------------------------------------------------------- | ||
1902 | |||
1881 | async setNewState (newState: VideoState, isNewVideo: boolean, transaction: Transaction) { | 1903 | async setNewState (newState: VideoState, isNewVideo: boolean, transaction: Transaction) { |
1882 | if (this.state === newState) throw new Error('Cannot use same state ' + newState) | 1904 | if (this.state === newState) throw new Error('Cannot use same state ' + newState) |
1883 | 1905 | ||
diff --git a/server/tests/api/object-storage/index.ts b/server/tests/api/object-storage/index.ts index f319d6ef5..1f4489fa3 100644 --- a/server/tests/api/object-storage/index.ts +++ b/server/tests/api/object-storage/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './live' | 1 | export * from './live' |
2 | export * from './video-imports' | 2 | export * from './video-imports' |
3 | export * from './video-static-file-privacy' | ||
3 | export * from './videos' | 4 | export * from './videos' |
diff --git a/server/tests/api/object-storage/live.ts b/server/tests/api/object-storage/live.ts index 77f3a8066..ad2b554b7 100644 --- a/server/tests/api/object-storage/live.ts +++ b/server/tests/api/object-storage/live.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { expectStartWith, testVideoResolutions } from '@server/tests/shared' | 4 | import { expectStartWith, testVideoResolutions } from '@server/tests/shared' |
5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 5 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
6 | import { HttpStatusCode, LiveVideoCreate, VideoPrivacy } from '@shared/models' | 6 | import { HttpStatusCode, LiveVideoCreate, VideoPrivacy } from '@shared/models' |
7 | import { | 7 | import { |
8 | createMultipleServers, | 8 | createMultipleServers, |
@@ -46,7 +46,7 @@ async function checkFilesExist (servers: PeerTubeServer[], videoUUID: string, nu | |||
46 | expect(files).to.have.lengthOf(numberOfFiles) | 46 | expect(files).to.have.lengthOf(numberOfFiles) |
47 | 47 | ||
48 | for (const file of files) { | 48 | for (const file of files) { |
49 | expectStartWith(file.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl()) | 49 | expectStartWith(file.fileUrl, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
50 | 50 | ||
51 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 51 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
52 | } | 52 | } |
@@ -75,16 +75,16 @@ async function checkFilesCleanup (server: PeerTubeServer, videoUUID: string, res | |||
75 | } | 75 | } |
76 | 76 | ||
77 | describe('Object storage for lives', function () { | 77 | describe('Object storage for lives', function () { |
78 | if (areObjectStorageTestsDisabled()) return | 78 | if (areMockObjectStorageTestsDisabled()) return |
79 | 79 | ||
80 | let servers: PeerTubeServer[] | 80 | let servers: PeerTubeServer[] |
81 | 81 | ||
82 | before(async function () { | 82 | before(async function () { |
83 | this.timeout(120000) | 83 | this.timeout(120000) |
84 | 84 | ||
85 | await ObjectStorageCommand.prepareDefaultBuckets() | 85 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
86 | 86 | ||
87 | servers = await createMultipleServers(2, ObjectStorageCommand.getDefaultConfig()) | 87 | servers = await createMultipleServers(2, ObjectStorageCommand.getDefaultMockConfig()) |
88 | 88 | ||
89 | await setAccessTokensToServers(servers) | 89 | await setAccessTokensToServers(servers) |
90 | await setDefaultVideoChannel(servers) | 90 | await setDefaultVideoChannel(servers) |
diff --git a/server/tests/api/object-storage/video-imports.ts b/server/tests/api/object-storage/video-imports.ts index 90988ea9a..11c866411 100644 --- a/server/tests/api/object-storage/video-imports.ts +++ b/server/tests/api/object-storage/video-imports.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { expectStartWith, FIXTURE_URLS } from '@server/tests/shared' | 4 | import { expectStartWith, FIXTURE_URLS } from '@server/tests/shared' |
5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 5 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
6 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' | 6 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' |
7 | import { | 7 | import { |
8 | createSingleServer, | 8 | createSingleServer, |
@@ -29,16 +29,16 @@ async function importVideo (server: PeerTubeServer) { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | describe('Object storage for video import', function () { | 31 | describe('Object storage for video import', function () { |
32 | if (areObjectStorageTestsDisabled()) return | 32 | if (areMockObjectStorageTestsDisabled()) return |
33 | 33 | ||
34 | let server: PeerTubeServer | 34 | let server: PeerTubeServer |
35 | 35 | ||
36 | before(async function () { | 36 | before(async function () { |
37 | this.timeout(120000) | 37 | this.timeout(120000) |
38 | 38 | ||
39 | await ObjectStorageCommand.prepareDefaultBuckets() | 39 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
40 | 40 | ||
41 | server = await createSingleServer(1, ObjectStorageCommand.getDefaultConfig()) | 41 | server = await createSingleServer(1, ObjectStorageCommand.getDefaultMockConfig()) |
42 | 42 | ||
43 | await setAccessTokensToServers([ server ]) | 43 | await setAccessTokensToServers([ server ]) |
44 | await setDefaultVideoChannel([ server ]) | 44 | await setDefaultVideoChannel([ server ]) |
@@ -64,7 +64,7 @@ describe('Object storage for video import', function () { | |||
64 | expect(video.streamingPlaylists).to.have.lengthOf(0) | 64 | expect(video.streamingPlaylists).to.have.lengthOf(0) |
65 | 65 | ||
66 | const fileUrl = video.files[0].fileUrl | 66 | const fileUrl = video.files[0].fileUrl |
67 | expectStartWith(fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 67 | expectStartWith(fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
68 | 68 | ||
69 | await makeRawRequest({ url: fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 69 | await makeRawRequest({ url: fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
70 | }) | 70 | }) |
@@ -89,13 +89,13 @@ describe('Object storage for video import', function () { | |||
89 | expect(video.streamingPlaylists[0].files).to.have.lengthOf(5) | 89 | expect(video.streamingPlaylists[0].files).to.have.lengthOf(5) |
90 | 90 | ||
91 | for (const file of video.files) { | 91 | for (const file of video.files) { |
92 | expectStartWith(file.fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 92 | expectStartWith(file.fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
93 | 93 | ||
94 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 94 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
95 | } | 95 | } |
96 | 96 | ||
97 | for (const file of video.streamingPlaylists[0].files) { | 97 | for (const file of video.streamingPlaylists[0].files) { |
98 | expectStartWith(file.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl()) | 98 | expectStartWith(file.fileUrl, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
99 | 99 | ||
100 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 100 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
101 | } | 101 | } |
diff --git a/server/tests/api/object-storage/video-static-file-privacy.ts b/server/tests/api/object-storage/video-static-file-privacy.ts new file mode 100644 index 000000000..981bbaa16 --- /dev/null +++ b/server/tests/api/object-storage/video-static-file-privacy.ts | |||
@@ -0,0 +1,336 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import { basename } from 'path' | ||
5 | import { expectStartWith } from '@server/tests/shared' | ||
6 | import { areScalewayObjectStorageTestsDisabled, getAllFiles, getHLS } from '@shared/core-utils' | ||
7 | import { HttpStatusCode, LiveVideo, VideoDetails, VideoPrivacy } from '@shared/models' | ||
8 | import { | ||
9 | cleanupTests, | ||
10 | createSingleServer, | ||
11 | findExternalSavedVideo, | ||
12 | makeRawRequest, | ||
13 | ObjectStorageCommand, | ||
14 | PeerTubeServer, | ||
15 | sendRTMPStream, | ||
16 | setAccessTokensToServers, | ||
17 | setDefaultVideoChannel, | ||
18 | stopFfmpeg, | ||
19 | waitJobs | ||
20 | } from '@shared/server-commands' | ||
21 | |||
22 | describe('Object storage for video static file privacy', function () { | ||
23 | // We need real world object storage to check ACL | ||
24 | if (areScalewayObjectStorageTestsDisabled()) return | ||
25 | |||
26 | let server: PeerTubeServer | ||
27 | let userToken: string | ||
28 | |||
29 | before(async function () { | ||
30 | this.timeout(120000) | ||
31 | |||
32 | server = await createSingleServer(1, ObjectStorageCommand.getDefaultScalewayConfig(1)) | ||
33 | await setAccessTokensToServers([ server ]) | ||
34 | await setDefaultVideoChannel([ server ]) | ||
35 | |||
36 | await server.config.enableMinimumTranscoding() | ||
37 | |||
38 | userToken = await server.users.generateUserAndToken('user1') | ||
39 | }) | ||
40 | |||
41 | describe('VOD', function () { | ||
42 | let privateVideoUUID: string | ||
43 | let publicVideoUUID: string | ||
44 | let userPrivateVideoUUID: string | ||
45 | |||
46 | async function checkPrivateFiles (uuid: string) { | ||
47 | const video = await server.videos.getWithToken({ id: uuid }) | ||
48 | |||
49 | for (const file of video.files) { | ||
50 | expectStartWith(file.fileUrl, server.url + '/object-storage-proxy/webseed/private/') | ||
51 | |||
52 | await makeRawRequest({ url: file.fileUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
53 | } | ||
54 | |||
55 | for (const file of getAllFiles(video)) { | ||
56 | const internalFileUrl = await server.sql.getInternalFileUrl(file.id) | ||
57 | expectStartWith(internalFileUrl, ObjectStorageCommand.getScalewayBaseUrl()) | ||
58 | await makeRawRequest({ url: internalFileUrl, token: server.accessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
59 | } | ||
60 | |||
61 | const hls = getHLS(video) | ||
62 | |||
63 | if (hls) { | ||
64 | for (const url of [ hls.playlistUrl, hls.segmentsSha256Url ]) { | ||
65 | expectStartWith(url, server.url + '/object-storage-proxy/streaming-playlists/hls/private/') | ||
66 | } | ||
67 | |||
68 | await makeRawRequest({ url: hls.playlistUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
69 | await makeRawRequest({ url: hls.segmentsSha256Url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
70 | |||
71 | for (const file of hls.files) { | ||
72 | expectStartWith(file.fileUrl, server.url + '/object-storage-proxy/streaming-playlists/hls/private/') | ||
73 | |||
74 | await makeRawRequest({ url: file.fileUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | async function checkPublicFiles (uuid: string) { | ||
80 | const video = await server.videos.getWithToken({ id: uuid }) | ||
81 | |||
82 | for (const file of getAllFiles(video)) { | ||
83 | expectStartWith(file.fileUrl, ObjectStorageCommand.getScalewayBaseUrl()) | ||
84 | |||
85 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | ||
86 | } | ||
87 | |||
88 | const hls = getHLS(video) | ||
89 | |||
90 | if (hls) { | ||
91 | expectStartWith(hls.playlistUrl, ObjectStorageCommand.getScalewayBaseUrl()) | ||
92 | expectStartWith(hls.segmentsSha256Url, ObjectStorageCommand.getScalewayBaseUrl()) | ||
93 | |||
94 | await makeRawRequest({ url: hls.playlistUrl, expectedStatus: HttpStatusCode.OK_200 }) | ||
95 | await makeRawRequest({ url: hls.segmentsSha256Url, expectedStatus: HttpStatusCode.OK_200 }) | ||
96 | } | ||
97 | } | ||
98 | |||
99 | async function getSampleFileUrls (videoId: string) { | ||
100 | const video = await server.videos.getWithToken({ id: videoId }) | ||
101 | |||
102 | return { | ||
103 | webTorrentFile: video.files[0].fileUrl, | ||
104 | hlsFile: getHLS(video).files[0].fileUrl | ||
105 | } | ||
106 | } | ||
107 | |||
108 | it('Should upload a private video and have appropriate object storage ACL', async function () { | ||
109 | this.timeout(60000) | ||
110 | |||
111 | { | ||
112 | const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.PRIVATE }) | ||
113 | privateVideoUUID = uuid | ||
114 | } | ||
115 | |||
116 | { | ||
117 | const { uuid } = await server.videos.quickUpload({ name: 'user video', token: userToken, privacy: VideoPrivacy.PRIVATE }) | ||
118 | userPrivateVideoUUID = uuid | ||
119 | } | ||
120 | |||
121 | await waitJobs([ server ]) | ||
122 | |||
123 | await checkPrivateFiles(privateVideoUUID) | ||
124 | }) | ||
125 | |||
126 | it('Should upload a public video and have appropriate object storage ACL', async function () { | ||
127 | this.timeout(60000) | ||
128 | |||
129 | const { uuid } = await server.videos.quickUpload({ name: 'video', privacy: VideoPrivacy.UNLISTED }) | ||
130 | await waitJobs([ server ]) | ||
131 | |||
132 | publicVideoUUID = uuid | ||
133 | |||
134 | await checkPublicFiles(publicVideoUUID) | ||
135 | }) | ||
136 | |||
137 | it('Should not get files without appropriate OAuth token', async function () { | ||
138 | this.timeout(60000) | ||
139 | |||
140 | const { webTorrentFile, hlsFile } = await getSampleFileUrls(privateVideoUUID) | ||
141 | |||
142 | await makeRawRequest({ url: webTorrentFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
143 | await makeRawRequest({ url: webTorrentFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
144 | |||
145 | await makeRawRequest({ url: hlsFile, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
146 | await makeRawRequest({ url: hlsFile, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
147 | }) | ||
148 | |||
149 | it('Should not get HLS file of another video', async function () { | ||
150 | this.timeout(60000) | ||
151 | |||
152 | const privateVideo = await server.videos.getWithToken({ id: privateVideoUUID }) | ||
153 | const hlsFilename = basename(getHLS(privateVideo).files[0].fileUrl) | ||
154 | |||
155 | const badUrl = server.url + '/object-storage-proxy/streaming-playlists/hls/private/' + userPrivateVideoUUID + '/' + hlsFilename | ||
156 | const goodUrl = server.url + '/object-storage-proxy/streaming-playlists/hls/private/' + privateVideoUUID + '/' + hlsFilename | ||
157 | |||
158 | await makeRawRequest({ url: badUrl, token: server.accessToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
159 | await makeRawRequest({ url: goodUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
160 | }) | ||
161 | |||
162 | it('Should correctly check OAuth or video file token', async function () { | ||
163 | this.timeout(60000) | ||
164 | |||
165 | const badVideoFileToken = await server.videoToken.getVideoFileToken({ token: userToken, videoId: userPrivateVideoUUID }) | ||
166 | const goodVideoFileToken = await server.videoToken.getVideoFileToken({ videoId: privateVideoUUID }) | ||
167 | |||
168 | const { webTorrentFile, hlsFile } = await getSampleFileUrls(privateVideoUUID) | ||
169 | |||
170 | for (const url of [ webTorrentFile, hlsFile ]) { | ||
171 | await makeRawRequest({ url, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
172 | await makeRawRequest({ url, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
173 | await makeRawRequest({ url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
174 | |||
175 | await makeRawRequest({ url, query: { videoFileToken: badVideoFileToken }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
176 | await makeRawRequest({ url, query: { videoFileToken: goodVideoFileToken }, expectedStatus: HttpStatusCode.OK_200 }) | ||
177 | } | ||
178 | }) | ||
179 | |||
180 | it('Should update public video to private', async function () { | ||
181 | this.timeout(60000) | ||
182 | |||
183 | await server.videos.update({ id: publicVideoUUID, attributes: { privacy: VideoPrivacy.INTERNAL } }) | ||
184 | |||
185 | await checkPrivateFiles(publicVideoUUID) | ||
186 | }) | ||
187 | |||
188 | it('Should update private video to public', async function () { | ||
189 | this.timeout(60000) | ||
190 | |||
191 | await server.videos.update({ id: publicVideoUUID, attributes: { privacy: VideoPrivacy.PUBLIC } }) | ||
192 | |||
193 | await checkPublicFiles(publicVideoUUID) | ||
194 | }) | ||
195 | |||
196 | after(async function () { | ||
197 | this.timeout(30000) | ||
198 | |||
199 | if (privateVideoUUID) await server.videos.remove({ id: privateVideoUUID }) | ||
200 | if (publicVideoUUID) await server.videos.remove({ id: publicVideoUUID }) | ||
201 | if (userPrivateVideoUUID) await server.videos.remove({ id: userPrivateVideoUUID }) | ||
202 | |||
203 | await waitJobs([ server ]) | ||
204 | }) | ||
205 | }) | ||
206 | |||
207 | describe('Live', function () { | ||
208 | let normalLiveId: string | ||
209 | let normalLive: LiveVideo | ||
210 | |||
211 | let permanentLiveId: string | ||
212 | let permanentLive: LiveVideo | ||
213 | |||
214 | let unrelatedFileToken: string | ||
215 | |||
216 | async function checkLiveFiles (live: LiveVideo, liveId: string) { | ||
217 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey }) | ||
218 | await server.live.waitUntilPublished({ videoId: liveId }) | ||
219 | |||
220 | const video = await server.videos.getWithToken({ id: liveId }) | ||
221 | const fileToken = await server.videoToken.getVideoFileToken({ videoId: video.uuid }) | ||
222 | |||
223 | const hls = video.streamingPlaylists[0] | ||
224 | |||
225 | for (const url of [ hls.playlistUrl, hls.segmentsSha256Url ]) { | ||
226 | expectStartWith(url, server.url + '/object-storage-proxy/streaming-playlists/hls/private/') | ||
227 | |||
228 | await makeRawRequest({ url: hls.playlistUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
229 | await makeRawRequest({ url: hls.segmentsSha256Url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
230 | |||
231 | await makeRawRequest({ url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
232 | await makeRawRequest({ url, query: { videoFileToken: fileToken }, expectedStatus: HttpStatusCode.OK_200 }) | ||
233 | |||
234 | await makeRawRequest({ url, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
235 | await makeRawRequest({ url, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
236 | await makeRawRequest({ url, query: { videoFileToken: unrelatedFileToken }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
237 | } | ||
238 | |||
239 | await stopFfmpeg(ffmpegCommand) | ||
240 | } | ||
241 | |||
242 | async function checkReplay (replay: VideoDetails) { | ||
243 | const fileToken = await server.videoToken.getVideoFileToken({ videoId: replay.uuid }) | ||
244 | |||
245 | const hls = replay.streamingPlaylists[0] | ||
246 | expect(hls.files).to.not.have.lengthOf(0) | ||
247 | |||
248 | for (const file of hls.files) { | ||
249 | await makeRawRequest({ url: file.fileUrl, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
250 | await makeRawRequest({ url: file.fileUrl, query: { videoFileToken: fileToken }, expectedStatus: HttpStatusCode.OK_200 }) | ||
251 | |||
252 | await makeRawRequest({ url: file.fileUrl, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
253 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
254 | await makeRawRequest({ | ||
255 | url: file.fileUrl, | ||
256 | query: { videoFileToken: unrelatedFileToken }, | ||
257 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
258 | }) | ||
259 | } | ||
260 | |||
261 | for (const url of [ hls.playlistUrl, hls.segmentsSha256Url ]) { | ||
262 | expectStartWith(url, server.url + '/object-storage-proxy/streaming-playlists/hls/private/') | ||
263 | |||
264 | await makeRawRequest({ url, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
265 | await makeRawRequest({ url, query: { videoFileToken: fileToken }, expectedStatus: HttpStatusCode.OK_200 }) | ||
266 | |||
267 | await makeRawRequest({ url, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
268 | await makeRawRequest({ url, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
269 | await makeRawRequest({ url, query: { videoFileToken: unrelatedFileToken }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
270 | } | ||
271 | } | ||
272 | |||
273 | before(async function () { | ||
274 | await server.config.enableMinimumTranscoding() | ||
275 | |||
276 | const { uuid } = await server.videos.quickUpload({ name: 'another video' }) | ||
277 | unrelatedFileToken = await server.videoToken.getVideoFileToken({ videoId: uuid }) | ||
278 | |||
279 | await server.config.enableLive({ | ||
280 | allowReplay: true, | ||
281 | transcoding: true, | ||
282 | resolutions: 'min' | ||
283 | }) | ||
284 | |||
285 | { | ||
286 | const { video, live } = await server.live.quickCreate({ saveReplay: true, permanentLive: false, privacy: VideoPrivacy.PRIVATE }) | ||
287 | normalLiveId = video.uuid | ||
288 | normalLive = live | ||
289 | } | ||
290 | |||
291 | { | ||
292 | const { video, live } = await server.live.quickCreate({ saveReplay: true, permanentLive: true, privacy: VideoPrivacy.PRIVATE }) | ||
293 | permanentLiveId = video.uuid | ||
294 | permanentLive = live | ||
295 | } | ||
296 | }) | ||
297 | |||
298 | it('Should create a private normal live and have a private static path', async function () { | ||
299 | this.timeout(240000) | ||
300 | |||
301 | await checkLiveFiles(normalLive, normalLiveId) | ||
302 | }) | ||
303 | |||
304 | it('Should create a private permanent live and have a private static path', async function () { | ||
305 | this.timeout(240000) | ||
306 | |||
307 | await checkLiveFiles(permanentLive, permanentLiveId) | ||
308 | }) | ||
309 | |||
310 | it('Should have created a replay of the normal live with a private static path', async function () { | ||
311 | this.timeout(240000) | ||
312 | |||
313 | await server.live.waitUntilReplacedByReplay({ videoId: normalLiveId }) | ||
314 | |||
315 | const replay = await server.videos.getWithToken({ id: normalLiveId }) | ||
316 | await checkReplay(replay) | ||
317 | }) | ||
318 | |||
319 | it('Should have created a replay of the permanent live with a private static path', async function () { | ||
320 | this.timeout(240000) | ||
321 | |||
322 | await server.live.waitUntilWaiting({ videoId: permanentLiveId }) | ||
323 | await waitJobs([ server ]) | ||
324 | |||
325 | const live = await server.videos.getWithToken({ id: permanentLiveId }) | ||
326 | const replayFromList = await findExternalSavedVideo(server, live) | ||
327 | const replay = await server.videos.getWithToken({ id: replayFromList.id }) | ||
328 | |||
329 | await checkReplay(replay) | ||
330 | }) | ||
331 | }) | ||
332 | |||
333 | after(async function () { | ||
334 | await cleanupTests([ server ]) | ||
335 | }) | ||
336 | }) | ||
diff --git a/server/tests/api/object-storage/videos.ts b/server/tests/api/object-storage/videos.ts index 63f5179c7..af3db9334 100644 --- a/server/tests/api/object-storage/videos.ts +++ b/server/tests/api/object-storage/videos.ts | |||
@@ -11,7 +11,7 @@ import { | |||
11 | generateHighBitrateVideo, | 11 | generateHighBitrateVideo, |
12 | MockObjectStorage | 12 | MockObjectStorage |
13 | } from '@server/tests/shared' | 13 | } from '@server/tests/shared' |
14 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 14 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
15 | import { HttpStatusCode, VideoDetails } from '@shared/models' | 15 | import { HttpStatusCode, VideoDetails } from '@shared/models' |
16 | import { | 16 | import { |
17 | cleanupTests, | 17 | cleanupTests, |
@@ -52,7 +52,7 @@ async function checkFiles (options: { | |||
52 | for (const file of video.files) { | 52 | for (const file of video.files) { |
53 | const baseUrl = baseMockUrl | 53 | const baseUrl = baseMockUrl |
54 | ? `${baseMockUrl}/${webtorrentBucket}/` | 54 | ? `${baseMockUrl}/${webtorrentBucket}/` |
55 | : `http://${webtorrentBucket}.${ObjectStorageCommand.getEndpointHost()}/` | 55 | : `http://${webtorrentBucket}.${ObjectStorageCommand.getMockEndpointHost()}/` |
56 | 56 | ||
57 | const prefix = webtorrentPrefix || '' | 57 | const prefix = webtorrentPrefix || '' |
58 | const start = baseUrl + prefix | 58 | const start = baseUrl + prefix |
@@ -73,7 +73,7 @@ async function checkFiles (options: { | |||
73 | 73 | ||
74 | const baseUrl = baseMockUrl | 74 | const baseUrl = baseMockUrl |
75 | ? `${baseMockUrl}/${playlistBucket}/` | 75 | ? `${baseMockUrl}/${playlistBucket}/` |
76 | : `http://${playlistBucket}.${ObjectStorageCommand.getEndpointHost()}/` | 76 | : `http://${playlistBucket}.${ObjectStorageCommand.getMockEndpointHost()}/` |
77 | 77 | ||
78 | const prefix = playlistPrefix || '' | 78 | const prefix = playlistPrefix || '' |
79 | const start = baseUrl + prefix | 79 | const start = baseUrl + prefix |
@@ -141,16 +141,16 @@ function runTestSuite (options: { | |||
141 | const port = await mockObjectStorage.initialize() | 141 | const port = await mockObjectStorage.initialize() |
142 | baseMockUrl = options.useMockBaseUrl ? `http://localhost:${port}` : undefined | 142 | baseMockUrl = options.useMockBaseUrl ? `http://localhost:${port}` : undefined |
143 | 143 | ||
144 | await ObjectStorageCommand.createBucket(options.playlistBucket) | 144 | await ObjectStorageCommand.createMockBucket(options.playlistBucket) |
145 | await ObjectStorageCommand.createBucket(options.webtorrentBucket) | 145 | await ObjectStorageCommand.createMockBucket(options.webtorrentBucket) |
146 | 146 | ||
147 | const config = { | 147 | const config = { |
148 | object_storage: { | 148 | object_storage: { |
149 | enabled: true, | 149 | enabled: true, |
150 | endpoint: 'http://' + ObjectStorageCommand.getEndpointHost(), | 150 | endpoint: 'http://' + ObjectStorageCommand.getMockEndpointHost(), |
151 | region: ObjectStorageCommand.getRegion(), | 151 | region: ObjectStorageCommand.getMockRegion(), |
152 | 152 | ||
153 | credentials: ObjectStorageCommand.getCredentialsConfig(), | 153 | credentials: ObjectStorageCommand.getMockCredentialsConfig(), |
154 | 154 | ||
155 | max_upload_part: options.maxUploadPart || '5MB', | 155 | max_upload_part: options.maxUploadPart || '5MB', |
156 | 156 | ||
@@ -261,7 +261,7 @@ function runTestSuite (options: { | |||
261 | } | 261 | } |
262 | 262 | ||
263 | describe('Object storage for videos', function () { | 263 | describe('Object storage for videos', function () { |
264 | if (areObjectStorageTestsDisabled()) return | 264 | if (areMockObjectStorageTestsDisabled()) return |
265 | 265 | ||
266 | describe('Test config', function () { | 266 | describe('Test config', function () { |
267 | let server: PeerTubeServer | 267 | let server: PeerTubeServer |
@@ -269,17 +269,17 @@ describe('Object storage for videos', function () { | |||
269 | const baseConfig = { | 269 | const baseConfig = { |
270 | object_storage: { | 270 | object_storage: { |
271 | enabled: true, | 271 | enabled: true, |
272 | endpoint: 'http://' + ObjectStorageCommand.getEndpointHost(), | 272 | endpoint: 'http://' + ObjectStorageCommand.getMockEndpointHost(), |
273 | region: ObjectStorageCommand.getRegion(), | 273 | region: ObjectStorageCommand.getMockRegion(), |
274 | 274 | ||
275 | credentials: ObjectStorageCommand.getCredentialsConfig(), | 275 | credentials: ObjectStorageCommand.getMockCredentialsConfig(), |
276 | 276 | ||
277 | streaming_playlists: { | 277 | streaming_playlists: { |
278 | bucket_name: ObjectStorageCommand.DEFAULT_PLAYLIST_BUCKET | 278 | bucket_name: ObjectStorageCommand.DEFAULT_PLAYLIST_MOCK_BUCKET |
279 | }, | 279 | }, |
280 | 280 | ||
281 | videos: { | 281 | videos: { |
282 | bucket_name: ObjectStorageCommand.DEFAULT_WEBTORRENT_BUCKET | 282 | bucket_name: ObjectStorageCommand.DEFAULT_WEBTORRENT_MOCK_BUCKET |
283 | } | 283 | } |
284 | } | 284 | } |
285 | } | 285 | } |
@@ -310,7 +310,7 @@ describe('Object storage for videos', function () { | |||
310 | it('Should fail with bad credentials', async function () { | 310 | it('Should fail with bad credentials', async function () { |
311 | this.timeout(60000) | 311 | this.timeout(60000) |
312 | 312 | ||
313 | await ObjectStorageCommand.prepareDefaultBuckets() | 313 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
314 | 314 | ||
315 | const config = merge({}, baseConfig, { | 315 | const config = merge({}, baseConfig, { |
316 | object_storage: { | 316 | object_storage: { |
@@ -334,7 +334,7 @@ describe('Object storage for videos', function () { | |||
334 | it('Should succeed with credentials from env', async function () { | 334 | it('Should succeed with credentials from env', async function () { |
335 | this.timeout(60000) | 335 | this.timeout(60000) |
336 | 336 | ||
337 | await ObjectStorageCommand.prepareDefaultBuckets() | 337 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
338 | 338 | ||
339 | const config = merge({}, baseConfig, { | 339 | const config = merge({}, baseConfig, { |
340 | object_storage: { | 340 | object_storage: { |
@@ -345,7 +345,7 @@ describe('Object storage for videos', function () { | |||
345 | } | 345 | } |
346 | }) | 346 | }) |
347 | 347 | ||
348 | const goodCredentials = ObjectStorageCommand.getCredentialsConfig() | 348 | const goodCredentials = ObjectStorageCommand.getMockCredentialsConfig() |
349 | 349 | ||
350 | server = await createSingleServer(1, config, { | 350 | server = await createSingleServer(1, config, { |
351 | env: { | 351 | env: { |
@@ -361,7 +361,7 @@ describe('Object storage for videos', function () { | |||
361 | await waitJobs([ server ], true) | 361 | await waitJobs([ server ], true) |
362 | const video = await server.videos.get({ id: uuid }) | 362 | const video = await server.videos.get({ id: uuid }) |
363 | 363 | ||
364 | expectStartWith(video.files[0].fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 364 | expectStartWith(video.files[0].fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
365 | }) | 365 | }) |
366 | 366 | ||
367 | after(async function () { | 367 | after(async function () { |
diff --git a/server/tests/api/server/proxy.ts b/server/tests/api/server/proxy.ts index a4151ebdd..3700b0746 100644 --- a/server/tests/api/server/proxy.ts +++ b/server/tests/api/server/proxy.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { expectNotStartWith, expectStartWith, FIXTURE_URLS, MockProxy } from '@server/tests/shared' | 4 | import { expectNotStartWith, expectStartWith, FIXTURE_URLS, MockProxy } from '@server/tests/shared' |
5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 5 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
6 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' | 6 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' |
7 | import { | 7 | import { |
8 | cleanupTests, | 8 | cleanupTests, |
@@ -120,40 +120,40 @@ describe('Test proxy', function () { | |||
120 | }) | 120 | }) |
121 | 121 | ||
122 | describe('Object storage', function () { | 122 | describe('Object storage', function () { |
123 | if (areObjectStorageTestsDisabled()) return | 123 | if (areMockObjectStorageTestsDisabled()) return |
124 | 124 | ||
125 | before(async function () { | 125 | before(async function () { |
126 | this.timeout(30000) | 126 | this.timeout(30000) |
127 | 127 | ||
128 | await ObjectStorageCommand.prepareDefaultBuckets() | 128 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
129 | }) | 129 | }) |
130 | 130 | ||
131 | it('Should succeed to upload to object storage with the appropriate proxy config', async function () { | 131 | it('Should succeed to upload to object storage with the appropriate proxy config', async function () { |
132 | this.timeout(120000) | 132 | this.timeout(120000) |
133 | 133 | ||
134 | await servers[0].kill() | 134 | await servers[0].kill() |
135 | await servers[0].run(ObjectStorageCommand.getDefaultConfig(), { env: goodEnv }) | 135 | await servers[0].run(ObjectStorageCommand.getDefaultMockConfig(), { env: goodEnv }) |
136 | 136 | ||
137 | const { uuid } = await servers[0].videos.quickUpload({ name: 'video' }) | 137 | const { uuid } = await servers[0].videos.quickUpload({ name: 'video' }) |
138 | await waitJobs(servers) | 138 | await waitJobs(servers) |
139 | 139 | ||
140 | const video = await servers[0].videos.get({ id: uuid }) | 140 | const video = await servers[0].videos.get({ id: uuid }) |
141 | 141 | ||
142 | expectStartWith(video.files[0].fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 142 | expectStartWith(video.files[0].fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
143 | }) | 143 | }) |
144 | 144 | ||
145 | it('Should fail to upload to object storage with a wrong proxy config', async function () { | 145 | it('Should fail to upload to object storage with a wrong proxy config', async function () { |
146 | this.timeout(120000) | 146 | this.timeout(120000) |
147 | 147 | ||
148 | await servers[0].kill() | 148 | await servers[0].kill() |
149 | await servers[0].run(ObjectStorageCommand.getDefaultConfig(), { env: badEnv }) | 149 | await servers[0].run(ObjectStorageCommand.getDefaultMockConfig(), { env: badEnv }) |
150 | 150 | ||
151 | const { uuid } = await servers[0].videos.quickUpload({ name: 'video' }) | 151 | const { uuid } = await servers[0].videos.quickUpload({ name: 'video' }) |
152 | await waitJobs(servers) | 152 | await waitJobs(servers) |
153 | 153 | ||
154 | const video = await servers[0].videos.get({ id: uuid }) | 154 | const video = await servers[0].videos.get({ id: uuid }) |
155 | 155 | ||
156 | expectNotStartWith(video.files[0].fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 156 | expectNotStartWith(video.files[0].fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
157 | }) | 157 | }) |
158 | }) | 158 | }) |
159 | 159 | ||
diff --git a/server/tests/api/transcoding/create-transcoding.ts b/server/tests/api/transcoding/create-transcoding.ts index 372f5332a..85389a949 100644 --- a/server/tests/api/transcoding/create-transcoding.ts +++ b/server/tests/api/transcoding/create-transcoding.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { checkResolutionsInMasterPlaylist, expectStartWith } from '@server/tests/shared' | 4 | import { checkResolutionsInMasterPlaylist, expectStartWith } from '@server/tests/shared' |
5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 5 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
6 | import { HttpStatusCode, VideoDetails } from '@shared/models' | 6 | import { HttpStatusCode, VideoDetails } from '@shared/models' |
7 | import { | 7 | import { |
8 | cleanupTests, | 8 | cleanupTests, |
@@ -19,7 +19,7 @@ import { | |||
19 | 19 | ||
20 | async function checkFilesInObjectStorage (video: VideoDetails) { | 20 | async function checkFilesInObjectStorage (video: VideoDetails) { |
21 | for (const file of video.files) { | 21 | for (const file of video.files) { |
22 | expectStartWith(file.fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 22 | expectStartWith(file.fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
23 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 23 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
24 | } | 24 | } |
25 | 25 | ||
@@ -27,14 +27,14 @@ async function checkFilesInObjectStorage (video: VideoDetails) { | |||
27 | 27 | ||
28 | const hlsPlaylist = video.streamingPlaylists[0] | 28 | const hlsPlaylist = video.streamingPlaylists[0] |
29 | for (const file of hlsPlaylist.files) { | 29 | for (const file of hlsPlaylist.files) { |
30 | expectStartWith(file.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl()) | 30 | expectStartWith(file.fileUrl, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
31 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 31 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
32 | } | 32 | } |
33 | 33 | ||
34 | expectStartWith(hlsPlaylist.playlistUrl, ObjectStorageCommand.getPlaylistBaseUrl()) | 34 | expectStartWith(hlsPlaylist.playlistUrl, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
35 | await makeRawRequest({ url: hlsPlaylist.playlistUrl, expectedStatus: HttpStatusCode.OK_200 }) | 35 | await makeRawRequest({ url: hlsPlaylist.playlistUrl, expectedStatus: HttpStatusCode.OK_200 }) |
36 | 36 | ||
37 | expectStartWith(hlsPlaylist.segmentsSha256Url, ObjectStorageCommand.getPlaylistBaseUrl()) | 37 | expectStartWith(hlsPlaylist.segmentsSha256Url, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
38 | await makeRawRequest({ url: hlsPlaylist.segmentsSha256Url, expectedStatus: HttpStatusCode.OK_200 }) | 38 | await makeRawRequest({ url: hlsPlaylist.segmentsSha256Url, expectedStatus: HttpStatusCode.OK_200 }) |
39 | } | 39 | } |
40 | 40 | ||
@@ -49,7 +49,7 @@ function runTests (objectStorage: boolean) { | |||
49 | this.timeout(120000) | 49 | this.timeout(120000) |
50 | 50 | ||
51 | const config = objectStorage | 51 | const config = objectStorage |
52 | ? ObjectStorageCommand.getDefaultConfig() | 52 | ? ObjectStorageCommand.getDefaultMockConfig() |
53 | : {} | 53 | : {} |
54 | 54 | ||
55 | // Run server 2 to have transcoding enabled | 55 | // Run server 2 to have transcoding enabled |
@@ -60,7 +60,7 @@ function runTests (objectStorage: boolean) { | |||
60 | 60 | ||
61 | await doubleFollow(servers[0], servers[1]) | 61 | await doubleFollow(servers[0], servers[1]) |
62 | 62 | ||
63 | if (objectStorage) await ObjectStorageCommand.prepareDefaultBuckets() | 63 | if (objectStorage) await ObjectStorageCommand.prepareDefaultMockBuckets() |
64 | 64 | ||
65 | const { shortUUID } = await servers[0].videos.quickUpload({ name: 'video' }) | 65 | const { shortUUID } = await servers[0].videos.quickUpload({ name: 'video' }) |
66 | videoUUID = shortUUID | 66 | videoUUID = shortUUID |
@@ -256,7 +256,7 @@ describe('Test create transcoding jobs from API', function () { | |||
256 | }) | 256 | }) |
257 | 257 | ||
258 | describe('On object storage', function () { | 258 | describe('On object storage', function () { |
259 | if (areObjectStorageTestsDisabled()) return | 259 | if (areMockObjectStorageTestsDisabled()) return |
260 | 260 | ||
261 | runTests(true) | 261 | runTests(true) |
262 | }) | 262 | }) |
diff --git a/server/tests/api/transcoding/hls.ts b/server/tests/api/transcoding/hls.ts index 7b5492cd4..84a53c0bd 100644 --- a/server/tests/api/transcoding/hls.ts +++ b/server/tests/api/transcoding/hls.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { checkDirectoryIsEmpty, checkTmpIsEmpty, completeCheckHlsPlaylist } from '@server/tests/shared' | 4 | import { checkDirectoryIsEmpty, checkTmpIsEmpty, completeCheckHlsPlaylist } from '@server/tests/shared' |
5 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 5 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
6 | import { HttpStatusCode } from '@shared/models' | 6 | import { HttpStatusCode } from '@shared/models' |
7 | import { | 7 | import { |
8 | cleanupTests, | 8 | cleanupTests, |
@@ -150,19 +150,19 @@ describe('Test HLS videos', function () { | |||
150 | }) | 150 | }) |
151 | 151 | ||
152 | describe('With object storage enabled', function () { | 152 | describe('With object storage enabled', function () { |
153 | if (areObjectStorageTestsDisabled()) return | 153 | if (areMockObjectStorageTestsDisabled()) return |
154 | 154 | ||
155 | before(async function () { | 155 | before(async function () { |
156 | this.timeout(120000) | 156 | this.timeout(120000) |
157 | 157 | ||
158 | const configOverride = ObjectStorageCommand.getDefaultConfig() | 158 | const configOverride = ObjectStorageCommand.getDefaultMockConfig() |
159 | await ObjectStorageCommand.prepareDefaultBuckets() | 159 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
160 | 160 | ||
161 | await servers[0].kill() | 161 | await servers[0].kill() |
162 | await servers[0].run(configOverride) | 162 | await servers[0].run(configOverride) |
163 | }) | 163 | }) |
164 | 164 | ||
165 | runTestSuite(true, ObjectStorageCommand.getPlaylistBaseUrl()) | 165 | runTestSuite(true, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
166 | }) | 166 | }) |
167 | 167 | ||
168 | after(async function () { | 168 | after(async function () { |
diff --git a/server/tests/api/transcoding/update-while-transcoding.ts b/server/tests/api/transcoding/update-while-transcoding.ts index 5ca923392..8e32ea069 100644 --- a/server/tests/api/transcoding/update-while-transcoding.ts +++ b/server/tests/api/transcoding/update-while-transcoding.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { completeCheckHlsPlaylist } from '@server/tests/shared' | 3 | import { completeCheckHlsPlaylist } from '@server/tests/shared' |
4 | import { areObjectStorageTestsDisabled, wait } from '@shared/core-utils' | 4 | import { areMockObjectStorageTestsDisabled, wait } from '@shared/core-utils' |
5 | import { VideoPrivacy } from '@shared/models' | 5 | import { VideoPrivacy } from '@shared/models' |
6 | import { | 6 | import { |
7 | cleanupTests, | 7 | cleanupTests, |
@@ -130,19 +130,19 @@ describe('Test update video privacy while transcoding', function () { | |||
130 | }) | 130 | }) |
131 | 131 | ||
132 | describe('With object storage enabled', function () { | 132 | describe('With object storage enabled', function () { |
133 | if (areObjectStorageTestsDisabled()) return | 133 | if (areMockObjectStorageTestsDisabled()) return |
134 | 134 | ||
135 | before(async function () { | 135 | before(async function () { |
136 | this.timeout(120000) | 136 | this.timeout(120000) |
137 | 137 | ||
138 | const configOverride = ObjectStorageCommand.getDefaultConfig() | 138 | const configOverride = ObjectStorageCommand.getDefaultMockConfig() |
139 | await ObjectStorageCommand.prepareDefaultBuckets() | 139 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
140 | 140 | ||
141 | await servers[0].kill() | 141 | await servers[0].kill() |
142 | await servers[0].run(configOverride) | 142 | await servers[0].run(configOverride) |
143 | }) | 143 | }) |
144 | 144 | ||
145 | runTestSuite(true, ObjectStorageCommand.getPlaylistBaseUrl()) | 145 | runTestSuite(true, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
146 | }) | 146 | }) |
147 | 147 | ||
148 | after(async function () { | 148 | after(async function () { |
diff --git a/server/tests/api/transcoding/video-studio.ts b/server/tests/api/transcoding/video-studio.ts index 9613111b5..ab08e8fb6 100644 --- a/server/tests/api/transcoding/video-studio.ts +++ b/server/tests/api/transcoding/video-studio.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { expect } from 'chai' | 1 | import { expect } from 'chai' |
2 | import { expectStartWith } from '@server/tests/shared' | 2 | import { expectStartWith } from '@server/tests/shared' |
3 | import { areObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils' | 3 | import { areMockObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils' |
4 | import { VideoStudioTask } from '@shared/models' | 4 | import { VideoStudioTask } from '@shared/models' |
5 | import { | 5 | import { |
6 | cleanupTests, | 6 | cleanupTests, |
@@ -315,13 +315,13 @@ describe('Test video studio', function () { | |||
315 | }) | 315 | }) |
316 | 316 | ||
317 | describe('Object storage video edition', function () { | 317 | describe('Object storage video edition', function () { |
318 | if (areObjectStorageTestsDisabled()) return | 318 | if (areMockObjectStorageTestsDisabled()) return |
319 | 319 | ||
320 | before(async function () { | 320 | before(async function () { |
321 | await ObjectStorageCommand.prepareDefaultBuckets() | 321 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
322 | 322 | ||
323 | await servers[0].kill() | 323 | await servers[0].kill() |
324 | await servers[0].run(ObjectStorageCommand.getDefaultConfig()) | 324 | await servers[0].run(ObjectStorageCommand.getDefaultMockConfig()) |
325 | 325 | ||
326 | await servers[0].config.enableMinimumTranscoding() | 326 | await servers[0].config.enableMinimumTranscoding() |
327 | }) | 327 | }) |
@@ -344,11 +344,11 @@ describe('Test video studio', function () { | |||
344 | } | 344 | } |
345 | 345 | ||
346 | for (const webtorrentFile of video.files) { | 346 | for (const webtorrentFile of video.files) { |
347 | expectStartWith(webtorrentFile.fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 347 | expectStartWith(webtorrentFile.fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
348 | } | 348 | } |
349 | 349 | ||
350 | for (const hlsFile of video.streamingPlaylists[0].files) { | 350 | for (const hlsFile of video.streamingPlaylists[0].files) { |
351 | expectStartWith(hlsFile.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl()) | 351 | expectStartWith(hlsFile.fileUrl, ObjectStorageCommand.getMockPlaylistBaseUrl()) |
352 | } | 352 | } |
353 | 353 | ||
354 | await checkDuration(server, 9) | 354 | await checkDuration(server, 9) |
diff --git a/server/tests/api/videos/video-static-file-privacy.ts b/server/tests/api/videos/video-static-file-privacy.ts index e38fdec6e..bdbe85127 100644 --- a/server/tests/api/videos/video-static-file-privacy.ts +++ b/server/tests/api/videos/video-static-file-privacy.ts | |||
@@ -37,7 +37,7 @@ describe('Test video static file privacy', function () { | |||
37 | 37 | ||
38 | function runSuite () { | 38 | function runSuite () { |
39 | 39 | ||
40 | async function checkPrivateWebTorrentFiles (uuid: string) { | 40 | async function checkPrivateFiles (uuid: string) { |
41 | const video = await server.videos.getWithToken({ id: uuid }) | 41 | const video = await server.videos.getWithToken({ id: uuid }) |
42 | 42 | ||
43 | for (const file of video.files) { | 43 | for (const file of video.files) { |
@@ -63,7 +63,7 @@ describe('Test video static file privacy', function () { | |||
63 | } | 63 | } |
64 | } | 64 | } |
65 | 65 | ||
66 | async function checkPublicWebTorrentFiles (uuid: string) { | 66 | async function checkPublicFiles (uuid: string) { |
67 | const video = await server.videos.get({ id: uuid }) | 67 | const video = await server.videos.get({ id: uuid }) |
68 | 68 | ||
69 | for (const file of getAllFiles(video)) { | 69 | for (const file of getAllFiles(video)) { |
@@ -98,7 +98,7 @@ describe('Test video static file privacy', function () { | |||
98 | const { uuid } = await server.videos.quickUpload({ name: 'video', privacy }) | 98 | const { uuid } = await server.videos.quickUpload({ name: 'video', privacy }) |
99 | await waitJobs([ server ]) | 99 | await waitJobs([ server ]) |
100 | 100 | ||
101 | await checkPrivateWebTorrentFiles(uuid) | 101 | await checkPrivateFiles(uuid) |
102 | } | 102 | } |
103 | }) | 103 | }) |
104 | 104 | ||
@@ -112,7 +112,7 @@ describe('Test video static file privacy', function () { | |||
112 | await server.videos.update({ id: uuid, attributes: { privacy } }) | 112 | await server.videos.update({ id: uuid, attributes: { privacy } }) |
113 | await waitJobs([ server ]) | 113 | await waitJobs([ server ]) |
114 | 114 | ||
115 | await checkPrivateWebTorrentFiles(uuid) | 115 | await checkPrivateFiles(uuid) |
116 | } | 116 | } |
117 | }) | 117 | }) |
118 | 118 | ||
@@ -125,7 +125,7 @@ describe('Test video static file privacy', function () { | |||
125 | await server.videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.UNLISTED } }) | 125 | await server.videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.UNLISTED } }) |
126 | await waitJobs([ server ]) | 126 | await waitJobs([ server ]) |
127 | 127 | ||
128 | await checkPublicWebTorrentFiles(uuid) | 128 | await checkPublicFiles(uuid) |
129 | }) | 129 | }) |
130 | 130 | ||
131 | it('Should upload an internal video and update it to public to have a public static path', async function () { | 131 | it('Should upload an internal video and update it to public to have a public static path', async function () { |
@@ -137,7 +137,7 @@ describe('Test video static file privacy', function () { | |||
137 | await server.videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.PUBLIC } }) | 137 | await server.videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.PUBLIC } }) |
138 | await waitJobs([ server ]) | 138 | await waitJobs([ server ]) |
139 | 139 | ||
140 | await checkPublicWebTorrentFiles(uuid) | 140 | await checkPublicFiles(uuid) |
141 | }) | 141 | }) |
142 | 142 | ||
143 | it('Should upload an internal video and schedule a public publish', async function () { | 143 | it('Should upload an internal video and schedule a public publish', async function () { |
@@ -160,7 +160,7 @@ describe('Test video static file privacy', function () { | |||
160 | 160 | ||
161 | await waitJobs([ server ]) | 161 | await waitJobs([ server ]) |
162 | 162 | ||
163 | await checkPublicWebTorrentFiles(uuid) | 163 | await checkPublicFiles(uuid) |
164 | }) | 164 | }) |
165 | } | 165 | } |
166 | 166 | ||
diff --git a/server/tests/cli/create-import-video-file-job.ts b/server/tests/cli/create-import-video-file-job.ts index a4aa5f699..43f53035b 100644 --- a/server/tests/cli/create-import-video-file-job.ts +++ b/server/tests/cli/create-import-video-file-job.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 4 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
5 | import { HttpStatusCode, VideoDetails, VideoFile, VideoInclude } from '@shared/models' | 5 | import { HttpStatusCode, VideoDetails, VideoFile, VideoInclude } from '@shared/models' |
6 | import { | 6 | import { |
7 | cleanupTests, | 7 | cleanupTests, |
@@ -27,7 +27,7 @@ function assertVideoProperties (video: VideoFile, resolution: number, extname: s | |||
27 | 27 | ||
28 | async function checkFiles (video: VideoDetails, objectStorage: boolean) { | 28 | async function checkFiles (video: VideoDetails, objectStorage: boolean) { |
29 | for (const file of video.files) { | 29 | for (const file of video.files) { |
30 | if (objectStorage) expectStartWith(file.fileUrl, ObjectStorageCommand.getWebTorrentBaseUrl()) | 30 | if (objectStorage) expectStartWith(file.fileUrl, ObjectStorageCommand.getMockWebTorrentBaseUrl()) |
31 | 31 | ||
32 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) | 32 | await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) |
33 | } | 33 | } |
@@ -43,7 +43,7 @@ function runTests (objectStorage: boolean) { | |||
43 | this.timeout(90000) | 43 | this.timeout(90000) |
44 | 44 | ||
45 | const config = objectStorage | 45 | const config = objectStorage |
46 | ? ObjectStorageCommand.getDefaultConfig() | 46 | ? ObjectStorageCommand.getDefaultMockConfig() |
47 | : {} | 47 | : {} |
48 | 48 | ||
49 | // Run server 2 to have transcoding enabled | 49 | // Run server 2 to have transcoding enabled |
@@ -52,7 +52,7 @@ function runTests (objectStorage: boolean) { | |||
52 | 52 | ||
53 | await doubleFollow(servers[0], servers[1]) | 53 | await doubleFollow(servers[0], servers[1]) |
54 | 54 | ||
55 | if (objectStorage) await ObjectStorageCommand.prepareDefaultBuckets() | 55 | if (objectStorage) await ObjectStorageCommand.prepareDefaultMockBuckets() |
56 | 56 | ||
57 | // Upload two videos for our needs | 57 | // Upload two videos for our needs |
58 | { | 58 | { |
@@ -157,7 +157,7 @@ describe('Test create import video jobs', function () { | |||
157 | }) | 157 | }) |
158 | 158 | ||
159 | describe('On object storage', function () { | 159 | describe('On object storage', function () { |
160 | if (areObjectStorageTestsDisabled()) return | 160 | if (areMockObjectStorageTestsDisabled()) return |
161 | 161 | ||
162 | runTests(true) | 162 | runTests(true) |
163 | }) | 163 | }) |
diff --git a/server/tests/cli/create-move-video-storage-job.ts b/server/tests/cli/create-move-video-storage-job.ts index ecdd75b76..c357f501b 100644 --- a/server/tests/cli/create-move-video-storage-job.ts +++ b/server/tests/cli/create-move-video-storage-job.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 3 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
4 | import { HttpStatusCode, VideoDetails } from '@shared/models' | 4 | import { HttpStatusCode, VideoDetails } from '@shared/models' |
5 | import { | 5 | import { |
6 | cleanupTests, | 6 | cleanupTests, |
@@ -17,7 +17,7 @@ import { expectStartWith } from '../shared' | |||
17 | async function checkFiles (origin: PeerTubeServer, video: VideoDetails, inObjectStorage: boolean) { | 17 | async function checkFiles (origin: PeerTubeServer, video: VideoDetails, inObjectStorage: boolean) { |
18 | for (const file of video.files) { | 18 | for (const file of video.files) { |
19 | const start = inObjectStorage | 19 | const start = inObjectStorage |
20 | ? ObjectStorageCommand.getWebTorrentBaseUrl() | 20 | ? ObjectStorageCommand.getMockWebTorrentBaseUrl() |
21 | : origin.url | 21 | : origin.url |
22 | 22 | ||
23 | expectStartWith(file.fileUrl, start) | 23 | expectStartWith(file.fileUrl, start) |
@@ -26,7 +26,7 @@ async function checkFiles (origin: PeerTubeServer, video: VideoDetails, inObject | |||
26 | } | 26 | } |
27 | 27 | ||
28 | const start = inObjectStorage | 28 | const start = inObjectStorage |
29 | ? ObjectStorageCommand.getPlaylistBaseUrl() | 29 | ? ObjectStorageCommand.getMockPlaylistBaseUrl() |
30 | : origin.url | 30 | : origin.url |
31 | 31 | ||
32 | const hls = video.streamingPlaylists[0] | 32 | const hls = video.streamingPlaylists[0] |
@@ -41,7 +41,7 @@ async function checkFiles (origin: PeerTubeServer, video: VideoDetails, inObject | |||
41 | } | 41 | } |
42 | 42 | ||
43 | describe('Test create move video storage job', function () { | 43 | describe('Test create move video storage job', function () { |
44 | if (areObjectStorageTestsDisabled()) return | 44 | if (areMockObjectStorageTestsDisabled()) return |
45 | 45 | ||
46 | let servers: PeerTubeServer[] = [] | 46 | let servers: PeerTubeServer[] = [] |
47 | const uuids: string[] = [] | 47 | const uuids: string[] = [] |
@@ -55,7 +55,7 @@ describe('Test create move video storage job', function () { | |||
55 | 55 | ||
56 | await doubleFollow(servers[0], servers[1]) | 56 | await doubleFollow(servers[0], servers[1]) |
57 | 57 | ||
58 | await ObjectStorageCommand.prepareDefaultBuckets() | 58 | await ObjectStorageCommand.prepareDefaultMockBuckets() |
59 | 59 | ||
60 | await servers[0].config.enableTranscoding() | 60 | await servers[0].config.enableTranscoding() |
61 | 61 | ||
@@ -67,14 +67,14 @@ describe('Test create move video storage job', function () { | |||
67 | await waitJobs(servers) | 67 | await waitJobs(servers) |
68 | 68 | ||
69 | await servers[0].kill() | 69 | await servers[0].kill() |
70 | await servers[0].run(ObjectStorageCommand.getDefaultConfig()) | 70 | await servers[0].run(ObjectStorageCommand.getDefaultMockConfig()) |
71 | }) | 71 | }) |
72 | 72 | ||
73 | it('Should move only one file', async function () { | 73 | it('Should move only one file', async function () { |
74 | this.timeout(120000) | 74 | this.timeout(120000) |
75 | 75 | ||
76 | const command = `npm run create-move-video-storage-job -- --to-object-storage -v ${uuids[1]}` | 76 | const command = `npm run create-move-video-storage-job -- --to-object-storage -v ${uuids[1]}` |
77 | await servers[0].cli.execWithEnv(command, ObjectStorageCommand.getDefaultConfig()) | 77 | await servers[0].cli.execWithEnv(command, ObjectStorageCommand.getDefaultMockConfig()) |
78 | await waitJobs(servers) | 78 | await waitJobs(servers) |
79 | 79 | ||
80 | for (const server of servers) { | 80 | for (const server of servers) { |
@@ -94,7 +94,7 @@ describe('Test create move video storage job', function () { | |||
94 | this.timeout(120000) | 94 | this.timeout(120000) |
95 | 95 | ||
96 | const command = `npm run create-move-video-storage-job -- --to-object-storage --all-videos` | 96 | const command = `npm run create-move-video-storage-job -- --to-object-storage --all-videos` |
97 | await servers[0].cli.execWithEnv(command, ObjectStorageCommand.getDefaultConfig()) | 97 | await servers[0].cli.execWithEnv(command, ObjectStorageCommand.getDefaultMockConfig()) |
98 | await waitJobs(servers) | 98 | await waitJobs(servers) |
99 | 99 | ||
100 | for (const server of servers) { | 100 | for (const server of servers) { |
diff --git a/server/tests/cli/create-transcoding-job.ts b/server/tests/cli/create-transcoding-job.ts index 51bf04a80..38b737829 100644 --- a/server/tests/cli/create-transcoding-job.ts +++ b/server/tests/cli/create-transcoding-job.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { areObjectStorageTestsDisabled } from '@shared/core-utils' | 4 | import { areMockObjectStorageTestsDisabled } from '@shared/core-utils' |
5 | import { HttpStatusCode, VideoFile } from '@shared/models' | 5 | import { HttpStatusCode, VideoFile } from '@shared/models' |
6 | import { | 6 | import { |
7 | cleanupTests, | 7 | cleanupTests, |
@@ -18,8 +18,8 @@ import { checkResolutionsInMasterPlaylist, expectStartWith } from '../shared' | |||
18 | async function checkFilesInObjectStorage (files: VideoFile[], type: 'webtorrent' | 'playlist') { | 18 | async function checkFilesInObjectStorage (files: VideoFile[], type: 'webtorrent' | 'playlist') { |
19 | for (const file of files) { | 19 | for (const file of files) { |
20 | const shouldStartWith = type === 'webtorrent' | 20 | const shouldStartWith = type === 'webtorrent' |
21 | ? ObjectStorageCommand.getWebTorrentBaseUrl() | 21 | ? ObjectStorageCommand.getMockWebTorrentBaseUrl() |
22 | : ObjectStorageCommand.getPlaylistBaseUrl() | 22 | : ObjectStorageCommand.getMockPlaylistBaseUrl() |
23 | 23 | ||
24 | expectStartWith(file.fileUrl, shouldStartWith) | 24 | expectStartWith(file.fileUrl, shouldStartWith) |
25 | 25 | ||
@@ -36,7 +36,7 @@ function runTests (objectStorage: boolean) { | |||
36 | this.timeout(120000) | 36 | this.timeout(120000) |
37 | 37 | ||
38 | const config = objectStorage | 38 | const config = objectStorage |
39 | ? ObjectStorageCommand.getDefaultConfig() | 39 | ? ObjectStorageCommand.getDefaultMockConfig() |
40 | : {} | 40 | : {} |
41 | 41 | ||
42 | // Run server 2 to have transcoding enabled | 42 | // Run server 2 to have transcoding enabled |
@@ -47,7 +47,7 @@ function runTests (objectStorage: boolean) { | |||
47 | 47 | ||
48 | await doubleFollow(servers[0], servers[1]) | 48 | await doubleFollow(servers[0], servers[1]) |
49 | 49 | ||
50 | if (objectStorage) await ObjectStorageCommand.prepareDefaultBuckets() | 50 | if (objectStorage) await ObjectStorageCommand.prepareDefaultMockBuckets() |
51 | 51 | ||
52 | for (let i = 1; i <= 5; i++) { | 52 | for (let i = 1; i <= 5; i++) { |
53 | const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'video' + i } }) | 53 | const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'video' + i } }) |
@@ -255,7 +255,7 @@ describe('Test create transcoding jobs', function () { | |||
255 | }) | 255 | }) |
256 | 256 | ||
257 | describe('On object storage', function () { | 257 | describe('On object storage', function () { |
258 | if (areObjectStorageTestsDisabled()) return | 258 | if (areMockObjectStorageTestsDisabled()) return |
259 | 259 | ||
260 | runTests(true) | 260 | runTests(true) |
261 | }) | 261 | }) |
diff --git a/server/tests/shared/live.ts b/server/tests/shared/live.ts index da3691711..78e29f575 100644 --- a/server/tests/shared/live.ts +++ b/server/tests/shared/live.ts | |||
@@ -50,7 +50,7 @@ async function testVideoResolutions (options: { | |||
50 | }) | 50 | }) |
51 | 51 | ||
52 | if (objectStorage) { | 52 | if (objectStorage) { |
53 | expect(hlsPlaylist.playlistUrl).to.contain(ObjectStorageCommand.getPlaylistBaseUrl()) | 53 | expect(hlsPlaylist.playlistUrl).to.contain(ObjectStorageCommand.getMockPlaylistBaseUrl()) |
54 | } | 54 | } |
55 | 55 | ||
56 | for (let i = 0; i < resolutions.length; i++) { | 56 | for (let i = 0; i < resolutions.length; i++) { |
@@ -65,11 +65,11 @@ async function testVideoResolutions (options: { | |||
65 | }) | 65 | }) |
66 | 66 | ||
67 | const baseUrl = objectStorage | 67 | const baseUrl = objectStorage |
68 | ? ObjectStorageCommand.getPlaylistBaseUrl() + 'hls' | 68 | ? ObjectStorageCommand.getMockPlaylistBaseUrl() + 'hls' |
69 | : originServer.url + '/static/streaming-playlists/hls' | 69 | : originServer.url + '/static/streaming-playlists/hls' |
70 | 70 | ||
71 | if (objectStorage) { | 71 | if (objectStorage) { |
72 | expect(hlsPlaylist.segmentsSha256Url).to.contain(ObjectStorageCommand.getPlaylistBaseUrl()) | 72 | expect(hlsPlaylist.segmentsSha256Url).to.contain(ObjectStorageCommand.getMockPlaylistBaseUrl()) |
73 | } | 73 | } |
74 | 74 | ||
75 | const subPlaylist = await originServer.streamingPlaylists.get({ | 75 | const subPlaylist = await originServer.streamingPlaylists.get({ |
diff --git a/server/tests/shared/mock-servers/mock-object-storage.ts b/server/tests/shared/mock-servers/mock-object-storage.ts index 99d68e014..8c325bf11 100644 --- a/server/tests/shared/mock-servers/mock-object-storage.ts +++ b/server/tests/shared/mock-servers/mock-object-storage.ts | |||
@@ -12,7 +12,7 @@ export class MockObjectStorage { | |||
12 | const app = express() | 12 | const app = express() |
13 | 13 | ||
14 | app.get('/:bucketName/:path(*)', (req: express.Request, res: express.Response, next: express.NextFunction) => { | 14 | app.get('/:bucketName/:path(*)', (req: express.Request, res: express.Response, next: express.NextFunction) => { |
15 | const url = `http://${req.params.bucketName}.${ObjectStorageCommand.getEndpointHost()}/${req.params.path}` | 15 | const url = `http://${req.params.bucketName}.${ObjectStorageCommand.getMockEndpointHost()}/${req.params.path}` |
16 | 16 | ||
17 | if (process.env.DEBUG) { | 17 | if (process.env.DEBUG) { |
18 | console.log('Receiving request on mocked server %s.', req.url) | 18 | console.log('Receiving request on mocked server %s.', req.url) |
diff --git a/server/types/express.d.ts b/server/types/express.d.ts index 27d60da72..3738ffc47 100644 --- a/server/types/express.d.ts +++ b/server/types/express.d.ts | |||
@@ -97,7 +97,7 @@ declare module 'express' { | |||
97 | 97 | ||
98 | title?: string | 98 | title?: string |
99 | status?: number | 99 | status?: number |
100 | type?: ServerErrorCode | 100 | type?: ServerErrorCode | string |
101 | instance?: string | 101 | instance?: string |
102 | 102 | ||
103 | data?: PeerTubeProblemDocumentData | 103 | data?: PeerTubeProblemDocumentData |
diff --git a/shared/core-utils/common/env.ts b/shared/core-utils/common/env.ts index 38c96b152..973f895d4 100644 --- a/shared/core-utils/common/env.ts +++ b/shared/core-utils/common/env.ts | |||
@@ -14,7 +14,7 @@ function areHttpImportTestsDisabled () { | |||
14 | return disabled | 14 | return disabled |
15 | } | 15 | } |
16 | 16 | ||
17 | function areObjectStorageTestsDisabled () { | 17 | function areMockObjectStorageTestsDisabled () { |
18 | const disabled = process.env.ENABLE_OBJECT_STORAGE_TESTS !== 'true' | 18 | const disabled = process.env.ENABLE_OBJECT_STORAGE_TESTS !== 'true' |
19 | 19 | ||
20 | if (disabled) console.log('ENABLE_OBJECT_STORAGE_TESTS env is not set to "true" so object storage tests are disabled') | 20 | if (disabled) console.log('ENABLE_OBJECT_STORAGE_TESTS env is not set to "true" so object storage tests are disabled') |
@@ -22,9 +22,25 @@ function areObjectStorageTestsDisabled () { | |||
22 | return disabled | 22 | return disabled |
23 | } | 23 | } |
24 | 24 | ||
25 | function areScalewayObjectStorageTestsDisabled () { | ||
26 | if (areMockObjectStorageTestsDisabled()) return true | ||
27 | |||
28 | const enabled = process.env.OBJECT_STORAGE_SCALEWAY_KEY_ID && process.env.OBJECT_STORAGE_SCALEWAY_ACCESS_KEY | ||
29 | if (!enabled) { | ||
30 | console.log( | ||
31 | 'OBJECT_STORAGE_SCALEWAY_KEY_ID and/or OBJECT_STORAGE_SCALEWAY_ACCESS_KEY are not set, so scaleway object storage tests are disabled' | ||
32 | ) | ||
33 | |||
34 | return true | ||
35 | } | ||
36 | |||
37 | return false | ||
38 | } | ||
39 | |||
25 | export { | 40 | export { |
26 | parallelTests, | 41 | parallelTests, |
27 | isGithubCI, | 42 | isGithubCI, |
28 | areHttpImportTestsDisabled, | 43 | areHttpImportTestsDisabled, |
29 | areObjectStorageTestsDisabled | 44 | areMockObjectStorageTestsDisabled, |
45 | areScalewayObjectStorageTestsDisabled | ||
30 | } | 46 | } |
diff --git a/shared/core-utils/videos/privacy.ts b/shared/core-utils/videos/common.ts index f33487b49..2c6efdb7f 100644 --- a/shared/core-utils/videos/privacy.ts +++ b/shared/core-utils/videos/common.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { VideoDetails } from '../../models/videos/video.model' | 1 | import { VideoStreamingPlaylistType } from '@shared/models' |
2 | import { VideoPrivacy } from '../../models/videos/video-privacy.enum' | 2 | import { VideoPrivacy } from '../../models/videos/video-privacy.enum' |
3 | import { VideoDetails } from '../../models/videos/video.model' | ||
3 | 4 | ||
4 | function getAllPrivacies () { | 5 | function getAllPrivacies () { |
5 | return [ VideoPrivacy.PUBLIC, VideoPrivacy.INTERNAL, VideoPrivacy.PRIVATE, VideoPrivacy.UNLISTED ] | 6 | return [ VideoPrivacy.PUBLIC, VideoPrivacy.INTERNAL, VideoPrivacy.PRIVATE, VideoPrivacy.UNLISTED ] |
@@ -8,14 +9,18 @@ function getAllPrivacies () { | |||
8 | function getAllFiles (video: Partial<Pick<VideoDetails, 'files' | 'streamingPlaylists'>>) { | 9 | function getAllFiles (video: Partial<Pick<VideoDetails, 'files' | 'streamingPlaylists'>>) { |
9 | const files = video.files | 10 | const files = video.files |
10 | 11 | ||
11 | if (video.streamingPlaylists[0]) { | 12 | const hls = getHLS(video) |
12 | return files.concat(video.streamingPlaylists[0].files) | 13 | if (hls) return files.concat(hls.files) |
13 | } | ||
14 | 14 | ||
15 | return files | 15 | return files |
16 | } | 16 | } |
17 | 17 | ||
18 | function getHLS (video: Partial<Pick<VideoDetails, 'streamingPlaylists'>>) { | ||
19 | return video.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) | ||
20 | } | ||
21 | |||
18 | export { | 22 | export { |
19 | getAllPrivacies, | 23 | getAllPrivacies, |
20 | getAllFiles | 24 | getAllFiles, |
25 | getHLS | ||
21 | } | 26 | } |
diff --git a/shared/core-utils/videos/index.ts b/shared/core-utils/videos/index.ts index 620e3a716..2cf319395 100644 --- a/shared/core-utils/videos/index.ts +++ b/shared/core-utils/videos/index.ts | |||
@@ -1,2 +1,2 @@ | |||
1 | export * from './bitrate' | 1 | export * from './bitrate' |
2 | export * from './privacy' | 2 | export * from './common' |
diff --git a/shared/server-commands/miscs/sql-command.ts b/shared/server-commands/miscs/sql-command.ts index 09a99f834..b0d9ce56d 100644 --- a/shared/server-commands/miscs/sql-command.ts +++ b/shared/server-commands/miscs/sql-command.ts | |||
@@ -23,6 +23,11 @@ export class SQLCommand extends AbstractCommand { | |||
23 | return parseInt(total, 10) | 23 | return parseInt(total, 10) |
24 | } | 24 | } |
25 | 25 | ||
26 | async getInternalFileUrl (fileId: number) { | ||
27 | return this.selectQuery(`SELECT "fileUrl" FROM "videoFile" WHERE id = ${fileId}`) | ||
28 | .then(rows => rows[0].fileUrl as string) | ||
29 | } | ||
30 | |||
26 | setActorField (to: string, field: string, value: string) { | 31 | setActorField (to: string, field: string, value: string) { |
27 | const seq = this.getSequelize() | 32 | const seq = this.getSequelize() |
28 | 33 | ||
diff --git a/shared/server-commands/server/object-storage-command.ts b/shared/server-commands/server/object-storage-command.ts index b4de8f4cb..405e1b043 100644 --- a/shared/server-commands/server/object-storage-command.ts +++ b/shared/server-commands/server/object-storage-command.ts | |||
@@ -4,74 +4,121 @@ import { makePostBodyRequest } from '../requests' | |||
4 | import { AbstractCommand } from '../shared' | 4 | import { AbstractCommand } from '../shared' |
5 | 5 | ||
6 | export class ObjectStorageCommand extends AbstractCommand { | 6 | export class ObjectStorageCommand extends AbstractCommand { |
7 | static readonly DEFAULT_PLAYLIST_BUCKET = 'streaming-playlists' | 7 | static readonly DEFAULT_PLAYLIST_MOCK_BUCKET = 'streaming-playlists' |
8 | static readonly DEFAULT_WEBTORRENT_BUCKET = 'videos' | 8 | static readonly DEFAULT_WEBTORRENT_MOCK_BUCKET = 'videos' |
9 | 9 | ||
10 | static getDefaultConfig () { | 10 | static readonly DEFAULT_SCALEWAY_BUCKET = 'peertube-ci-test' |
11 | |||
12 | // --------------------------------------------------------------------------- | ||
13 | |||
14 | static getDefaultMockConfig () { | ||
11 | return { | 15 | return { |
12 | object_storage: { | 16 | object_storage: { |
13 | enabled: true, | 17 | enabled: true, |
14 | endpoint: 'http://' + this.getEndpointHost(), | 18 | endpoint: 'http://' + this.getMockEndpointHost(), |
15 | region: this.getRegion(), | 19 | region: this.getMockRegion(), |
16 | 20 | ||
17 | credentials: this.getCredentialsConfig(), | 21 | credentials: this.getMockCredentialsConfig(), |
18 | 22 | ||
19 | streaming_playlists: { | 23 | streaming_playlists: { |
20 | bucket_name: this.DEFAULT_PLAYLIST_BUCKET | 24 | bucket_name: this.DEFAULT_PLAYLIST_MOCK_BUCKET |
21 | }, | 25 | }, |
22 | 26 | ||
23 | videos: { | 27 | videos: { |
24 | bucket_name: this.DEFAULT_WEBTORRENT_BUCKET | 28 | bucket_name: this.DEFAULT_WEBTORRENT_MOCK_BUCKET |
25 | } | 29 | } |
26 | } | 30 | } |
27 | } | 31 | } |
28 | } | 32 | } |
29 | 33 | ||
30 | static getCredentialsConfig () { | 34 | static getMockCredentialsConfig () { |
31 | return { | 35 | return { |
32 | access_key_id: 'AKIAIOSFODNN7EXAMPLE', | 36 | access_key_id: 'AKIAIOSFODNN7EXAMPLE', |
33 | secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' | 37 | secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' |
34 | } | 38 | } |
35 | } | 39 | } |
36 | 40 | ||
37 | static getEndpointHost () { | 41 | static getMockEndpointHost () { |
38 | return 'localhost:9444' | 42 | return 'localhost:9444' |
39 | } | 43 | } |
40 | 44 | ||
41 | static getRegion () { | 45 | static getMockRegion () { |
42 | return 'us-east-1' | 46 | return 'us-east-1' |
43 | } | 47 | } |
44 | 48 | ||
45 | static getWebTorrentBaseUrl () { | 49 | static getMockWebTorrentBaseUrl () { |
46 | return `http://${this.DEFAULT_WEBTORRENT_BUCKET}.${this.getEndpointHost()}/` | 50 | return `http://${this.DEFAULT_WEBTORRENT_MOCK_BUCKET}.${this.getMockEndpointHost()}/` |
47 | } | 51 | } |
48 | 52 | ||
49 | static getPlaylistBaseUrl () { | 53 | static getMockPlaylistBaseUrl () { |
50 | return `http://${this.DEFAULT_PLAYLIST_BUCKET}.${this.getEndpointHost()}/` | 54 | return `http://${this.DEFAULT_PLAYLIST_MOCK_BUCKET}.${this.getMockEndpointHost()}/` |
51 | } | 55 | } |
52 | 56 | ||
53 | static async prepareDefaultBuckets () { | 57 | static async prepareDefaultMockBuckets () { |
54 | await this.createBucket(this.DEFAULT_PLAYLIST_BUCKET) | 58 | await this.createMockBucket(this.DEFAULT_PLAYLIST_MOCK_BUCKET) |
55 | await this.createBucket(this.DEFAULT_WEBTORRENT_BUCKET) | 59 | await this.createMockBucket(this.DEFAULT_WEBTORRENT_MOCK_BUCKET) |
56 | } | 60 | } |
57 | 61 | ||
58 | static async createBucket (name: string) { | 62 | static async createMockBucket (name: string) { |
59 | await makePostBodyRequest({ | 63 | await makePostBodyRequest({ |
60 | url: this.getEndpointHost(), | 64 | url: this.getMockEndpointHost(), |
61 | path: '/ui/' + name + '?delete', | 65 | path: '/ui/' + name + '?delete', |
62 | expectedStatus: HttpStatusCode.TEMPORARY_REDIRECT_307 | 66 | expectedStatus: HttpStatusCode.TEMPORARY_REDIRECT_307 |
63 | }) | 67 | }) |
64 | 68 | ||
65 | await makePostBodyRequest({ | 69 | await makePostBodyRequest({ |
66 | url: this.getEndpointHost(), | 70 | url: this.getMockEndpointHost(), |
67 | path: '/ui/' + name + '?create', | 71 | path: '/ui/' + name + '?create', |
68 | expectedStatus: HttpStatusCode.TEMPORARY_REDIRECT_307 | 72 | expectedStatus: HttpStatusCode.TEMPORARY_REDIRECT_307 |
69 | }) | 73 | }) |
70 | 74 | ||
71 | await makePostBodyRequest({ | 75 | await makePostBodyRequest({ |
72 | url: this.getEndpointHost(), | 76 | url: this.getMockEndpointHost(), |
73 | path: '/ui/' + name + '?make-public', | 77 | path: '/ui/' + name + '?make-public', |
74 | expectedStatus: HttpStatusCode.TEMPORARY_REDIRECT_307 | 78 | expectedStatus: HttpStatusCode.TEMPORARY_REDIRECT_307 |
75 | }) | 79 | }) |
76 | } | 80 | } |
81 | |||
82 | // --------------------------------------------------------------------------- | ||
83 | |||
84 | static getDefaultScalewayConfig (serverNumber: number) { | ||
85 | return { | ||
86 | object_storage: { | ||
87 | enabled: true, | ||
88 | endpoint: this.getScalewayEndpointHost(), | ||
89 | region: this.getScalewayRegion(), | ||
90 | |||
91 | credentials: this.getScalewayCredentialsConfig(), | ||
92 | |||
93 | streaming_playlists: { | ||
94 | bucket_name: this.DEFAULT_SCALEWAY_BUCKET, | ||
95 | prefix: `test:server-${serverNumber}-streaming-playlists:` | ||
96 | }, | ||
97 | |||
98 | videos: { | ||
99 | bucket_name: this.DEFAULT_SCALEWAY_BUCKET, | ||
100 | prefix: `test:server-${serverNumber}-videos:` | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | static getScalewayCredentialsConfig () { | ||
107 | return { | ||
108 | access_key_id: process.env.OBJECT_STORAGE_SCALEWAY_KEY_ID, | ||
109 | secret_access_key: process.env.OBJECT_STORAGE_SCALEWAY_ACCESS_KEY | ||
110 | } | ||
111 | } | ||
112 | |||
113 | static getScalewayEndpointHost () { | ||
114 | return 's3.fr-par.scw.cloud' | ||
115 | } | ||
116 | |||
117 | static getScalewayRegion () { | ||
118 | return 'fr-par' | ||
119 | } | ||
120 | |||
121 | static getScalewayBaseUrl () { | ||
122 | return `https://${this.DEFAULT_SCALEWAY_BUCKET}.${this.getScalewayEndpointHost()}/` | ||
123 | } | ||
77 | } | 124 | } |
diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index de193fa49..cc9502c6f 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts | |||
@@ -197,7 +197,7 @@ export class LiveCommand extends AbstractCommand { | |||
197 | 197 | ||
198 | const segmentName = `${playlistNumber}-00000${segment}.ts` | 198 | const segmentName = `${playlistNumber}-00000${segment}.ts` |
199 | const baseUrl = objectStorage | 199 | const baseUrl = objectStorage |
200 | ? ObjectStorageCommand.getPlaylistBaseUrl() + 'hls' | 200 | ? ObjectStorageCommand.getMockPlaylistBaseUrl() + 'hls' |
201 | : server.url + '/static/streaming-playlists/hls' | 201 | : server.url + '/static/streaming-playlists/hls' |
202 | 202 | ||
203 | let error = true | 203 | let error = true |
@@ -253,7 +253,7 @@ export class LiveCommand extends AbstractCommand { | |||
253 | 253 | ||
254 | const segmentName = `${playlistNumber}-00000${segment}.ts` | 254 | const segmentName = `${playlistNumber}-00000${segment}.ts` |
255 | const baseUrl = objectStorage | 255 | const baseUrl = objectStorage |
256 | ? ObjectStorageCommand.getPlaylistBaseUrl() | 256 | ? ObjectStorageCommand.getMockPlaylistBaseUrl() |
257 | : `${this.server.url}/static/streaming-playlists/hls` | 257 | : `${this.server.url}/static/streaming-playlists/hls` |
258 | 258 | ||
259 | const url = `${baseUrl}/${videoUUID}/${segmentName}` | 259 | const url = `${baseUrl}/${videoUUID}/${segmentName}` |
@@ -275,7 +275,7 @@ export class LiveCommand extends AbstractCommand { | |||
275 | const { playlistName, videoUUID, objectStorage = false } = options | 275 | const { playlistName, videoUUID, objectStorage = false } = options |
276 | 276 | ||
277 | const baseUrl = objectStorage | 277 | const baseUrl = objectStorage |
278 | ? ObjectStorageCommand.getPlaylistBaseUrl() | 278 | ? ObjectStorageCommand.getMockPlaylistBaseUrl() |
279 | : `${this.server.url}/static/streaming-playlists/hls` | 279 | : `${this.server.url}/static/streaming-playlists/hls` |
280 | 280 | ||
281 | const url = `${baseUrl}/${videoUUID}/${playlistName}` | 281 | const url = `${baseUrl}/${videoUUID}/${playlistName}` |
@@ -139,720 +139,740 @@ | |||
139 | "@aws-sdk/util-utf8-browser" "^3.0.0" | 139 | "@aws-sdk/util-utf8-browser" "^3.0.0" |
140 | tslib "^1.11.1" | 140 | tslib "^1.11.1" |
141 | 141 | ||
142 | "@aws-sdk/abort-controller@3.162.0": | 142 | "@aws-sdk/abort-controller@3.190.0": |
143 | version "3.162.0" | 143 | version "3.190.0" |
144 | resolved "https://registry.yarnpkg.com/@aws-sdk/abort-controller/-/abort-controller-3.162.0.tgz#c49c08e61e87c1e6bcba8214177228ecf4007535" | 144 | resolved "https://registry.yarnpkg.com/@aws-sdk/abort-controller/-/abort-controller-3.190.0.tgz#284263db7ba051f31dda64e077b68e45cca7a7b3" |
145 | integrity sha512-8j1f/g+pNny3HkOojl+6phwd1yQE0FmM6EdssRJPA/IpR+SE0qTva2psKfZA9DivAg+/iTBozVCQU5GUJY1F2A== | 145 | integrity sha512-M6qo2exTzEfHT5RuW7K090OgesUojhb2JyWiV4ulu7ngY4DWBUBMKUqac696sHRUZvGE5CDzSi0606DMboM+kA== |
146 | dependencies: | 146 | dependencies: |
147 | "@aws-sdk/types" "3.162.0" | 147 | "@aws-sdk/types" "3.190.0" |
148 | tslib "^2.3.1" | 148 | tslib "^2.3.1" |
149 | 149 | ||
150 | "@aws-sdk/chunked-blob-reader-native@3.109.0": | 150 | "@aws-sdk/chunked-blob-reader-native@3.188.0": |
151 | version "3.109.0" | 151 | version "3.188.0" |
152 | resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.109.0.tgz#4db2ec81faf38fe33cf9dd6f75641afe0826dcfd" | 152 | resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.188.0.tgz#a5c3a778b23af761703317ef286a083a43fb510f" |
153 | integrity sha512-Ybn3vDZ3CqGyprL2qdF6QZqoqlx8lA3qOJepobjuKKDRw+KgGxjUY4NvWe0R2MdRoduyaDj6uvhIay0S1MOSJQ== | 153 | integrity sha512-WielYjaAHfT/HAOW7Tj6yVeNdaOtts3aUm9Sf/3D+ElbCTGyaaMNfE4x0a+qn6dJZXewf1eAxybOIU5ftIeSGw== |
154 | dependencies: | 154 | dependencies: |
155 | "@aws-sdk/util-base64-browser" "3.109.0" | 155 | "@aws-sdk/util-base64-browser" "3.188.0" |
156 | tslib "^2.3.1" | 156 | tslib "^2.3.1" |
157 | 157 | ||
158 | "@aws-sdk/chunked-blob-reader@3.55.0": | 158 | "@aws-sdk/chunked-blob-reader@3.188.0": |
159 | version "3.55.0" | 159 | version "3.188.0" |
160 | resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.55.0.tgz#db240c78e7c4c826e707f0ca32a4d221c41cf6a0" | 160 | resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.188.0.tgz#18181b27511ab512e56b9f2cef30d2abbef639dc" |
161 | integrity sha512-o/xjMCq81opAjSBjt7YdHJwIJcGVG5XIV9+C2KXcY5QwVimkOKPybWTv0mXPvSwSilSx+EhpLNhkcJuXdzhw4w== | 161 | integrity sha512-zkPRFZZPL3eH+kH86LDYYXImiClA1/sW60zYOjse9Pgka+eDJlvBN6hcYxwDEKjcwATYiSRR1aVQHcfCinlGXg== |
162 | dependencies: | 162 | dependencies: |
163 | tslib "^2.3.1" | 163 | tslib "^2.3.1" |
164 | 164 | ||
165 | "@aws-sdk/client-s3@^3.23.0": | 165 | "@aws-sdk/client-s3@^3.190.0": |
166 | version "3.165.0" | 166 | version "3.190.0" |
167 | resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.165.0.tgz#62555e00ca5df1736c36682e39da272a9d6cf013" | 167 | resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.190.0.tgz#7d97da023d68fd19c1b2f9a8a6a162a75ff32daf" |
168 | integrity sha512-vVTIxf6OJoX0t2Ur64r0gQXKfSeK7VnHq4m5O6QM8IDmOuVP7jyeEt5sw1PaDC4amarVa215u/IZWsaIEDlrsw== | 168 | integrity sha512-ngF92/X+odFt5Zbs5AWTozI+35fwFkHghbDABi5uSWNtgs2alSc/A94/yexbDdvVrVnuUa/FAMkvYX8duGZ9ig== |
169 | dependencies: | 169 | dependencies: |
170 | "@aws-crypto/sha1-browser" "2.0.0" | 170 | "@aws-crypto/sha1-browser" "2.0.0" |
171 | "@aws-crypto/sha256-browser" "2.0.0" | 171 | "@aws-crypto/sha256-browser" "2.0.0" |
172 | "@aws-crypto/sha256-js" "2.0.0" | 172 | "@aws-crypto/sha256-js" "2.0.0" |
173 | "@aws-sdk/client-sts" "3.165.0" | 173 | "@aws-sdk/client-sts" "3.190.0" |
174 | "@aws-sdk/config-resolver" "3.163.0" | 174 | "@aws-sdk/config-resolver" "3.190.0" |
175 | "@aws-sdk/credential-provider-node" "3.165.0" | 175 | "@aws-sdk/credential-provider-node" "3.190.0" |
176 | "@aws-sdk/eventstream-serde-browser" "3.162.0" | 176 | "@aws-sdk/eventstream-serde-browser" "3.190.0" |
177 | "@aws-sdk/eventstream-serde-config-resolver" "3.162.0" | 177 | "@aws-sdk/eventstream-serde-config-resolver" "3.190.0" |
178 | "@aws-sdk/eventstream-serde-node" "3.162.0" | 178 | "@aws-sdk/eventstream-serde-node" "3.190.0" |
179 | "@aws-sdk/fetch-http-handler" "3.162.0" | 179 | "@aws-sdk/fetch-http-handler" "3.190.0" |
180 | "@aws-sdk/hash-blob-browser" "3.162.0" | 180 | "@aws-sdk/hash-blob-browser" "3.190.0" |
181 | "@aws-sdk/hash-node" "3.162.0" | 181 | "@aws-sdk/hash-node" "3.190.0" |
182 | "@aws-sdk/hash-stream-node" "3.162.0" | 182 | "@aws-sdk/hash-stream-node" "3.190.0" |
183 | "@aws-sdk/invalid-dependency" "3.162.0" | 183 | "@aws-sdk/invalid-dependency" "3.190.0" |
184 | "@aws-sdk/md5-js" "3.162.0" | 184 | "@aws-sdk/md5-js" "3.190.0" |
185 | "@aws-sdk/middleware-bucket-endpoint" "3.162.0" | 185 | "@aws-sdk/middleware-bucket-endpoint" "3.190.0" |
186 | "@aws-sdk/middleware-content-length" "3.162.0" | 186 | "@aws-sdk/middleware-content-length" "3.190.0" |
187 | "@aws-sdk/middleware-expect-continue" "3.162.0" | 187 | "@aws-sdk/middleware-expect-continue" "3.190.0" |
188 | "@aws-sdk/middleware-flexible-checksums" "3.162.0" | 188 | "@aws-sdk/middleware-flexible-checksums" "3.190.0" |
189 | "@aws-sdk/middleware-host-header" "3.162.0" | 189 | "@aws-sdk/middleware-host-header" "3.190.0" |
190 | "@aws-sdk/middleware-location-constraint" "3.162.0" | 190 | "@aws-sdk/middleware-location-constraint" "3.190.0" |
191 | "@aws-sdk/middleware-logger" "3.162.0" | 191 | "@aws-sdk/middleware-logger" "3.190.0" |
192 | "@aws-sdk/middleware-recursion-detection" "3.162.0" | 192 | "@aws-sdk/middleware-recursion-detection" "3.190.0" |
193 | "@aws-sdk/middleware-retry" "3.162.0" | 193 | "@aws-sdk/middleware-retry" "3.190.0" |
194 | "@aws-sdk/middleware-sdk-s3" "3.165.0" | 194 | "@aws-sdk/middleware-sdk-s3" "3.190.0" |
195 | "@aws-sdk/middleware-serde" "3.162.0" | 195 | "@aws-sdk/middleware-serde" "3.190.0" |
196 | "@aws-sdk/middleware-signing" "3.163.0" | 196 | "@aws-sdk/middleware-signing" "3.190.0" |
197 | "@aws-sdk/middleware-ssec" "3.162.0" | 197 | "@aws-sdk/middleware-ssec" "3.190.0" |
198 | "@aws-sdk/middleware-stack" "3.162.0" | 198 | "@aws-sdk/middleware-stack" "3.190.0" |
199 | "@aws-sdk/middleware-user-agent" "3.162.0" | 199 | "@aws-sdk/middleware-user-agent" "3.190.0" |
200 | "@aws-sdk/node-config-provider" "3.162.0" | 200 | "@aws-sdk/node-config-provider" "3.190.0" |
201 | "@aws-sdk/node-http-handler" "3.162.0" | 201 | "@aws-sdk/node-http-handler" "3.190.0" |
202 | "@aws-sdk/protocol-http" "3.162.0" | 202 | "@aws-sdk/protocol-http" "3.190.0" |
203 | "@aws-sdk/signature-v4-multi-region" "3.163.0" | 203 | "@aws-sdk/signature-v4-multi-region" "3.190.0" |
204 | "@aws-sdk/smithy-client" "3.162.0" | 204 | "@aws-sdk/smithy-client" "3.190.0" |
205 | "@aws-sdk/types" "3.162.0" | 205 | "@aws-sdk/types" "3.190.0" |
206 | "@aws-sdk/url-parser" "3.162.0" | 206 | "@aws-sdk/url-parser" "3.190.0" |
207 | "@aws-sdk/util-base64-browser" "3.109.0" | 207 | "@aws-sdk/util-base64-browser" "3.188.0" |
208 | "@aws-sdk/util-base64-node" "3.55.0" | 208 | "@aws-sdk/util-base64-node" "3.188.0" |
209 | "@aws-sdk/util-body-length-browser" "3.154.0" | 209 | "@aws-sdk/util-body-length-browser" "3.188.0" |
210 | "@aws-sdk/util-body-length-node" "3.55.0" | 210 | "@aws-sdk/util-body-length-node" "3.188.0" |
211 | "@aws-sdk/util-defaults-mode-browser" "3.162.0" | 211 | "@aws-sdk/util-defaults-mode-browser" "3.190.0" |
212 | "@aws-sdk/util-defaults-mode-node" "3.163.0" | 212 | "@aws-sdk/util-defaults-mode-node" "3.190.0" |
213 | "@aws-sdk/util-stream-browser" "3.162.0" | 213 | "@aws-sdk/util-stream-browser" "3.190.0" |
214 | "@aws-sdk/util-stream-node" "3.162.0" | 214 | "@aws-sdk/util-stream-node" "3.190.0" |
215 | "@aws-sdk/util-user-agent-browser" "3.162.0" | 215 | "@aws-sdk/util-user-agent-browser" "3.190.0" |
216 | "@aws-sdk/util-user-agent-node" "3.162.0" | 216 | "@aws-sdk/util-user-agent-node" "3.190.0" |
217 | "@aws-sdk/util-utf8-browser" "3.109.0" | 217 | "@aws-sdk/util-utf8-browser" "3.188.0" |
218 | "@aws-sdk/util-utf8-node" "3.109.0" | 218 | "@aws-sdk/util-utf8-node" "3.188.0" |
219 | "@aws-sdk/util-waiter" "3.162.0" | 219 | "@aws-sdk/util-waiter" "3.190.0" |
220 | "@aws-sdk/xml-builder" "3.142.0" | 220 | "@aws-sdk/xml-builder" "3.188.0" |
221 | entities "2.2.0" | 221 | fast-xml-parser "4.0.11" |
222 | fast-xml-parser "3.19.0" | ||
223 | tslib "^2.3.1" | 222 | tslib "^2.3.1" |
224 | 223 | ||
225 | "@aws-sdk/client-sso@3.165.0": | 224 | "@aws-sdk/client-sso@3.190.0": |
226 | version "3.165.0" | 225 | version "3.190.0" |
227 | resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.165.0.tgz#655e74e4673b79ab167d228a0ad9de8d08a88845" | 226 | resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.190.0.tgz#d3435bf406bd7cedf705e9e876da49dd5a2bc17f" |
228 | integrity sha512-Cizf03z6UFgHWOIQYOjZdNwUhoh6yhT5B2dH+mh1q+Naq1zsLmD2PUvx7SM+0fZsN9MhOICLyBSE/nSSE7E8Kg== | 227 | integrity sha512-joEKRjJEzgvXnEih/x2UDDCPlvXWCO3MAHmqi44yJ36Ph4YsFS299mOjPdVLuzUtpQ+cST1nRO7hXNFrulW2jQ== |
229 | dependencies: | 228 | dependencies: |
230 | "@aws-crypto/sha256-browser" "2.0.0" | 229 | "@aws-crypto/sha256-browser" "2.0.0" |
231 | "@aws-crypto/sha256-js" "2.0.0" | 230 | "@aws-crypto/sha256-js" "2.0.0" |
232 | "@aws-sdk/config-resolver" "3.163.0" | 231 | "@aws-sdk/config-resolver" "3.190.0" |
233 | "@aws-sdk/fetch-http-handler" "3.162.0" | 232 | "@aws-sdk/fetch-http-handler" "3.190.0" |
234 | "@aws-sdk/hash-node" "3.162.0" | 233 | "@aws-sdk/hash-node" "3.190.0" |
235 | "@aws-sdk/invalid-dependency" "3.162.0" | 234 | "@aws-sdk/invalid-dependency" "3.190.0" |
236 | "@aws-sdk/middleware-content-length" "3.162.0" | 235 | "@aws-sdk/middleware-content-length" "3.190.0" |
237 | "@aws-sdk/middleware-host-header" "3.162.0" | 236 | "@aws-sdk/middleware-host-header" "3.190.0" |
238 | "@aws-sdk/middleware-logger" "3.162.0" | 237 | "@aws-sdk/middleware-logger" "3.190.0" |
239 | "@aws-sdk/middleware-recursion-detection" "3.162.0" | 238 | "@aws-sdk/middleware-recursion-detection" "3.190.0" |
240 | "@aws-sdk/middleware-retry" "3.162.0" | 239 | "@aws-sdk/middleware-retry" "3.190.0" |
241 | "@aws-sdk/middleware-serde" "3.162.0" | 240 | "@aws-sdk/middleware-serde" "3.190.0" |
242 | "@aws-sdk/middleware-stack" "3.162.0" | 241 | "@aws-sdk/middleware-stack" "3.190.0" |
243 | "@aws-sdk/middleware-user-agent" "3.162.0" | 242 | "@aws-sdk/middleware-user-agent" "3.190.0" |
244 | "@aws-sdk/node-config-provider" "3.162.0" | 243 | "@aws-sdk/node-config-provider" "3.190.0" |
245 | "@aws-sdk/node-http-handler" "3.162.0" | 244 | "@aws-sdk/node-http-handler" "3.190.0" |
246 | "@aws-sdk/protocol-http" "3.162.0" | 245 | "@aws-sdk/protocol-http" "3.190.0" |
247 | "@aws-sdk/smithy-client" "3.162.0" | 246 | "@aws-sdk/smithy-client" "3.190.0" |
248 | "@aws-sdk/types" "3.162.0" | 247 | "@aws-sdk/types" "3.190.0" |
249 | "@aws-sdk/url-parser" "3.162.0" | 248 | "@aws-sdk/url-parser" "3.190.0" |
250 | "@aws-sdk/util-base64-browser" "3.109.0" | 249 | "@aws-sdk/util-base64-browser" "3.188.0" |
251 | "@aws-sdk/util-base64-node" "3.55.0" | 250 | "@aws-sdk/util-base64-node" "3.188.0" |
252 | "@aws-sdk/util-body-length-browser" "3.154.0" | 251 | "@aws-sdk/util-body-length-browser" "3.188.0" |
253 | "@aws-sdk/util-body-length-node" "3.55.0" | 252 | "@aws-sdk/util-body-length-node" "3.188.0" |
254 | "@aws-sdk/util-defaults-mode-browser" "3.162.0" | 253 | "@aws-sdk/util-defaults-mode-browser" "3.190.0" |
255 | "@aws-sdk/util-defaults-mode-node" "3.163.0" | 254 | "@aws-sdk/util-defaults-mode-node" "3.190.0" |
256 | "@aws-sdk/util-user-agent-browser" "3.162.0" | 255 | "@aws-sdk/util-user-agent-browser" "3.190.0" |
257 | "@aws-sdk/util-user-agent-node" "3.162.0" | 256 | "@aws-sdk/util-user-agent-node" "3.190.0" |
258 | "@aws-sdk/util-utf8-browser" "3.109.0" | 257 | "@aws-sdk/util-utf8-browser" "3.188.0" |
259 | "@aws-sdk/util-utf8-node" "3.109.0" | 258 | "@aws-sdk/util-utf8-node" "3.188.0" |
260 | tslib "^2.3.1" | 259 | tslib "^2.3.1" |
261 | 260 | ||
262 | "@aws-sdk/client-sts@3.165.0": | 261 | "@aws-sdk/client-sts@3.190.0": |
263 | version "3.165.0" | 262 | version "3.190.0" |
264 | resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.165.0.tgz#1d9824aba899af5c9e6712543916fa63bfb3a2bf" | 263 | resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.190.0.tgz#835a471daec37aa12e073f425aeab60fc1b3f9e5" |
265 | integrity sha512-pizXLuaIRDdC1zseB0v/YQ3IKxzJfD/bVBgOhQNCNVr4d7O7/oDXU3I+GhESmKpWopQADg1s1Q3NGtkUoJJUew== | 264 | integrity sha512-s5MqfxqWxHAl1RhfQ6swjawsVPBqmq5F+SfzZcGLBCnVv03GaSL8J9K42O1Cc0+HwPQH2miY+Avy0zAr6VpY+Q== |
266 | dependencies: | 265 | dependencies: |
267 | "@aws-crypto/sha256-browser" "2.0.0" | 266 | "@aws-crypto/sha256-browser" "2.0.0" |
268 | "@aws-crypto/sha256-js" "2.0.0" | 267 | "@aws-crypto/sha256-js" "2.0.0" |
269 | "@aws-sdk/config-resolver" "3.163.0" | 268 | "@aws-sdk/config-resolver" "3.190.0" |
270 | "@aws-sdk/credential-provider-node" "3.165.0" | 269 | "@aws-sdk/credential-provider-node" "3.190.0" |
271 | "@aws-sdk/fetch-http-handler" "3.162.0" | 270 | "@aws-sdk/fetch-http-handler" "3.190.0" |
272 | "@aws-sdk/hash-node" "3.162.0" | 271 | "@aws-sdk/hash-node" "3.190.0" |
273 | "@aws-sdk/invalid-dependency" "3.162.0" | 272 | "@aws-sdk/invalid-dependency" "3.190.0" |
274 | "@aws-sdk/middleware-content-length" "3.162.0" | 273 | "@aws-sdk/middleware-content-length" "3.190.0" |
275 | "@aws-sdk/middleware-host-header" "3.162.0" | 274 | "@aws-sdk/middleware-host-header" "3.190.0" |
276 | "@aws-sdk/middleware-logger" "3.162.0" | 275 | "@aws-sdk/middleware-logger" "3.190.0" |
277 | "@aws-sdk/middleware-recursion-detection" "3.162.0" | 276 | "@aws-sdk/middleware-recursion-detection" "3.190.0" |
278 | "@aws-sdk/middleware-retry" "3.162.0" | 277 | "@aws-sdk/middleware-retry" "3.190.0" |
279 | "@aws-sdk/middleware-sdk-sts" "3.163.0" | 278 | "@aws-sdk/middleware-sdk-sts" "3.190.0" |
280 | "@aws-sdk/middleware-serde" "3.162.0" | 279 | "@aws-sdk/middleware-serde" "3.190.0" |
281 | "@aws-sdk/middleware-signing" "3.163.0" | 280 | "@aws-sdk/middleware-signing" "3.190.0" |
282 | "@aws-sdk/middleware-stack" "3.162.0" | 281 | "@aws-sdk/middleware-stack" "3.190.0" |
283 | "@aws-sdk/middleware-user-agent" "3.162.0" | 282 | "@aws-sdk/middleware-user-agent" "3.190.0" |
284 | "@aws-sdk/node-config-provider" "3.162.0" | 283 | "@aws-sdk/node-config-provider" "3.190.0" |
285 | "@aws-sdk/node-http-handler" "3.162.0" | 284 | "@aws-sdk/node-http-handler" "3.190.0" |
286 | "@aws-sdk/protocol-http" "3.162.0" | 285 | "@aws-sdk/protocol-http" "3.190.0" |
287 | "@aws-sdk/smithy-client" "3.162.0" | 286 | "@aws-sdk/smithy-client" "3.190.0" |
288 | "@aws-sdk/types" "3.162.0" | 287 | "@aws-sdk/types" "3.190.0" |
289 | "@aws-sdk/url-parser" "3.162.0" | 288 | "@aws-sdk/url-parser" "3.190.0" |
290 | "@aws-sdk/util-base64-browser" "3.109.0" | 289 | "@aws-sdk/util-base64-browser" "3.188.0" |
291 | "@aws-sdk/util-base64-node" "3.55.0" | 290 | "@aws-sdk/util-base64-node" "3.188.0" |
292 | "@aws-sdk/util-body-length-browser" "3.154.0" | 291 | "@aws-sdk/util-body-length-browser" "3.188.0" |
293 | "@aws-sdk/util-body-length-node" "3.55.0" | 292 | "@aws-sdk/util-body-length-node" "3.188.0" |
294 | "@aws-sdk/util-defaults-mode-browser" "3.162.0" | 293 | "@aws-sdk/util-defaults-mode-browser" "3.190.0" |
295 | "@aws-sdk/util-defaults-mode-node" "3.163.0" | 294 | "@aws-sdk/util-defaults-mode-node" "3.190.0" |
296 | "@aws-sdk/util-user-agent-browser" "3.162.0" | 295 | "@aws-sdk/util-user-agent-browser" "3.190.0" |
297 | "@aws-sdk/util-user-agent-node" "3.162.0" | 296 | "@aws-sdk/util-user-agent-node" "3.190.0" |
298 | "@aws-sdk/util-utf8-browser" "3.109.0" | 297 | "@aws-sdk/util-utf8-browser" "3.188.0" |
299 | "@aws-sdk/util-utf8-node" "3.109.0" | 298 | "@aws-sdk/util-utf8-node" "3.188.0" |
300 | entities "2.2.0" | 299 | fast-xml-parser "4.0.11" |
301 | fast-xml-parser "3.19.0" | ||
302 | tslib "^2.3.1" | 300 | tslib "^2.3.1" |
303 | 301 | ||
304 | "@aws-sdk/config-resolver@3.163.0": | 302 | "@aws-sdk/config-resolver@3.190.0": |
305 | version "3.163.0" | 303 | version "3.190.0" |
306 | resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.163.0.tgz#65ae429a02d65a8a9d2fe321cc88fa9117c6ecae" | 304 | resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.190.0.tgz#cb068fef70360c227698b670a2f1224467b523b4" |
307 | integrity sha512-iBl5Zc3+VRGJy6n+aMcg++7tzYi4G1bHia6v/eF93SvdKxtRv40M9QnqoNfaNUuw9U2ltwKOHepw7J3bkOA8cQ== | 305 | integrity sha512-K+VnDtjTgjpf7yHEdDB0qgGbHToF0pIL0pQMSnmk2yc8BoB3LGG/gg1T0Ki+wRlrFnDCJ6L+8zUdawY2qDsbyw== |
308 | dependencies: | 306 | dependencies: |
309 | "@aws-sdk/signature-v4" "3.163.0" | 307 | "@aws-sdk/signature-v4" "3.190.0" |
310 | "@aws-sdk/types" "3.162.0" | 308 | "@aws-sdk/types" "3.190.0" |
311 | "@aws-sdk/util-config-provider" "3.109.0" | 309 | "@aws-sdk/util-config-provider" "3.188.0" |
312 | "@aws-sdk/util-middleware" "3.162.0" | 310 | "@aws-sdk/util-middleware" "3.190.0" |
313 | tslib "^2.3.1" | 311 | tslib "^2.3.1" |
314 | 312 | ||
315 | "@aws-sdk/credential-provider-env@3.162.0": | 313 | "@aws-sdk/credential-provider-env@3.190.0": |
316 | version "3.162.0" | 314 | version "3.190.0" |
317 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.162.0.tgz#be2bf9587d9e7b2a10b1c2530c5984b60efc11bd" | 315 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.190.0.tgz#b0be7325508529ec1d910b1f18c5a6cc98186dcd" |
318 | integrity sha512-yzCJXiAAbZZHB4iThi4I+rs+gTYwBSetdU4Z1D89a2xjcOjCa8IhdQKm3GO/uJMScy4VtW3EEFG4/zZ7dVQPOw== | 316 | integrity sha512-GTY7l3SJhTmRGFpWddbdJOihSqoMN8JMo3CsCtIjk4/h3xirBi02T4GSvbrMyP7FP3Fdl4NAdT+mHJ4q2Bvzxw== |
319 | dependencies: | 317 | dependencies: |
320 | "@aws-sdk/property-provider" "3.162.0" | 318 | "@aws-sdk/property-provider" "3.190.0" |
321 | "@aws-sdk/types" "3.162.0" | 319 | "@aws-sdk/types" "3.190.0" |
322 | tslib "^2.3.1" | 320 | tslib "^2.3.1" |
323 | 321 | ||
324 | "@aws-sdk/credential-provider-imds@3.162.0": | 322 | "@aws-sdk/credential-provider-imds@3.190.0": |
325 | version "3.162.0" | 323 | version "3.190.0" |
326 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.162.0.tgz#bb8002a37c42e6f2f42fcafff3a8e4262b6aac4a" | 324 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.190.0.tgz#15aee396b321e01ede0f0aa88f643e43c42ad879" |
327 | integrity sha512-ohrHMIu2MNauPjbE8mEMKtlEQH/VZdpNswPigaEejUGVumz0NSft9PlIn2X79sNX5Y+uXopynMQF4MZj773hTw== | 325 | integrity sha512-gI5pfBqGYCKdmx8igPvq+jLzyE2kuNn9Q5u73pdM/JZxiq7GeWYpE/MqqCubHxPtPcTFgAwxCxCFoXlUTBh/2g== |
328 | dependencies: | 326 | dependencies: |
329 | "@aws-sdk/node-config-provider" "3.162.0" | 327 | "@aws-sdk/node-config-provider" "3.190.0" |
330 | "@aws-sdk/property-provider" "3.162.0" | 328 | "@aws-sdk/property-provider" "3.190.0" |
331 | "@aws-sdk/types" "3.162.0" | 329 | "@aws-sdk/types" "3.190.0" |
332 | "@aws-sdk/url-parser" "3.162.0" | 330 | "@aws-sdk/url-parser" "3.190.0" |
333 | tslib "^2.3.1" | 331 | tslib "^2.3.1" |
334 | 332 | ||
335 | "@aws-sdk/credential-provider-ini@3.165.0": | 333 | "@aws-sdk/credential-provider-ini@3.190.0": |
336 | version "3.165.0" | 334 | version "3.190.0" |
337 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.165.0.tgz#eee4131ef1b8a0f815f53e6be5452b547e839d04" | 335 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.190.0.tgz#b12b9620aeb30c87d99dd234ba7c80b983688167" |
338 | integrity sha512-NrLe29bdhmpNPsEsYxUxb0hTxNMXCmz5pH2l/T9COT6SMxom1wpbB/aKwf9897Z1xvhoFi6flDQjmu//599BZw== | 336 | integrity sha512-Z7NN/evXJk59hBQlfOSWDfHntwmxwryu6uclgv7ECI6SEVtKt1EKIlPuCLUYgQ4lxb9bomyO5lQAl/1WutNT5w== |
339 | dependencies: | 337 | dependencies: |
340 | "@aws-sdk/credential-provider-env" "3.162.0" | 338 | "@aws-sdk/credential-provider-env" "3.190.0" |
341 | "@aws-sdk/credential-provider-imds" "3.162.0" | 339 | "@aws-sdk/credential-provider-imds" "3.190.0" |
342 | "@aws-sdk/credential-provider-sso" "3.165.0" | 340 | "@aws-sdk/credential-provider-sso" "3.190.0" |
343 | "@aws-sdk/credential-provider-web-identity" "3.162.0" | 341 | "@aws-sdk/credential-provider-web-identity" "3.190.0" |
344 | "@aws-sdk/property-provider" "3.162.0" | 342 | "@aws-sdk/property-provider" "3.190.0" |
345 | "@aws-sdk/shared-ini-file-loader" "3.162.0" | 343 | "@aws-sdk/shared-ini-file-loader" "3.190.0" |
346 | "@aws-sdk/types" "3.162.0" | 344 | "@aws-sdk/types" "3.190.0" |
347 | tslib "^2.3.1" | 345 | tslib "^2.3.1" |
348 | 346 | ||
349 | "@aws-sdk/credential-provider-node@3.165.0": | 347 | "@aws-sdk/credential-provider-node@3.190.0": |
350 | version "3.165.0" | 348 | version "3.190.0" |
351 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.165.0.tgz#ff3aa22df468ded2d370955f0b2c0548860583d4" | 349 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.190.0.tgz#7de69d65c694e26191414ddde978df929bd632b7" |
352 | integrity sha512-emUd3kqAvV8Qydn5pJ+YKo47UJ+B5RXNyQXMasNQsw1jxrB60j8QAIL9JGM019SzZBnHZuW3DrHClA17OVC+xQ== | 350 | integrity sha512-ctCG5+TsIK2gVgvvFiFjinPjc5nGpSypU3nQKCaihtPh83wDN6gCx4D0p9M8+fUrlPa5y+o/Y7yHo94ATepM8w== |
353 | dependencies: | 351 | dependencies: |
354 | "@aws-sdk/credential-provider-env" "3.162.0" | 352 | "@aws-sdk/credential-provider-env" "3.190.0" |
355 | "@aws-sdk/credential-provider-imds" "3.162.0" | 353 | "@aws-sdk/credential-provider-imds" "3.190.0" |
356 | "@aws-sdk/credential-provider-ini" "3.165.0" | 354 | "@aws-sdk/credential-provider-ini" "3.190.0" |
357 | "@aws-sdk/credential-provider-process" "3.162.0" | 355 | "@aws-sdk/credential-provider-process" "3.190.0" |
358 | "@aws-sdk/credential-provider-sso" "3.165.0" | 356 | "@aws-sdk/credential-provider-sso" "3.190.0" |
359 | "@aws-sdk/credential-provider-web-identity" "3.162.0" | 357 | "@aws-sdk/credential-provider-web-identity" "3.190.0" |
360 | "@aws-sdk/property-provider" "3.162.0" | 358 | "@aws-sdk/property-provider" "3.190.0" |
361 | "@aws-sdk/shared-ini-file-loader" "3.162.0" | 359 | "@aws-sdk/shared-ini-file-loader" "3.190.0" |
362 | "@aws-sdk/types" "3.162.0" | 360 | "@aws-sdk/types" "3.190.0" |
363 | tslib "^2.3.1" | 361 | tslib "^2.3.1" |
364 | 362 | ||
365 | "@aws-sdk/credential-provider-process@3.162.0": | 363 | "@aws-sdk/credential-provider-process@3.190.0": |
366 | version "3.162.0" | 364 | version "3.190.0" |
367 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.162.0.tgz#e54db5f3ac5a5200a6f04803b05278c028a54447" | 365 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.190.0.tgz#b1a4aa9fc83984bf2219cfc027a78deaca417c59" |
368 | integrity sha512-KtmYjlCMAa0XF3IJo4dxSF+OWmRoHbrdEHGEZw+j6iCZ3Nz6Y6xCsdxun5rAKdom1QRNMDR4wX0hRAdPYobW2w== | 366 | integrity sha512-sIJhICR80n5XY1kW/EFHTh5ZzBHb5X+744QCH3StcbKYI44mOZvNKfFdeRL2fQ7yLgV7npte2HJRZzQPWpZUrw== |
369 | dependencies: | 367 | dependencies: |
370 | "@aws-sdk/property-provider" "3.162.0" | 368 | "@aws-sdk/property-provider" "3.190.0" |
371 | "@aws-sdk/shared-ini-file-loader" "3.162.0" | 369 | "@aws-sdk/shared-ini-file-loader" "3.190.0" |
372 | "@aws-sdk/types" "3.162.0" | 370 | "@aws-sdk/types" "3.190.0" |
373 | tslib "^2.3.1" | 371 | tslib "^2.3.1" |
374 | 372 | ||
375 | "@aws-sdk/credential-provider-sso@3.165.0": | 373 | "@aws-sdk/credential-provider-sso@3.190.0": |
376 | version "3.165.0" | 374 | version "3.190.0" |
377 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.165.0.tgz#7da83675149983e25345c05ee1113e64485b5b19" | 375 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.190.0.tgz#285895dc38c09033154906ce253ff6f0bdca86ab" |
378 | integrity sha512-b2BuYyUSmnfChhz5ZbnqOaLSAsnzYcwpEPEUbQUdNGPSE3QcMd0SPl3woH82095WYlXTFjwgxlOPn5ad5hdBpA== | 376 | integrity sha512-uarU9vk471MHHT+GJj3KWFSmaaqLNL5n1KcMer2CCAZfjs+mStAi8+IjZuuKXB4vqVs5DxdH8cy5aLaJcBlXwQ== |
379 | dependencies: | 377 | dependencies: |
380 | "@aws-sdk/client-sso" "3.165.0" | 378 | "@aws-sdk/client-sso" "3.190.0" |
381 | "@aws-sdk/property-provider" "3.162.0" | 379 | "@aws-sdk/property-provider" "3.190.0" |
382 | "@aws-sdk/shared-ini-file-loader" "3.162.0" | 380 | "@aws-sdk/shared-ini-file-loader" "3.190.0" |
383 | "@aws-sdk/types" "3.162.0" | 381 | "@aws-sdk/types" "3.190.0" |
384 | tslib "^2.3.1" | 382 | tslib "^2.3.1" |
385 | 383 | ||
386 | "@aws-sdk/credential-provider-web-identity@3.162.0": | 384 | "@aws-sdk/credential-provider-web-identity@3.190.0": |
387 | version "3.162.0" | 385 | version "3.190.0" |
388 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.162.0.tgz#0b06aee91777b16c362ad565e9f1fdf77de7e8f6" | 386 | resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.190.0.tgz#c41fe6f1ebb814581b010c0f82e5232da85c90b7" |
389 | integrity sha512-vy86OS5/h+Vfk1bxvWjbayyUtFNdwU+mfALin3zxJbFqneSxRBydNBomt/guJjapZE+h865lkteyOsqsYMskzQ== | 387 | integrity sha512-nlIBeK9hGHKWC874h+ITAfPZ9Eaok+x/ydZQVKsLHiQ9PH3tuQ8AaGqhuCwBSH0hEAHZ/BiKeEx5VyWAE8/x+Q== |
390 | dependencies: | 388 | dependencies: |
391 | "@aws-sdk/property-provider" "3.162.0" | 389 | "@aws-sdk/property-provider" "3.190.0" |
392 | "@aws-sdk/types" "3.162.0" | 390 | "@aws-sdk/types" "3.190.0" |
393 | tslib "^2.3.1" | 391 | tslib "^2.3.1" |
394 | 392 | ||
395 | "@aws-sdk/eventstream-codec@3.162.0": | 393 | "@aws-sdk/eventstream-codec@3.190.0": |
396 | version "3.162.0" | 394 | version "3.190.0" |
397 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.162.0.tgz#c105a2d3081b0b74a3d1be6c49bd489a677102ad" | 395 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.190.0.tgz#7e9705ed5ffd2b7b77c0eca868c1c64a8a2d2941" |
398 | integrity sha512-DllkOwvOFO28nuFyY+Klu31aRwHp1Db6G6BfMfRFACId5RIE9LNVgEoNnR/uluZqQ9IN7k7kyp7ycztyn18tUA== | 396 | integrity sha512-F1ux94fMKUrlOfJR/1x8p5+lisfemKizNSRtMnj0kcR+Y9vIt9bUodFyuDF8tJl/7iwnop6EPiGc3QA1IKjBKA== |
399 | dependencies: | 397 | dependencies: |
400 | "@aws-crypto/crc32" "2.0.0" | 398 | "@aws-crypto/crc32" "2.0.0" |
401 | "@aws-sdk/types" "3.162.0" | 399 | "@aws-sdk/types" "3.190.0" |
402 | "@aws-sdk/util-hex-encoding" "3.109.0" | 400 | "@aws-sdk/util-hex-encoding" "3.188.0" |
403 | tslib "^2.3.1" | 401 | tslib "^2.3.1" |
404 | 402 | ||
405 | "@aws-sdk/eventstream-serde-browser@3.162.0": | 403 | "@aws-sdk/eventstream-serde-browser@3.190.0": |
406 | version "3.162.0" | 404 | version "3.190.0" |
407 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.162.0.tgz#d84952d5c65b247b3e01c4ee59c42a716338ce38" | 405 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.190.0.tgz#cb53132a6340742c2dd1a767da4442d3b5a6c866" |
408 | integrity sha512-99xPbUs3JS+uwdKe+pZu3UOc/GeI9qPk4epramssgaLKzQGkO4ylN3CD9ts4xeMXkE+VS0p0lEKeg80/fkzqzA== | 406 | integrity sha512-aUsbLLPi3dtafnpIJtGbpCe8fhABIsVV49V1jJx6gQDAs6HG5IhO3LfndF05H6UbMyt8sDS6223wSt6HFUSHjQ== |
409 | dependencies: | 407 | dependencies: |
410 | "@aws-sdk/eventstream-serde-universal" "3.162.0" | 408 | "@aws-sdk/eventstream-serde-universal" "3.190.0" |
411 | "@aws-sdk/types" "3.162.0" | 409 | "@aws-sdk/types" "3.190.0" |
412 | tslib "^2.3.1" | 410 | tslib "^2.3.1" |
413 | 411 | ||
414 | "@aws-sdk/eventstream-serde-config-resolver@3.162.0": | 412 | "@aws-sdk/eventstream-serde-config-resolver@3.190.0": |
415 | version "3.162.0" | 413 | version "3.190.0" |
416 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.162.0.tgz#2c5f749262575d44b8ebebff96e243d9c0bbcf38" | 414 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.190.0.tgz#9c05e4bd73157d0933bfa7b834ad34138cbac9c1" |
417 | integrity sha512-1G4IUPrcONzZ0o60CLbv3dOZT9UhT1iOCSRXzdy7XiTQ4rNLpqZVLG8GxNdu2ZpuDoW0ZdpjRDfmnzX+IXAILA== | 415 | integrity sha512-etlsbvG8KSFQpGzoNazJoNPnN3P/i+IgIo/5D8pEl4R7gkjLAHZYnbk299xfv59olDWn9SVdrZfVx8lS+lUWHA== |
418 | dependencies: | 416 | dependencies: |
419 | "@aws-sdk/types" "3.162.0" | 417 | "@aws-sdk/types" "3.190.0" |
420 | tslib "^2.3.1" | 418 | tslib "^2.3.1" |
421 | 419 | ||
422 | "@aws-sdk/eventstream-serde-node@3.162.0": | 420 | "@aws-sdk/eventstream-serde-node@3.190.0": |
423 | version "3.162.0" | 421 | version "3.190.0" |
424 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.162.0.tgz#06676c14b9cea5f179586d47bdbac9c60966efb4" | 422 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.190.0.tgz#de910debb967258be370e10fc8f2b970d936de8e" |
425 | integrity sha512-bXfgIR/6ZBdu022sTr0dRjEWMI1Z0UKCARYuywygwQ7GtAzhyHaRKrLk59foDX9NkLTExlQCfIRcsW6rMjL+hA== | 423 | integrity sha512-CmZ1jZJPar1uZAbfMrv00fzGk4NIc+1w4lRxOc0oow18pPSXsUAmefJKcW5ETX609xaH47nO5b7pTuHU8eGgzg== |
426 | dependencies: | 424 | dependencies: |
427 | "@aws-sdk/eventstream-serde-universal" "3.162.0" | 425 | "@aws-sdk/eventstream-serde-universal" "3.190.0" |
428 | "@aws-sdk/types" "3.162.0" | 426 | "@aws-sdk/types" "3.190.0" |
429 | tslib "^2.3.1" | 427 | tslib "^2.3.1" |
430 | 428 | ||
431 | "@aws-sdk/eventstream-serde-universal@3.162.0": | 429 | "@aws-sdk/eventstream-serde-universal@3.190.0": |
432 | version "3.162.0" | 430 | version "3.190.0" |
433 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.162.0.tgz#cf515746715baed3efc9bdac9e28ed29e8546142" | 431 | resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.190.0.tgz#28eb59946db104e15e63a117b9b3327b21c4da03" |
434 | integrity sha512-EnZGRWUkZ8d07OuoN+WG1u+ta42b6szf06F+SE2pKhsiAfnHHN3MsfxsnUN/ZYsgSXv6COxdp+acHR8CnjzRMQ== | 432 | integrity sha512-pioZzWDjjhfCfRIUr5oQdghUMdQV6KtP3lBrOO6rBCFCBOQjnQafqH+a+xRjEw19YvBpMX3tFUrVrUytCN9TDQ== |
435 | dependencies: | 433 | dependencies: |
436 | "@aws-sdk/eventstream-codec" "3.162.0" | 434 | "@aws-sdk/eventstream-codec" "3.190.0" |
437 | "@aws-sdk/types" "3.162.0" | 435 | "@aws-sdk/types" "3.190.0" |
438 | tslib "^2.3.1" | 436 | tslib "^2.3.1" |
439 | 437 | ||
440 | "@aws-sdk/fetch-http-handler@3.162.0": | 438 | "@aws-sdk/fetch-http-handler@3.190.0": |
441 | version "3.162.0" | 439 | version "3.190.0" |
442 | resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.162.0.tgz#d90d3f179ff11bedf69b971d22a7c00abba650d9" | 440 | resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.190.0.tgz#9943c8c9ec3bd9eb9121d3a6c1d356f24f0931a9" |
443 | integrity sha512-DZLxxEqSMXqKteYohO4w6uoORabpETWso6wBdIFMul1BbEseqLjub1594D5RA18cqkcM2dV4ttw+boPPzOjSAw== | 441 | integrity sha512-5riRpKydARXAPLesTZm6eP6QKJ4HJGQ3k0Tepi3nvxHVx3UddkRNoX0pLS3rvbajkykWPNC2qdfRGApWlwOYsA== |
444 | dependencies: | 442 | dependencies: |
445 | "@aws-sdk/protocol-http" "3.162.0" | 443 | "@aws-sdk/protocol-http" "3.190.0" |
446 | "@aws-sdk/querystring-builder" "3.162.0" | 444 | "@aws-sdk/querystring-builder" "3.190.0" |
447 | "@aws-sdk/types" "3.162.0" | 445 | "@aws-sdk/types" "3.190.0" |
448 | "@aws-sdk/util-base64-browser" "3.109.0" | 446 | "@aws-sdk/util-base64-browser" "3.188.0" |
449 | tslib "^2.3.1" | 447 | tslib "^2.3.1" |
450 | 448 | ||
451 | "@aws-sdk/hash-blob-browser@3.162.0": | 449 | "@aws-sdk/hash-blob-browser@3.190.0": |
452 | version "3.162.0" | 450 | version "3.190.0" |
453 | resolved "https://registry.yarnpkg.com/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.162.0.tgz#75d1ff18dc3181231b35a131adadfe85cc227e63" | 451 | resolved "https://registry.yarnpkg.com/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.190.0.tgz#75e7e69bbab4cda4b9f69ef208fc7e1d5f695ca0" |
454 | integrity sha512-m6d9jSQvV0eNWUOaUEHeP5N5AgjKs+wag+sY+Obr1zQlX1hp5boIauCEhTnm2sJxL5Z2M0bSleb/I0V8RFvYHw== | 452 | integrity sha512-qRIoUGsy6S6kmqi0LQ+Ma9L5HKm8lIt002z+Yhb4kRTf6PFBWa/A0mDyrcj6L3MV71QGKfAEacV5nrVMF/aIhw== |
455 | dependencies: | 453 | dependencies: |
456 | "@aws-sdk/chunked-blob-reader" "3.55.0" | 454 | "@aws-sdk/chunked-blob-reader" "3.188.0" |
457 | "@aws-sdk/chunked-blob-reader-native" "3.109.0" | 455 | "@aws-sdk/chunked-blob-reader-native" "3.188.0" |
458 | "@aws-sdk/types" "3.162.0" | 456 | "@aws-sdk/types" "3.190.0" |
459 | tslib "^2.3.1" | 457 | tslib "^2.3.1" |
460 | 458 | ||
461 | "@aws-sdk/hash-node@3.162.0": | 459 | "@aws-sdk/hash-node@3.190.0": |
462 | version "3.162.0" | 460 | version "3.190.0" |
463 | resolved "https://registry.yarnpkg.com/@aws-sdk/hash-node/-/hash-node-3.162.0.tgz#72eeba4fe923fc96103740600bcb5a217dc8d338" | 461 | resolved "https://registry.yarnpkg.com/@aws-sdk/hash-node/-/hash-node-3.190.0.tgz#0ecad888142e8c097e13701f7bafc69e3e7ce91e" |
464 | integrity sha512-lfyyAb0Cd084QnUNLTkYowD8RW3L5Tb9lNnIMH6HY7uSE/obw1j/OnLUPqpey628WJ5DPyyvNBah3Vu+JVZ5Mw== | 462 | integrity sha512-DNwVT3O8zc9Jk/bXiXcN0WsD98r+JJWryw9F1/ZZbuzbf6rx2qhI8ZK+nh5X6WMtYPU84luQMcF702fJt/1bzg== |
465 | dependencies: | 463 | dependencies: |
466 | "@aws-sdk/types" "3.162.0" | 464 | "@aws-sdk/types" "3.190.0" |
467 | "@aws-sdk/util-buffer-from" "3.55.0" | 465 | "@aws-sdk/util-buffer-from" "3.188.0" |
468 | tslib "^2.3.1" | 466 | tslib "^2.3.1" |
469 | 467 | ||
470 | "@aws-sdk/hash-stream-node@3.162.0": | 468 | "@aws-sdk/hash-stream-node@3.190.0": |
471 | version "3.162.0" | 469 | version "3.190.0" |
472 | resolved "https://registry.yarnpkg.com/@aws-sdk/hash-stream-node/-/hash-stream-node-3.162.0.tgz#cfb1e8cc36df4772a339416a5c4c5138064a8648" | 470 | resolved "https://registry.yarnpkg.com/@aws-sdk/hash-stream-node/-/hash-stream-node-3.190.0.tgz#3173e1febfccfcbc63e581dd355df26f94de2ec9" |
473 | integrity sha512-WnaKxaK+RIl+MOm3oohyKy1rDduNRTxMhSuLpo9NsZVc6tqZBXQ4Y4fTfND80YP6iyAcao1Gv96Ph8H6wY7yzA== | 471 | integrity sha512-Itdqn0tRx5bS9A1vy/GzvAtg+KeBwg1MTeiefJQrGsIzh7KitvbFpcDlHZBvId6HPLI0c0aIORucwi9ayEOqjQ== |
474 | dependencies: | 472 | dependencies: |
475 | "@aws-sdk/types" "3.162.0" | 473 | "@aws-sdk/types" "3.190.0" |
476 | tslib "^2.3.1" | 474 | tslib "^2.3.1" |
477 | 475 | ||
478 | "@aws-sdk/invalid-dependency@3.162.0": | 476 | "@aws-sdk/invalid-dependency@3.190.0": |
479 | version "3.162.0" | 477 | version "3.190.0" |
480 | resolved "https://registry.yarnpkg.com/@aws-sdk/invalid-dependency/-/invalid-dependency-3.162.0.tgz#a75b29aae362854041ebc4d282746041231109e4" | 478 | resolved "https://registry.yarnpkg.com/@aws-sdk/invalid-dependency/-/invalid-dependency-3.190.0.tgz#a4caa91ce50554f99fbfcba062eca233bb79e280" |
481 | integrity sha512-ENZ7Jf2EcxMMdAX9/sRrt/1rzeA2WwqAKrjIacKGT9KEGQNU+omWF/h+8stLCu0Uxcg0XswFXgQCXcI1IQuZjg== | 479 | integrity sha512-crCh63e8d/Uw9y3dQlVTPja7+IZiXpNXyH6oSuAadTDQwMq6KK87Av1/SDzVf6bAo2KgAOo41MyO2joaCEk0dQ== |
482 | dependencies: | 480 | dependencies: |
483 | "@aws-sdk/types" "3.162.0" | 481 | "@aws-sdk/types" "3.190.0" |
484 | tslib "^2.3.1" | 482 | tslib "^2.3.1" |
485 | 483 | ||
486 | "@aws-sdk/is-array-buffer@3.55.0": | 484 | "@aws-sdk/is-array-buffer@3.188.0": |
487 | version "3.55.0" | 485 | version "3.188.0" |
488 | resolved "https://registry.yarnpkg.com/@aws-sdk/is-array-buffer/-/is-array-buffer-3.55.0.tgz#c46122c5636f01d5895e5256a587768c3425ea7a" | 486 | resolved "https://registry.yarnpkg.com/@aws-sdk/is-array-buffer/-/is-array-buffer-3.188.0.tgz#2e969b2e799490e3bbd5008554aa346c58e3a9b6" |
489 | integrity sha512-NbiPHVYuPxdqdFd6FxzzN3H1BQn/iWA3ri3Ry7AyLeP/tGs1yzEWMwf8BN8TSMALI0GXT6Sh0GDWy3Ok5xB6DA== | 487 | integrity sha512-n69N4zJZCNd87Rf4NzufPzhactUeM877Y0Tp/F3KiHqGeTnVjYUa4Lv1vLBjqtfjYb2HWT3NKlYn5yzrhaEwiQ== |
490 | dependencies: | 488 | dependencies: |
491 | tslib "^2.3.1" | 489 | tslib "^2.3.1" |
492 | 490 | ||
493 | "@aws-sdk/lib-storage@^3.72.0": | 491 | "@aws-sdk/lib-storage@^3.190.0": |
494 | version "3.165.0" | 492 | version "3.190.0" |
495 | resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.165.0.tgz#810dec9b649656ae663ef14b7e1a5a5032363044" | 493 | resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.190.0.tgz#a7550ab703dc3e45421ad41599c59fb72df81802" |
496 | integrity sha512-6eM4xQgq4VfIFI8hLnrGXhnynFDnTdIGksE9ejOb6sloOVcqhsrffnWuhGRc4AkK2/LuExY8E+jKbiQjM0h3aQ== | 494 | integrity sha512-dmjtkMZlIncDOeYHPXEv/wxqT2V8z3l7eYHoILSnT/T1238dYOk06yGH6SyCdIdDxTJq5f06NQIzSCRtzN48EA== |
497 | dependencies: | 495 | dependencies: |
498 | "@aws-sdk/smithy-client" "3.162.0" | 496 | "@aws-sdk/middleware-endpoint" "3.190.0" |
497 | "@aws-sdk/smithy-client" "3.190.0" | ||
499 | buffer "5.6.0" | 498 | buffer "5.6.0" |
500 | events "3.3.0" | 499 | events "3.3.0" |
501 | stream-browserify "3.0.0" | 500 | stream-browserify "3.0.0" |
502 | tslib "^2.3.1" | 501 | tslib "^2.3.1" |
503 | 502 | ||
504 | "@aws-sdk/md5-js@3.162.0": | 503 | "@aws-sdk/md5-js@3.190.0": |
505 | version "3.162.0" | 504 | version "3.190.0" |
506 | resolved "https://registry.yarnpkg.com/@aws-sdk/md5-js/-/md5-js-3.162.0.tgz#f469e9dca0eea77ce9d87cf157dc034b834f1144" | 505 | resolved "https://registry.yarnpkg.com/@aws-sdk/md5-js/-/md5-js-3.190.0.tgz#6d6992a5f2012d36473c39356c89f499e87d33f0" |
507 | integrity sha512-8rODeZjopffWtnvGOOn3JZghztvxZBAF9a8I6rAUFUveOvyZbxhDZRxdqfGbnNesYBKxZRjU4hjt9dvfmRVSvw== | 506 | integrity sha512-zeyHnFzKYOgpAS1O+RfLyTRTjo0yLTw3Hooh/GjyuScfjwYG4UqP9kgZHnNLjHS9gXBahtskBOHaBCBGNTVLdw== |
508 | dependencies: | 507 | dependencies: |
509 | "@aws-sdk/types" "3.162.0" | 508 | "@aws-sdk/types" "3.190.0" |
510 | "@aws-sdk/util-utf8-browser" "3.109.0" | 509 | "@aws-sdk/util-utf8-browser" "3.188.0" |
511 | "@aws-sdk/util-utf8-node" "3.109.0" | 510 | "@aws-sdk/util-utf8-node" "3.188.0" |
512 | tslib "^2.3.1" | 511 | tslib "^2.3.1" |
513 | 512 | ||
514 | "@aws-sdk/middleware-bucket-endpoint@3.162.0": | 513 | "@aws-sdk/middleware-bucket-endpoint@3.190.0": |
515 | version "3.162.0" | 514 | version "3.190.0" |
516 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.162.0.tgz#7930aa6ecc2248c578996e43b00b4cddd77b8904" | 515 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.190.0.tgz#ddb703cdfaf5780351a4f7657bd3fa0e27899c8a" |
517 | integrity sha512-WkT8BqBN1GzAAzQnkhmyIIhRrZucCY2LdLgXfArYNgzdxFphUJXk19JuKlT8xQHBNENMnCiX+OHupn4prKXQaA== | 516 | integrity sha512-p1ItehR+NEEBpfPxRpq6VB12qIMWvs/D9ROLRltnIPC6Cf5H0rqWFf2ewT36PkkpL17+rjbt89N7AXLkBgU9NA== |
518 | dependencies: | 517 | dependencies: |
519 | "@aws-sdk/protocol-http" "3.162.0" | 518 | "@aws-sdk/protocol-http" "3.190.0" |
520 | "@aws-sdk/types" "3.162.0" | 519 | "@aws-sdk/types" "3.190.0" |
521 | "@aws-sdk/util-arn-parser" "3.55.0" | 520 | "@aws-sdk/util-arn-parser" "3.188.0" |
522 | "@aws-sdk/util-config-provider" "3.109.0" | 521 | "@aws-sdk/util-config-provider" "3.188.0" |
523 | tslib "^2.3.1" | 522 | tslib "^2.3.1" |
524 | 523 | ||
525 | "@aws-sdk/middleware-content-length@3.162.0": | 524 | "@aws-sdk/middleware-content-length@3.190.0": |
526 | version "3.162.0" | 525 | version "3.190.0" |
527 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.162.0.tgz#987d77a843598aa52d1045745dbae7e79e763464" | 526 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.190.0.tgz#640d2dfeeb1c715a93f8a03048a8458aaf153973" |
528 | integrity sha512-gwuxHPBNNkr9Ah9gTNHqJ3uIp3zeY+VC2H810+RqkG5QrxU1bGAN/zezIIbcAlXjMM9vTSfO0rxGI04nhTx0BQ== | 527 | integrity sha512-sSU347SuC6I8kWum1jlJlpAqeV23KP7enG+ToWcEcgFrJhm3AvuqB//NJxDbkKb2DNroRvJjBckBvrwNAjQnBQ== |
529 | dependencies: | 528 | dependencies: |
530 | "@aws-sdk/protocol-http" "3.162.0" | 529 | "@aws-sdk/protocol-http" "3.190.0" |
531 | "@aws-sdk/types" "3.162.0" | 530 | "@aws-sdk/types" "3.190.0" |
532 | tslib "^2.3.1" | 531 | tslib "^2.3.1" |
533 | 532 | ||
534 | "@aws-sdk/middleware-expect-continue@3.162.0": | 533 | "@aws-sdk/middleware-endpoint@3.190.0": |
535 | version "3.162.0" | 534 | version "3.190.0" |
536 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.162.0.tgz#4d3695f82cf950c6b47d227d8382a145e6992053" | 535 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.190.0.tgz#dfee34aece9a67598d2aebed1fd0565f740eb806" |
537 | integrity sha512-6AVKtODhV0mfwAONc67haulkPVlrxNkcgw4gEc4iXTT9ZQiyz4WHUU8hELB0Bkj+7or94BU15fCpUD3rK1VXeQ== | 536 | integrity sha512-jpsfQ1MuXVOBXtlMAkM/Dy5Qrv70K1V0FkRPYI6zftqfhDSf2sWb5Uc887m904bWwwQE4hIlkQJIPByZVkT0+g== |
537 | dependencies: | ||
538 | "@aws-sdk/middleware-serde" "3.190.0" | ||
539 | "@aws-sdk/protocol-http" "3.190.0" | ||
540 | "@aws-sdk/signature-v4" "3.190.0" | ||
541 | "@aws-sdk/types" "3.190.0" | ||
542 | "@aws-sdk/url-parser" "3.190.0" | ||
543 | "@aws-sdk/util-config-provider" "3.188.0" | ||
544 | "@aws-sdk/util-middleware" "3.190.0" | ||
545 | tslib "^2.3.1" | ||
546 | |||
547 | "@aws-sdk/middleware-expect-continue@3.190.0": | ||
548 | version "3.190.0" | ||
549 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.190.0.tgz#09167fa3206f663e6e605e11125529b162211df7" | ||
550 | integrity sha512-ZE3WY6RQ1uNuFgDn2KHfJXiLbwYgK/a4LX3SWNsO5gCrf9qchHTotkAc8PjFS5x4WV7TkddvhL2i57eikf1cYg== | ||
538 | dependencies: | 551 | dependencies: |
539 | "@aws-sdk/protocol-http" "3.162.0" | 552 | "@aws-sdk/protocol-http" "3.190.0" |
540 | "@aws-sdk/types" "3.162.0" | 553 | "@aws-sdk/types" "3.190.0" |
541 | tslib "^2.3.1" | 554 | tslib "^2.3.1" |
542 | 555 | ||
543 | "@aws-sdk/middleware-flexible-checksums@3.162.0": | 556 | "@aws-sdk/middleware-flexible-checksums@3.190.0": |
544 | version "3.162.0" | 557 | version "3.190.0" |
545 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.162.0.tgz#f218775cf65c4b28705a72a6f4968df7a48ca171" | 558 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.190.0.tgz#e453d92c95b594b05c9515387daa80d09368599f" |
546 | integrity sha512-KMOOJB+ntqSBVbsNln55Cm+wrPxP0+6dWdRcjuq1NnQqsTHoADiJ+o9+BBYgAFUQR4Q/zWcvxZQ7gTan0W+PLQ== | 559 | integrity sha512-YcZC2KX5G00RPhZpzFHBru2t27OelKYFG96Tc4cNOnjFmi++t7p5m5ZItFgovv9gUI9vTiI/XBQ+kc1XQ769Xw== |
547 | dependencies: | 560 | dependencies: |
548 | "@aws-crypto/crc32" "2.0.0" | 561 | "@aws-crypto/crc32" "2.0.0" |
549 | "@aws-crypto/crc32c" "2.0.0" | 562 | "@aws-crypto/crc32c" "2.0.0" |
550 | "@aws-sdk/is-array-buffer" "3.55.0" | 563 | "@aws-sdk/is-array-buffer" "3.188.0" |
551 | "@aws-sdk/protocol-http" "3.162.0" | 564 | "@aws-sdk/protocol-http" "3.190.0" |
552 | "@aws-sdk/types" "3.162.0" | 565 | "@aws-sdk/types" "3.190.0" |
553 | tslib "^2.3.1" | 566 | tslib "^2.3.1" |
554 | 567 | ||
555 | "@aws-sdk/middleware-host-header@3.162.0": | 568 | "@aws-sdk/middleware-host-header@3.190.0": |
556 | version "3.162.0" | 569 | version "3.190.0" |
557 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.162.0.tgz#c59015c83f6c574bde72534919022b3a90c3cd2a" | 570 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.190.0.tgz#47a01bd9b7db526114097db4659ef7e578881b62" |
558 | integrity sha512-gw5xe22P62N9yZPvrVXewM2vp70w9mLRWC1vh6pRDs0hEudAlsbXoWjB/z6jpG6ucA4Y1IOuXy5yGr9lND+zhg== | 571 | integrity sha512-cL7Vo/QSpGx/DDmFxjeV0Qlyi1atvHQDPn3MLBBmi1icu+3GKZkCMAJwzsrV3U4+WoVoDYT9FJ9yMQf2HaIjeQ== |
559 | dependencies: | 572 | dependencies: |
560 | "@aws-sdk/protocol-http" "3.162.0" | 573 | "@aws-sdk/protocol-http" "3.190.0" |
561 | "@aws-sdk/types" "3.162.0" | 574 | "@aws-sdk/types" "3.190.0" |
562 | tslib "^2.3.1" | 575 | tslib "^2.3.1" |
563 | 576 | ||
564 | "@aws-sdk/middleware-location-constraint@3.162.0": | 577 | "@aws-sdk/middleware-location-constraint@3.190.0": |
565 | version "3.162.0" | 578 | version "3.190.0" |
566 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.162.0.tgz#201f3f97099e6d771f7456cec526c235b608c7d3" | 579 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.190.0.tgz#bd624370daadb0b47982ea83b7e0ce001286654c" |
567 | integrity sha512-CnCx4TA8wZa4fnXYiyj37CIkOnppBKokZFu+mbiG6shxXb4tVA8p4PgptOnDRYJHLzgeD4v7B/zMFpUP3o7a8g== | 580 | integrity sha512-dJ9u7Jb51z9YZLlpvT61og4bzsArJ81cox1t1P990Bbbi+pvJWoiwhwTdLDZhGqTYYg9ZuPd1ajmM2d9NAG/CQ== |
568 | dependencies: | 581 | dependencies: |
569 | "@aws-sdk/types" "3.162.0" | 582 | "@aws-sdk/types" "3.190.0" |
570 | tslib "^2.3.1" | 583 | tslib "^2.3.1" |
571 | 584 | ||
572 | "@aws-sdk/middleware-logger@3.162.0": | 585 | "@aws-sdk/middleware-logger@3.190.0": |
573 | version "3.162.0" | 586 | version "3.190.0" |
574 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.162.0.tgz#10b2d552d7aa2c48b91061a418224cc47984272c" | 587 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.190.0.tgz#022c1c6da76d95b3d04e32179c5b1bdfb3944295" |
575 | integrity sha512-3YysLwpTZdfZkve2ytKFIwEc/WqDkxoI5kUXQq2hjsHAjLW7pEhUV00o+LJbgKjNxh38eSmmKeFlr5jnIjXHiQ== | 588 | integrity sha512-rrfLGYSZCBtiXNrIa8pJ2uwUoUMyj6Q82E8zmduTvqKWviCr6ZKes0lttGIkWhjvhql2m4CbjG5MPBnY7RXL4A== |
576 | dependencies: | 589 | dependencies: |
577 | "@aws-sdk/types" "3.162.0" | 590 | "@aws-sdk/types" "3.190.0" |
578 | tslib "^2.3.1" | 591 | tslib "^2.3.1" |
579 | 592 | ||
580 | "@aws-sdk/middleware-recursion-detection@3.162.0": | 593 | "@aws-sdk/middleware-recursion-detection@3.190.0": |
581 | version "3.162.0" | 594 | version "3.190.0" |
582 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.162.0.tgz#6c13e90ec9cc7b7adcb98bcb3d02eb37cef37b5c" | 595 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.190.0.tgz#6b8480ff62d141312f10940b0a0fe44f651e3f8a" |
583 | integrity sha512-AqoTnSX0JgoFuKPyWy0S+WUJqgfkVz6Os50azi32snjHmluEgLOmfeF0ixfxGFUVGxZp8WDuu/JVhwgTRKVuUA== | 596 | integrity sha512-5tc1AIIZe5jDNdyuJW+7vIFmQOxz3q031ZVrEtUEIF7cz2ySho2lkOWziz+v+UGSLhjHGKMz3V26+aN1FLZNxQ== |
584 | dependencies: | 597 | dependencies: |
585 | "@aws-sdk/protocol-http" "3.162.0" | 598 | "@aws-sdk/protocol-http" "3.190.0" |
586 | "@aws-sdk/types" "3.162.0" | 599 | "@aws-sdk/types" "3.190.0" |
587 | tslib "^2.3.1" | 600 | tslib "^2.3.1" |
588 | 601 | ||
589 | "@aws-sdk/middleware-retry@3.162.0": | 602 | "@aws-sdk/middleware-retry@3.190.0": |
590 | version "3.162.0" | 603 | version "3.190.0" |
591 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.162.0.tgz#0601882f9105fc440b902a937f630da65914bd99" | 604 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.190.0.tgz#935d4097d5785ae14b98272af69aed7ff066786b" |
592 | integrity sha512-9ZuTim8tnTgP7wNgj+RIdYzGhNgou6QBBX85qMIvngksRUgsd1CGR17HQTyYDZTKlZs7GvLt/L5FaJcOlpPUxA== | 605 | integrity sha512-h1bPopkncf2ue/erJdhqvgR2AEh0bIvkNsIHhx93DckWKotZd/GAVDq0gpKj7/f/7B+teHH8Fg5GDOwOOGyKcg== |
593 | dependencies: | 606 | dependencies: |
594 | "@aws-sdk/protocol-http" "3.162.0" | 607 | "@aws-sdk/protocol-http" "3.190.0" |
595 | "@aws-sdk/service-error-classification" "3.162.0" | 608 | "@aws-sdk/service-error-classification" "3.190.0" |
596 | "@aws-sdk/types" "3.162.0" | 609 | "@aws-sdk/types" "3.190.0" |
597 | "@aws-sdk/util-middleware" "3.162.0" | 610 | "@aws-sdk/util-middleware" "3.190.0" |
598 | tslib "^2.3.1" | 611 | tslib "^2.3.1" |
599 | uuid "^8.3.2" | 612 | uuid "^8.3.2" |
600 | 613 | ||
601 | "@aws-sdk/middleware-sdk-s3@3.165.0": | 614 | "@aws-sdk/middleware-sdk-s3@3.190.0": |
602 | version "3.165.0" | 615 | version "3.190.0" |
603 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.165.0.tgz#7181f9f2efec56fd85d98c845bf996d8d109d5e3" | 616 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.190.0.tgz#27f5d760896d76ea66e9fa4531b7cb3fb80654d4" |
604 | integrity sha512-OaCQqrgvJLdCVmBwSvQ/woYyDfYuOHUY4i7hl/DDH20QGq1n/CE8g7BBvFVqEaptin0dunFVHOOgzopmVpmOUQ== | 617 | integrity sha512-ixN3OOnF95Pla2Q9c4EyUpZk0TR5yYGbV1/eZqz5M9n2Iy1t6H11ZYSmK0BH3YjWG6Tdqva0AIwCfuvoUXWGZg== |
605 | dependencies: | 618 | dependencies: |
606 | "@aws-sdk/middleware-bucket-endpoint" "3.162.0" | 619 | "@aws-sdk/middleware-bucket-endpoint" "3.190.0" |
607 | "@aws-sdk/protocol-http" "3.162.0" | 620 | "@aws-sdk/protocol-http" "3.190.0" |
608 | "@aws-sdk/types" "3.162.0" | 621 | "@aws-sdk/types" "3.190.0" |
609 | "@aws-sdk/util-arn-parser" "3.55.0" | 622 | "@aws-sdk/util-arn-parser" "3.188.0" |
610 | tslib "^2.3.1" | 623 | tslib "^2.3.1" |
611 | 624 | ||
612 | "@aws-sdk/middleware-sdk-sts@3.163.0": | 625 | "@aws-sdk/middleware-sdk-sts@3.190.0": |
613 | version "3.163.0" | 626 | version "3.190.0" |
614 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.163.0.tgz#362eedb0739c3b4e98aa1154cc5c6f38d7e18f68" | 627 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.190.0.tgz#4606c41658f6d0ff2ff9b11bd2fc3a35f8ebd1ea" |
615 | integrity sha512-3UV0O5D3HPF5xHsIrDiygs06wmGVnoAXsyrqcZSPkYig9eGP6lTL1I8YS8JIG9/VojQDKjDUpQZMC3Om0+C7hA== | 628 | integrity sha512-eUHrsr35mkD/cAFKoYuFYz0zE7QPBWvSzMzqmEJC+YXzAF6IABP3FL/htAFpWkje5XDl5dQ6dAxzV+ebK8RNXQ== |
616 | dependencies: | 629 | dependencies: |
617 | "@aws-sdk/middleware-signing" "3.163.0" | 630 | "@aws-sdk/middleware-signing" "3.190.0" |
618 | "@aws-sdk/property-provider" "3.162.0" | 631 | "@aws-sdk/property-provider" "3.190.0" |
619 | "@aws-sdk/protocol-http" "3.162.0" | 632 | "@aws-sdk/protocol-http" "3.190.0" |
620 | "@aws-sdk/signature-v4" "3.163.0" | 633 | "@aws-sdk/signature-v4" "3.190.0" |
621 | "@aws-sdk/types" "3.162.0" | 634 | "@aws-sdk/types" "3.190.0" |
622 | tslib "^2.3.1" | 635 | tslib "^2.3.1" |
623 | 636 | ||
624 | "@aws-sdk/middleware-serde@3.162.0": | 637 | "@aws-sdk/middleware-serde@3.190.0": |
625 | version "3.162.0" | 638 | version "3.190.0" |
626 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.162.0.tgz#e83201bffd46500ed4ea71bb3ceda63505f31f96" | 639 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.190.0.tgz#85f17432facfa8453564a5b5cd2d24e722eeff9f" |
627 | integrity sha512-Vdgxbl7/o99CjeljQx3mTpY4cX7rc8YQykD49L2S61D6+Gkk9Zc4DMvaJDcxvR7ZUzRwjMTcMHlxbopcp1+UBA== | 640 | integrity sha512-S132hEOK4jwbtZ1bGAgSuQ0DMFG4TiD4ulAwbQRBYooC7tiWZbRiR0Pkt2hV8d7WhOHgUpg7rvqlA7/HXXBAsA== |
628 | dependencies: | 641 | dependencies: |
629 | "@aws-sdk/types" "3.162.0" | 642 | "@aws-sdk/types" "3.190.0" |
630 | tslib "^2.3.1" | 643 | tslib "^2.3.1" |
631 | 644 | ||
632 | "@aws-sdk/middleware-signing@3.163.0": | 645 | "@aws-sdk/middleware-signing@3.190.0": |
633 | version "3.163.0" | 646 | version "3.190.0" |
634 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.163.0.tgz#9ecc4bdeb1e2b67ab777808818f86ebde9e64578" | 647 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.190.0.tgz#32fc668c6ea7e632c1dd0eaacd78c71ff522dc77" |
635 | integrity sha512-Uj5vdejYUJOCJAx5u/SHWQTp75bd7GVqnXazO3QFHRjhSCMT55wsm8D+7LKRNbp4SjavO49m9kubXf+pLpqlJQ== | 648 | integrity sha512-Xj5MmXZq8UIpY8wOwyqei5q6MgqKxsO9Plo2zUgW7JR0w7R21MlqY2kzzvcM9R0FFhi9dqhniFT2ZMRUb1v73w== |
636 | dependencies: | 649 | dependencies: |
637 | "@aws-sdk/property-provider" "3.162.0" | 650 | "@aws-sdk/property-provider" "3.190.0" |
638 | "@aws-sdk/protocol-http" "3.162.0" | 651 | "@aws-sdk/protocol-http" "3.190.0" |
639 | "@aws-sdk/signature-v4" "3.163.0" | 652 | "@aws-sdk/signature-v4" "3.190.0" |
640 | "@aws-sdk/types" "3.162.0" | 653 | "@aws-sdk/types" "3.190.0" |
654 | "@aws-sdk/util-middleware" "3.190.0" | ||
641 | tslib "^2.3.1" | 655 | tslib "^2.3.1" |
642 | 656 | ||
643 | "@aws-sdk/middleware-ssec@3.162.0": | 657 | "@aws-sdk/middleware-ssec@3.190.0": |
644 | version "3.162.0" | 658 | version "3.190.0" |
645 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.162.0.tgz#2fcda524b9582a3fcec4124037b3cc3e2d81c453" | 659 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.190.0.tgz#8519077c258ed503953220bb004b2e338ecdd19d" |
646 | integrity sha512-hCPivyliCIQ3nncVJmwxhLiWiuMpk3aQYclhhg//KW8xke7UFr9Q6WD8wzINMWFnBOmsNq1guRi3uVjz6K9m2g== | 660 | integrity sha512-nwggMCfXBmhcDIrV/oPeSeuE1FRk0xvi/2PBuYYhM+xnkfUYovYUcdJhGkNqt7U1Mk0+CR2VVwozreigfcLesg== |
647 | dependencies: | 661 | dependencies: |
648 | "@aws-sdk/types" "3.162.0" | 662 | "@aws-sdk/types" "3.190.0" |
649 | tslib "^2.3.1" | 663 | tslib "^2.3.1" |
650 | 664 | ||
651 | "@aws-sdk/middleware-stack@3.162.0": | 665 | "@aws-sdk/middleware-stack@3.190.0": |
652 | version "3.162.0" | 666 | version "3.190.0" |
653 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.162.0.tgz#26b37e6241ca5c1a5e50bb2b1367a39eabd2b5ad" | 667 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.190.0.tgz#15572c938bf3bbe9d275870e541360fdc7997fab" |
654 | integrity sha512-e/by4QvDl9qMQHdBnLz6n8PRglswPb3eS23qT2Wt32KVLUehMUGAf1cdns6YmYSHATK/ivFmT2QHHEnNIc+n5w== | 668 | integrity sha512-h1mqiWNJdi1OTSEY8QovpiHgDQEeRG818v8yShpqSYXJKEqdn54MA3Z1D2fg/Wv/8ZJsFrBCiI7waT1JUYOmCg== |
655 | dependencies: | 669 | dependencies: |
656 | tslib "^2.3.1" | 670 | tslib "^2.3.1" |
657 | 671 | ||
658 | "@aws-sdk/middleware-user-agent@3.162.0": | 672 | "@aws-sdk/middleware-user-agent@3.190.0": |
659 | version "3.162.0" | 673 | version "3.190.0" |
660 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.162.0.tgz#da374bd9c66efc563ee9a2f6d1fff29c5ebea965" | 674 | resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.190.0.tgz#791eb451b01846184140eeda63dd51153f911c2c" |
661 | integrity sha512-aSCQk+oQbMPVHdncuend4jmd4MguLWjvi67OwKqdZjIKsSQfObCO8vwlfDM+ED3HcOfA0LwSxsFeSfQxC+WHxA== | 675 | integrity sha512-y/2cTE1iYHKR0nkb3DvR3G8vt12lcTP95r/iHp8ZO+Uzpc25jM/AyMHWr2ZjqQiHKNlzh8uRw1CmQtgg4sBxXQ== |
662 | dependencies: | 676 | dependencies: |
663 | "@aws-sdk/protocol-http" "3.162.0" | 677 | "@aws-sdk/protocol-http" "3.190.0" |
664 | "@aws-sdk/types" "3.162.0" | 678 | "@aws-sdk/types" "3.190.0" |
665 | tslib "^2.3.1" | 679 | tslib "^2.3.1" |
666 | 680 | ||
667 | "@aws-sdk/node-config-provider@3.162.0": | 681 | "@aws-sdk/node-config-provider@3.190.0": |
668 | version "3.162.0" | 682 | version "3.190.0" |
669 | resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.162.0.tgz#9637996fd5ef18ce4619b927744727d2aff0d508" | 683 | resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.190.0.tgz#a6005c5d3393970e1682c2561c5622d36d05c35d" |
670 | integrity sha512-PgaekXCCyz/gKkbukt9zYLBJDEVgmCm0l78q5J84yJbu0FhcZY4LaAgCHdzhsgEYWTX497hokzNc3rgLdVu46A== | 684 | integrity sha512-TJPUchyeK5KeEXWrwb6oW5/OkY3STCSGR1QIlbPcaTGkbo4kXAVyQmmZsY4KtRPuDM6/HlfUQV17bD716K65rQ== |
671 | dependencies: | 685 | dependencies: |
672 | "@aws-sdk/property-provider" "3.162.0" | 686 | "@aws-sdk/property-provider" "3.190.0" |
673 | "@aws-sdk/shared-ini-file-loader" "3.162.0" | 687 | "@aws-sdk/shared-ini-file-loader" "3.190.0" |
674 | "@aws-sdk/types" "3.162.0" | 688 | "@aws-sdk/types" "3.190.0" |
675 | tslib "^2.3.1" | 689 | tslib "^2.3.1" |
676 | 690 | ||
677 | "@aws-sdk/node-http-handler@3.162.0", "@aws-sdk/node-http-handler@^3.82.0": | 691 | "@aws-sdk/node-http-handler@3.190.0", "@aws-sdk/node-http-handler@^3.190.0": |
678 | version "3.162.0" | 692 | version "3.190.0" |
679 | resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.162.0.tgz#771370fe09cc3b030666a6654cf1e461e6fe3cf1" | 693 | resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.190.0.tgz#db14e265a5d42587b3edca0e71fa47f530d8c81b" |
680 | integrity sha512-9jNk9SU3nNLZ1OW+fd6zHGdByUDm0FEO3Hy+J62DvbFe16x09TnVnPAoHfZ69kjz5ZNS7Gg0wmdKjUHi9T3lJQ== | 694 | integrity sha512-3Klkr73TpZkCzcnSP+gmFF0Baluzk3r7BaWclJHqt2LcFUWfIJzYlnbBQNZ4t3EEq7ZlBJX85rIDHBRlS+rUyA== |
681 | dependencies: | 695 | dependencies: |
682 | "@aws-sdk/abort-controller" "3.162.0" | 696 | "@aws-sdk/abort-controller" "3.190.0" |
683 | "@aws-sdk/protocol-http" "3.162.0" | 697 | "@aws-sdk/protocol-http" "3.190.0" |
684 | "@aws-sdk/querystring-builder" "3.162.0" | 698 | "@aws-sdk/querystring-builder" "3.190.0" |
685 | "@aws-sdk/types" "3.162.0" | 699 | "@aws-sdk/types" "3.190.0" |
686 | tslib "^2.3.1" | 700 | tslib "^2.3.1" |
687 | 701 | ||
688 | "@aws-sdk/property-provider@3.162.0": | 702 | "@aws-sdk/property-provider@3.190.0": |
689 | version "3.162.0" | 703 | version "3.190.0" |
690 | resolved "https://registry.yarnpkg.com/@aws-sdk/property-provider/-/property-provider-3.162.0.tgz#45cdaadfba54bb1c275972f12f33f72c8eb22333" | 704 | resolved "https://registry.yarnpkg.com/@aws-sdk/property-provider/-/property-provider-3.190.0.tgz#99372b7e2fba63d3f47ea368c9659ef003733e57" |
691 | integrity sha512-kQLpibZRIrF58axcKY4Pr17YGoVBKBOWKol8jI8vlDhbFJqn14pVLohv4wZ8TzG2kKhWCF+t25YQCefWz2/lkg== | 705 | integrity sha512-uzdKjHE2blbuceTC5zeBgZ0+Uo/hf9pH20CHpJeVNtrrtF3GALtu4Y1Gu5QQVIQBz8gjHnqANx0XhfYzorv69Q== |
692 | dependencies: | 706 | dependencies: |
693 | "@aws-sdk/types" "3.162.0" | 707 | "@aws-sdk/types" "3.190.0" |
694 | tslib "^2.3.1" | 708 | tslib "^2.3.1" |
695 | 709 | ||
696 | "@aws-sdk/protocol-http@3.162.0": | 710 | "@aws-sdk/protocol-http@3.190.0": |
697 | version "3.162.0" | 711 | version "3.190.0" |
698 | resolved "https://registry.yarnpkg.com/@aws-sdk/protocol-http/-/protocol-http-3.162.0.tgz#3657cb6627576180d8c5a9a37d6c3f2984d70f92" | 712 | resolved "https://registry.yarnpkg.com/@aws-sdk/protocol-http/-/protocol-http-3.190.0.tgz#6f777f4f5193fc83402fdce29d8fc2bd0c93fb05" |
699 | integrity sha512-xMFFxwcO+x5QoQX/LRGb3BpLCIBWC9cBOULm34rYGBySd/zQqebVJOhiKTPzaRL02WZTDNxsEEQHg97Lpe8CNw== | 713 | integrity sha512-s5MVfeONpfZYRzCSbqQ+wJ3GxKED+aSS7+CQoeaYoD6HDTDxaMGNv9aiPxVCzW02sgG7py7f29Q6Vw+5taZXZA== |
700 | dependencies: | 714 | dependencies: |
701 | "@aws-sdk/types" "3.162.0" | 715 | "@aws-sdk/types" "3.190.0" |
702 | tslib "^2.3.1" | 716 | tslib "^2.3.1" |
703 | 717 | ||
704 | "@aws-sdk/querystring-builder@3.162.0": | 718 | "@aws-sdk/querystring-builder@3.190.0": |
705 | version "3.162.0" | 719 | version "3.190.0" |
706 | resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-builder/-/querystring-builder-3.162.0.tgz#c1667eebeb0e15ac6cae2523afa5ea3a8ca8aa00" | 720 | resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-builder/-/querystring-builder-3.190.0.tgz#5c115eb30343cc28ea8fc6ab1ca945907533403a" |
707 | integrity sha512-3urwxCEpnQwa1B6fKmcr8R2Qmzr8VDttRSay5CgD/stbZ4XUzNsA6G1V36+EL1Vq4vMr1aZhriARioLDlhcz+g== | 721 | integrity sha512-w9mTKkCsaLIBC8EA4RAHrqethNGbf60CbpPzN/QM7yCV3ZZJAXkppFfjTVVOMbPaI8GUEOptJtzgqV68CRB7ow== |
708 | dependencies: | 722 | dependencies: |
709 | "@aws-sdk/types" "3.162.0" | 723 | "@aws-sdk/types" "3.190.0" |
710 | "@aws-sdk/util-uri-escape" "3.55.0" | 724 | "@aws-sdk/util-uri-escape" "3.188.0" |
711 | tslib "^2.3.1" | 725 | tslib "^2.3.1" |
712 | 726 | ||
713 | "@aws-sdk/querystring-parser@3.162.0": | 727 | "@aws-sdk/querystring-parser@3.190.0": |
714 | version "3.162.0" | 728 | version "3.190.0" |
715 | resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-parser/-/querystring-parser-3.162.0.tgz#d4f0522cfe2a44d2f242a2e5c9c9cf928930938e" | 729 | resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-parser/-/querystring-parser-3.190.0.tgz#e96fab0ac834ab57777d736790eb2509491bd3fa" |
716 | integrity sha512-0ccaGsR1O7e3BsprdYBMwGf8gmycTv1Dfz2EB5R6MiTqzcuQJ/lxpIcRh3jhUJaD1TPlUziyrBEAxtLka3HDDQ== | 730 | integrity sha512-vCKP0s33VtS47LSYzEWRRr2aTbi3qNkUuQyIrc5LMqBfS5hsy79P1HL4Q7lCVqZB5fe61N8fKzOxDxWRCF0sXg== |
717 | dependencies: | 731 | dependencies: |
718 | "@aws-sdk/types" "3.162.0" | 732 | "@aws-sdk/types" "3.190.0" |
719 | tslib "^2.3.1" | 733 | tslib "^2.3.1" |
720 | 734 | ||
721 | "@aws-sdk/service-error-classification@3.162.0": | 735 | "@aws-sdk/service-error-classification@3.190.0": |
722 | version "3.162.0" | 736 | version "3.190.0" |
723 | resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.162.0.tgz#b07ed4ef541ec4d3d3cfe93efae054e3d39b5a1b" | 737 | resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.190.0.tgz#b1e232abfdc98fcf6f12dcbe50f9b9141fe53d42" |
724 | integrity sha512-AD9XL3CHFzwVWNEzdTo9aRnJl1ImqrRLlJ5zR/5ihTIJ68ZTYEiYP4vNKSCV6UfQ+vaaRNgLwiAx7JXzY54awg== | 738 | integrity sha512-g+s6xtaMa5fCMA2zJQC4BiFGMP7FN5/L1V/UwxCnKy8skCwaN0K5A1tFffBjjbYiPI7Gu7LVorWD2A0Y4xl01Q== |
725 | 739 | ||
726 | "@aws-sdk/shared-ini-file-loader@3.162.0": | 740 | "@aws-sdk/shared-ini-file-loader@3.190.0": |
727 | version "3.162.0" | 741 | version "3.190.0" |
728 | resolved "https://registry.yarnpkg.com/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.162.0.tgz#53bc40d774f4411200104e415cbe27a3dea110f7" | 742 | resolved "https://registry.yarnpkg.com/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.190.0.tgz#23efb053ae56f7cb96cb1cb64e8afeffafac963c" |
729 | integrity sha512-AGxISXns+1o6Pw+SPizFJDTw4Lwm+JSwhycCNhFU3JfdLsKfLY08JV4JHlcc+TyY4a8HhnGvE3r5t2f2dPLIsA== | 743 | integrity sha512-CZC/xsGReUEl5w+JgfancrxfkaCbEisyIFy6HALUYrioWQe80WMqLAdUMZSXHWjIaNK9mH0J/qvcSV2MuIoMzQ== |
730 | dependencies: | 744 | dependencies: |
745 | "@aws-sdk/types" "3.190.0" | ||
731 | tslib "^2.3.1" | 746 | tslib "^2.3.1" |
732 | 747 | ||
733 | "@aws-sdk/signature-v4-multi-region@3.163.0": | 748 | "@aws-sdk/signature-v4-multi-region@3.190.0": |
734 | version "3.163.0" | 749 | version "3.190.0" |
735 | resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.163.0.tgz#e1d58d6dd40c4530d6ae83f8ebc0ad33a64f5d7c" | 750 | resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.190.0.tgz#f3971e238362b3128dcf536142277f4123ddafed" |
736 | integrity sha512-SIb6e1dFNchvWziKudh7+BbYjUDW7WAEWWz419pKj/WDGdZNaA7dj7rr4IAB9vbi6QqzkECGDszdMqriWbJrDg== | 751 | integrity sha512-i9BpqlY3kAF8l8amqJ4skyjrlBy4B3hhO4RPu1D1wF4+GsJ5JGZ638Y5bYMH90k7A7ycTDDgFWHJcAsm1b0fEQ== |
737 | dependencies: | 752 | dependencies: |
738 | "@aws-sdk/protocol-http" "3.162.0" | 753 | "@aws-sdk/protocol-http" "3.190.0" |
739 | "@aws-sdk/signature-v4" "3.163.0" | 754 | "@aws-sdk/signature-v4" "3.190.0" |
740 | "@aws-sdk/types" "3.162.0" | 755 | "@aws-sdk/types" "3.190.0" |
741 | "@aws-sdk/util-arn-parser" "3.55.0" | 756 | "@aws-sdk/util-arn-parser" "3.188.0" |
742 | tslib "^2.3.1" | 757 | tslib "^2.3.1" |
743 | 758 | ||
744 | "@aws-sdk/signature-v4@3.163.0": | 759 | "@aws-sdk/signature-v4@3.190.0": |
745 | version "3.163.0" | 760 | version "3.190.0" |
746 | resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.163.0.tgz#6a083fd0fe285b07ca71fc88990c7a9440b7c0b2" | 761 | resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.190.0.tgz#ed5a408465723021648fd95440234898e114e2f6" |
747 | integrity sha512-1iein+7iAHKcRIXaZhl/lG6JrOR/Qmk27zMqfARzxDF7o/W5arSs3DHIKytO1sOEn9zV6Mqm21dRAumD21VCCg== | 762 | integrity sha512-L/R/1X2T+/Kg2k/sjoYyDFulVUGrVcRfyEKKVFIUNg0NwUtw5UKa1/gS7geTKcg4q8M2pd/v+OCBrge2X7phUw== |
748 | dependencies: | 763 | dependencies: |
749 | "@aws-sdk/is-array-buffer" "3.55.0" | 764 | "@aws-sdk/is-array-buffer" "3.188.0" |
750 | "@aws-sdk/types" "3.162.0" | 765 | "@aws-sdk/types" "3.190.0" |
751 | "@aws-sdk/util-hex-encoding" "3.109.0" | 766 | "@aws-sdk/util-hex-encoding" "3.188.0" |
752 | "@aws-sdk/util-middleware" "3.162.0" | 767 | "@aws-sdk/util-middleware" "3.190.0" |
753 | "@aws-sdk/util-uri-escape" "3.55.0" | 768 | "@aws-sdk/util-uri-escape" "3.188.0" |
754 | tslib "^2.3.1" | 769 | tslib "^2.3.1" |
755 | 770 | ||
756 | "@aws-sdk/smithy-client@3.162.0": | 771 | "@aws-sdk/smithy-client@3.190.0": |
757 | version "3.162.0" | 772 | version "3.190.0" |
758 | resolved "https://registry.yarnpkg.com/@aws-sdk/smithy-client/-/smithy-client-3.162.0.tgz#2646b05c287a609a1abb7d28a7009f3314c26803" | 773 | resolved "https://registry.yarnpkg.com/@aws-sdk/smithy-client/-/smithy-client-3.190.0.tgz#4a951a7f3470fe148330e3a3e68cf9020b148e64" |
759 | integrity sha512-o7CwdhPvzYMvHY5dTzL2kqN8Zsl2D8pZ1mG2dPdQW9hYnutLOFK1HVv5dIzoSkp3jUwVGh6AXd1i4ZSb2d0LrA== | 774 | integrity sha512-f5EoCwjBLXMyuN491u1NmEutbolL0cJegaJbtgK9OJw2BLuRHiBknjDF4OEVuK/WqK0kz2JLMGi9xwVPl4BKCA== |
760 | dependencies: | 775 | dependencies: |
761 | "@aws-sdk/middleware-stack" "3.162.0" | 776 | "@aws-sdk/middleware-stack" "3.190.0" |
762 | "@aws-sdk/types" "3.162.0" | 777 | "@aws-sdk/types" "3.190.0" |
763 | tslib "^2.3.1" | 778 | tslib "^2.3.1" |
764 | 779 | ||
765 | "@aws-sdk/types@3.162.0", "@aws-sdk/types@^3.1.0", "@aws-sdk/types@^3.110.0": | 780 | "@aws-sdk/types@3.190.0": |
781 | version "3.190.0" | ||
782 | resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.190.0.tgz#ef22549c81ea6a7dd2c57e5869e787fea40c4434" | ||
783 | integrity sha512-mkeZ+vJZzElP6OdRXvuLKWHSlDQxZP9u8BjQB9N0Rw0pCXTzYS0vzIhN1pL0uddWp5fMrIE68snto9xNR6BQuA== | ||
784 | |||
785 | "@aws-sdk/types@^3.1.0", "@aws-sdk/types@^3.110.0": | ||
766 | version "3.162.0" | 786 | version "3.162.0" |
767 | resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.162.0.tgz#e908ff1a5de6bd06d7d6b88a648b384592acf7e2" | 787 | resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.162.0.tgz#e908ff1a5de6bd06d7d6b88a648b384592acf7e2" |
768 | integrity sha512-NBmuwVujH8fURDMvBHkHrYu/JAfG6Js/Bu0mC4o2Kdo5mRa3fD/N9kK0dEAxU1Rxp4wY2E++V9j2ZCw1KBGrSg== | 788 | integrity sha512-NBmuwVujH8fURDMvBHkHrYu/JAfG6Js/Bu0mC4o2Kdo5mRa3fD/N9kK0dEAxU1Rxp4wY2E++V9j2ZCw1KBGrSg== |
769 | 789 | ||
770 | "@aws-sdk/url-parser@3.162.0": | 790 | "@aws-sdk/url-parser@3.190.0": |
771 | version "3.162.0" | 791 | version "3.190.0" |
772 | resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.162.0.tgz#ce341d3b6dbcaf52f00b80aff56b24b5ab8c1e82" | 792 | resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.190.0.tgz#d3c40dd0d01fb97c2c7f610baf1be2f045ae5582" |
773 | integrity sha512-aJQ2awXYDceLAzPMQETpvI1XQd8oYuqH1EriFzXHqoJTNmYnHb7awtKSqwaS8pq48x1rS/eVtJAi85BG93fXyw== | 793 | integrity sha512-FKFDtxA9pvHmpfWmNVK5BAVRpDgkWMz3u4Sg9UzB+WAFN6UexRypXXUZCFAo8S04FbPKfYOR3O0uVlw7kzmj9g== |
774 | dependencies: | 794 | dependencies: |
775 | "@aws-sdk/querystring-parser" "3.162.0" | 795 | "@aws-sdk/querystring-parser" "3.190.0" |
776 | "@aws-sdk/types" "3.162.0" | 796 | "@aws-sdk/types" "3.190.0" |
777 | tslib "^2.3.1" | 797 | tslib "^2.3.1" |
778 | 798 | ||
779 | "@aws-sdk/util-arn-parser@3.55.0": | 799 | "@aws-sdk/util-arn-parser@3.188.0": |
780 | version "3.55.0" | 800 | version "3.188.0" |
781 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.55.0.tgz#6672eb2975e798a460bedfaf6b5618d4e4b262e1" | 801 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.188.0.tgz#4df0144c00dce3490666da7d55e6e13c9a3f21b2" |
782 | integrity sha512-76KJxp4MRWufHYWys7DFl64znr5yeJ3AIQNAPCKKw1sP0hzO7p6Kx0PaJnw9x+CPSzOrT4NbuApL6/srYhKDGg== | 802 | integrity sha512-q4nZzt/g3sRY9a3sj1PaNFwql5bXfKSW4fRy0zLdbZHcYdgq2oQfVsJTIlL9lUNjifkXiIsmk61Q16JExtrLyw== |
783 | dependencies: | 803 | dependencies: |
784 | tslib "^2.3.1" | 804 | tslib "^2.3.1" |
785 | 805 | ||
786 | "@aws-sdk/util-base64-browser@3.109.0": | 806 | "@aws-sdk/util-base64-browser@3.188.0": |
787 | version "3.109.0" | 807 | version "3.188.0" |
788 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64-browser/-/util-base64-browser-3.109.0.tgz#e7faf5c4cbb88bc39b9c1c5a1a79e4c869e9f645" | 808 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64-browser/-/util-base64-browser-3.188.0.tgz#581c85dc157aff88ca81e42d9c79d87c95db8d03" |
789 | integrity sha512-lAZ6fyDGiRLaIsKT9qh7P9FGuNyZ4gAbr1YOSQk/5mHtaTuUvxlPptZuInNM/0MPQm6lpcot00D8IWTucn4PbA== | 809 | integrity sha512-qlH+5NZBLiyKziL335BEPedYxX6j+p7KFRWXvDQox9S+s+gLCayednpK+fteOhBenCcR9fUZOVuAPScy1I8qCg== |
790 | dependencies: | 810 | dependencies: |
791 | tslib "^2.3.1" | 811 | tslib "^2.3.1" |
792 | 812 | ||
793 | "@aws-sdk/util-base64-node@3.55.0": | 813 | "@aws-sdk/util-base64-node@3.188.0": |
794 | version "3.55.0" | 814 | version "3.188.0" |
795 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64-node/-/util-base64-node-3.55.0.tgz#da9a3fd6752be49163572144793e6b23d0186ff4" | 815 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64-node/-/util-base64-node-3.188.0.tgz#1d2413f68c8ad1cca0903fc11d92af88ba70e14d" |
796 | integrity sha512-UQ/ZuNoAc8CFMpSiRYmevaTsuRKzLwulZTnM8LNlIt9Wx1tpNvqp80cfvVj7yySKROtEi20wq29h31dZf1eYNQ== | 816 | integrity sha512-r1dccRsRjKq+OhVRUfqFiW3sGgZBjHbMeHLbrAs9jrOjU2PTQ8PSzAXLvX/9lmp7YjmX17Qvlsg0NCr1tbB9OA== |
797 | dependencies: | 817 | dependencies: |
798 | "@aws-sdk/util-buffer-from" "3.55.0" | 818 | "@aws-sdk/util-buffer-from" "3.188.0" |
799 | tslib "^2.3.1" | 819 | tslib "^2.3.1" |
800 | 820 | ||
801 | "@aws-sdk/util-body-length-browser@3.154.0": | 821 | "@aws-sdk/util-body-length-browser@3.188.0": |
802 | version "3.154.0" | 822 | version "3.188.0" |
803 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.154.0.tgz#8c4c5d08c1923deeedf46006dc4db820ca606f56" | 823 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.188.0.tgz#e1d949318c10a621b38575a9ef01e39f9857ddb0" |
804 | integrity sha512-TUuy7paVkBRQrB/XFCsL8iTW6g/ma0S3N8dYOiIMJdeTqTFryeyOGkBpYBgYFQL6zRMZpyu0jOM7GYEffGFOXw== | 824 | integrity sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg== |
805 | dependencies: | 825 | dependencies: |
806 | tslib "^2.3.1" | 826 | tslib "^2.3.1" |
807 | 827 | ||
808 | "@aws-sdk/util-body-length-node@3.55.0": | 828 | "@aws-sdk/util-body-length-node@3.188.0": |
809 | version "3.55.0" | 829 | version "3.188.0" |
810 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-node/-/util-body-length-node-3.55.0.tgz#67049bbb6c62d794a1bb5a13b9a678988c925489" | 830 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-node/-/util-body-length-node-3.188.0.tgz#3fc2a820b9be0efcbdf962d8f980b9000b98ddba" |
811 | integrity sha512-lU1d4I+9wJwydduXs0SxSfd+mHKjxeyd39VwOv6i2KSwWkPbji9UQqpflKLKw+r45jL7+xU/zfeTUg5Tt/3Gew== | 831 | integrity sha512-XwqP3vxk60MKp4YDdvDeCD6BPOiG2e+/Ou4AofZOy5/toB6NKz2pFNibQIUg2+jc7mPMnGnvOW3MQEgSJ+gu/Q== |
812 | dependencies: | 832 | dependencies: |
813 | tslib "^2.3.1" | 833 | tslib "^2.3.1" |
814 | 834 | ||
815 | "@aws-sdk/util-buffer-from@3.55.0": | 835 | "@aws-sdk/util-buffer-from@3.188.0": |
816 | version "3.55.0" | 836 | version "3.188.0" |
817 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-buffer-from/-/util-buffer-from-3.55.0.tgz#e7c927974b07a29502aa1ad58509b91d0d7cf0f7" | 837 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-buffer-from/-/util-buffer-from-3.188.0.tgz#a062ccd990571df4353990e8b78aebec5a14547d" |
818 | integrity sha512-uVzKG1UgvnV7XX2FPTylBujYMKBPBaq/qFBxfl0LVNfrty7YjpfieQxAe6yRLD+T0Kir/WDQwGvYC+tOYG3IGA== | 838 | integrity sha512-NX1WXZ8TH20IZb4jPFT2CnLKSqZWddGxtfiWxD9M47YOtq/SSQeR82fhqqVjJn4P8w2F5E28f+Du4ntg/sGcxA== |
819 | dependencies: | 839 | dependencies: |
820 | "@aws-sdk/is-array-buffer" "3.55.0" | 840 | "@aws-sdk/is-array-buffer" "3.188.0" |
821 | tslib "^2.3.1" | 841 | tslib "^2.3.1" |
822 | 842 | ||
823 | "@aws-sdk/util-config-provider@3.109.0": | 843 | "@aws-sdk/util-config-provider@3.188.0": |
824 | version "3.109.0" | 844 | version "3.188.0" |
825 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-config-provider/-/util-config-provider-3.109.0.tgz#7828b8894b2b23c289ffc5c106cbced7a5d6ee86" | 845 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-config-provider/-/util-config-provider-3.188.0.tgz#f7a365e6cbfe728c1224f0b39926636619b669e0" |
826 | integrity sha512-GrAZl/aBv0A28LkyNyq8SPJ5fmViCwz80fWLMeWx/6q5AbivuILogjlWwEZSvZ9zrlHOcFC0+AnCa5pQrjaslw== | 846 | integrity sha512-LBA7tLbi7v4uvbOJhSnjJrxbcRifKK/1ZVK94JTV2MNSCCyNkFotyEI5UWDl10YKriTIUyf7o5cakpiDZ3O4xg== |
827 | dependencies: | 847 | dependencies: |
828 | tslib "^2.3.1" | 848 | tslib "^2.3.1" |
829 | 849 | ||
830 | "@aws-sdk/util-defaults-mode-browser@3.162.0": | 850 | "@aws-sdk/util-defaults-mode-browser@3.190.0": |
831 | version "3.162.0" | 851 | version "3.190.0" |
832 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.162.0.tgz#41625d5ea4d3d347df00cc5647a0808fcb059c94" | 852 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.190.0.tgz#b544c978ae4e5a7cf12bb7975c0199dbe3517c85" |
833 | integrity sha512-BjhuriainNy0ezFqCK//380Wc4xsJJOnq1tmPlHScQxp3g8ucfClvjOUi96XQaTrEf8c8EsYp77+JNsvrHytmw== | 853 | integrity sha512-FKxTU4tIbFk2pdUbBNneStF++j+/pB4NYJ1HRSEAb/g4D2+kxikR/WKIv3p0JTVvAkwcuX/ausILYEPUyDZ4HQ== |
834 | dependencies: | 854 | dependencies: |
835 | "@aws-sdk/property-provider" "3.162.0" | 855 | "@aws-sdk/property-provider" "3.190.0" |
836 | "@aws-sdk/types" "3.162.0" | 856 | "@aws-sdk/types" "3.190.0" |
837 | bowser "^2.11.0" | 857 | bowser "^2.11.0" |
838 | tslib "^2.3.1" | 858 | tslib "^2.3.1" |
839 | 859 | ||
840 | "@aws-sdk/util-defaults-mode-node@3.163.0": | 860 | "@aws-sdk/util-defaults-mode-node@3.190.0": |
841 | version "3.163.0" | 861 | version "3.190.0" |
842 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.163.0.tgz#9cb4d5b0b1beb9573b11289eee46c762d3a9c0bd" | 862 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.190.0.tgz#67acd5a3dba7f30ac2fb30084dd2b9ff77612c15" |
843 | integrity sha512-IM5BVeUXzLpb9m8qBSpUc2iO+topP1F7Ojq1GNrl5G/b22f7b1FCL5qkTem/UIXkkgI+efI7jr05xPRGiU73Hg== | 863 | integrity sha512-qBiIMjNynqAP7p6urG1+ZattYkFaylhyinofVcLEiDvM9a6zGt6GZsxru2Loq0kRAXXGew9E9BWGt45HcDc20g== |
844 | dependencies: | 864 | dependencies: |
845 | "@aws-sdk/config-resolver" "3.163.0" | 865 | "@aws-sdk/config-resolver" "3.190.0" |
846 | "@aws-sdk/credential-provider-imds" "3.162.0" | 866 | "@aws-sdk/credential-provider-imds" "3.190.0" |
847 | "@aws-sdk/node-config-provider" "3.162.0" | 867 | "@aws-sdk/node-config-provider" "3.190.0" |
848 | "@aws-sdk/property-provider" "3.162.0" | 868 | "@aws-sdk/property-provider" "3.190.0" |
849 | "@aws-sdk/types" "3.162.0" | 869 | "@aws-sdk/types" "3.190.0" |
850 | tslib "^2.3.1" | 870 | tslib "^2.3.1" |
851 | 871 | ||
852 | "@aws-sdk/util-hex-encoding@3.109.0": | 872 | "@aws-sdk/util-hex-encoding@3.188.0": |
853 | version "3.109.0" | 873 | version "3.188.0" |
854 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.109.0.tgz#93b20acc27c0a1d7d80f653bf19d3dd01c2ccc65" | 874 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.188.0.tgz#c2d8b02b952db58acbd5f53718109657c69c460f" |
855 | integrity sha512-s8CgTNrn3cLkrdiohfxLuOYPCanzvHn/aH5RW6DaMoeQiG5Hl9QUiP/WtdQ9QQx3xvpQFpmvxIaSBwSgFNLQxA== | 875 | integrity sha512-QyWovTtjQ2RYxqVM+STPh65owSqzuXURnfoof778spyX4iQ4z46wOge1YV2ZtwS8w5LWd9eeVvDrLu5POPYOnA== |
856 | dependencies: | 876 | dependencies: |
857 | tslib "^2.3.1" | 877 | tslib "^2.3.1" |
858 | 878 | ||
@@ -863,88 +883,95 @@ | |||
863 | dependencies: | 883 | dependencies: |
864 | tslib "^2.3.1" | 884 | tslib "^2.3.1" |
865 | 885 | ||
866 | "@aws-sdk/util-middleware@3.162.0": | 886 | "@aws-sdk/util-middleware@3.190.0": |
867 | version "3.162.0" | 887 | version "3.190.0" |
868 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-middleware/-/util-middleware-3.162.0.tgz#5e38b45b52b731ec4be7b3eb65e8097e70a8a844" | 888 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-middleware/-/util-middleware-3.190.0.tgz#9c594987f107af05b770f2ac2e70c0391d0cb5b5" |
869 | integrity sha512-jDqZZ5nst+NtzvAPIQBdQqGY14Z3HeGANGm5NUoxWp8IlHnEV7GhTFDjFgubf8mgTBCzHnvbuBY1bfkzAeXWBA== | 889 | integrity sha512-qzTJ/qhFDzHZS+iXdHydQ/0sWAuNIB5feeLm55Io/I8Utv3l3TKYOhbgGwTsXY+jDk7oD+YnAi7hLN5oEBCwpg== |
870 | dependencies: | 890 | dependencies: |
871 | tslib "^2.3.1" | 891 | tslib "^2.3.1" |
872 | 892 | ||
873 | "@aws-sdk/util-stream-browser@3.162.0": | 893 | "@aws-sdk/util-stream-browser@3.190.0": |
874 | version "3.162.0" | 894 | version "3.190.0" |
875 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream-browser/-/util-stream-browser-3.162.0.tgz#9fbde6fee82bdef40b36f2529f99378f3899ec4e" | 895 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream-browser/-/util-stream-browser-3.190.0.tgz#ebb14f63dffe05a09a670cf14a307920d736c803" |
876 | integrity sha512-1GCOvu6bIQNo3ql/ULobztaJTGxUsWBIgSxftATU0vuCI1Rf4ReluENvpXzdbTEi6mv+k1YUrBBLVzSmFwwxrw== | 896 | integrity sha512-BqHUD+Bz780LM6lD2YLYsX1PZ+BqwkRYtSaw+ch8IvrnMWeAB1hzQWXRh+2NhMpe2IBw18IrrYB3kVmcyGgUtg== |
877 | dependencies: | 897 | dependencies: |
878 | "@aws-sdk/fetch-http-handler" "3.162.0" | 898 | "@aws-sdk/fetch-http-handler" "3.190.0" |
879 | "@aws-sdk/types" "3.162.0" | 899 | "@aws-sdk/types" "3.190.0" |
880 | "@aws-sdk/util-base64-browser" "3.109.0" | 900 | "@aws-sdk/util-base64-browser" "3.188.0" |
881 | "@aws-sdk/util-hex-encoding" "3.109.0" | 901 | "@aws-sdk/util-hex-encoding" "3.188.0" |
882 | "@aws-sdk/util-utf8-browser" "3.109.0" | 902 | "@aws-sdk/util-utf8-browser" "3.188.0" |
883 | tslib "^2.3.1" | 903 | tslib "^2.3.1" |
884 | 904 | ||
885 | "@aws-sdk/util-stream-node@3.162.0": | 905 | "@aws-sdk/util-stream-node@3.190.0": |
886 | version "3.162.0" | 906 | version "3.190.0" |
887 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream-node/-/util-stream-node-3.162.0.tgz#fcc6e8db77c1785033f3f120a2700affee304b7b" | 907 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream-node/-/util-stream-node-3.190.0.tgz#30f7a3a81e3ad379f9bbf60d197686ca6fa6138e" |
888 | integrity sha512-MWHF8HIsEdircxXb00/y+SesLugetGiU47xOVQtg40yWdoJyPWzP6kBK6+SWT8uR0r1IYdW7fwyxMbc9TccYcQ== | 908 | integrity sha512-RJ7iQB43fSfGW+aPhdT5LfG5GtbenB7q8mQLiTdIoj4Hw+gwa90JagMX+NxZv6DEkT4IgbT4q9liPQ48M83/YA== |
889 | dependencies: | 909 | dependencies: |
890 | "@aws-sdk/node-http-handler" "3.162.0" | 910 | "@aws-sdk/node-http-handler" "3.190.0" |
891 | "@aws-sdk/types" "3.162.0" | 911 | "@aws-sdk/types" "3.190.0" |
892 | "@aws-sdk/util-buffer-from" "3.55.0" | 912 | "@aws-sdk/util-buffer-from" "3.188.0" |
893 | tslib "^2.3.1" | 913 | tslib "^2.3.1" |
894 | 914 | ||
895 | "@aws-sdk/util-uri-escape@3.55.0": | 915 | "@aws-sdk/util-uri-escape@3.188.0": |
896 | version "3.55.0" | 916 | version "3.188.0" |
897 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-uri-escape/-/util-uri-escape-3.55.0.tgz#ee57743c628a1c9f942dfe73205ce890ec011916" | 917 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-uri-escape/-/util-uri-escape-3.188.0.tgz#6dbd4322f6cdc3252a75c6f729e1082369c468c0" |
898 | integrity sha512-mmdDLUpFCN2nkfwlLdOM54lTD528GiGSPN1qb8XtGLgZsJUmg3uJSFIN2lPeSbEwJB3NFjVas/rnQC48i7mV8w== | 918 | integrity sha512-4Y6AYZMT483Tiuq8dxz5WHIiPNdSFPGrl6tRTo2Oi2FcwypwmFhqgEGcqxeXDUJktvaCBxeA08DLr/AemVhPCg== |
899 | dependencies: | 919 | dependencies: |
900 | tslib "^2.3.1" | 920 | tslib "^2.3.1" |
901 | 921 | ||
902 | "@aws-sdk/util-user-agent-browser@3.162.0": | 922 | "@aws-sdk/util-user-agent-browser@3.190.0": |
903 | version "3.162.0" | 923 | version "3.190.0" |
904 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.162.0.tgz#735a3611e65df0c4b8a416bbb096e56d0b43f5c9" | 924 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.190.0.tgz#efb7eda04b94b260ae8e8ff5f623eeb9318f2bfd" |
905 | integrity sha512-FNmC2ywy1u3tbUSVCSkCwLvcbjIvj5EzAtF6I2wrMTI5PfaxVIQapKn2EecoVQgf4lsZqvGjyTxbl7SYvf9fxw== | 925 | integrity sha512-c074wjsD+/u9vT7DVrBLkwVhn28I+OEHuHaqpTVCvAIjpueZ3oms0e99YJLfpdpEgdLavOroAsNFtAuRrrTZZw== |
906 | dependencies: | 926 | dependencies: |
907 | "@aws-sdk/types" "3.162.0" | 927 | "@aws-sdk/types" "3.190.0" |
908 | bowser "^2.11.0" | 928 | bowser "^2.11.0" |
909 | tslib "^2.3.1" | 929 | tslib "^2.3.1" |
910 | 930 | ||
911 | "@aws-sdk/util-user-agent-node@3.162.0": | 931 | "@aws-sdk/util-user-agent-node@3.190.0": |
912 | version "3.162.0" | 932 | version "3.190.0" |
913 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.162.0.tgz#3c589c1ad1ce2821c9568dd12bb5632b8eb776be" | 933 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.190.0.tgz#b4bdc523d63ca418f5ca54e26f836db91fe55c43" |
914 | integrity sha512-OIbZlccBFwITDQJoymU0V+yqqyPEbJUExJzeiP9bxJ58h7Jxj/da24cxCMaVDYvjhP/PoflOmC5Xblonaeg+oQ== | 934 | integrity sha512-R36BMvvPX8frqFhU4lAsrOJ/2PJEHH/Jz1WZzO3GWmVSEAQQdHmo8tVPE3KOM7mZWe5Hj1dZudFAIxWHHFYKJA== |
915 | dependencies: | 935 | dependencies: |
916 | "@aws-sdk/node-config-provider" "3.162.0" | 936 | "@aws-sdk/node-config-provider" "3.190.0" |
917 | "@aws-sdk/types" "3.162.0" | 937 | "@aws-sdk/types" "3.190.0" |
918 | tslib "^2.3.1" | 938 | tslib "^2.3.1" |
919 | 939 | ||
920 | "@aws-sdk/util-utf8-browser@3.109.0", "@aws-sdk/util-utf8-browser@^3.0.0": | 940 | "@aws-sdk/util-utf8-browser@3.188.0": |
941 | version "3.188.0" | ||
942 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz#484762bd600401350e148277731d6744a4a92225" | ||
943 | integrity sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q== | ||
944 | dependencies: | ||
945 | tslib "^2.3.1" | ||
946 | |||
947 | "@aws-sdk/util-utf8-browser@^3.0.0": | ||
921 | version "3.109.0" | 948 | version "3.109.0" |
922 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.109.0.tgz#d013272e1981b23a4c84ac06f154db686c0cf84e" | 949 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.109.0.tgz#d013272e1981b23a4c84ac06f154db686c0cf84e" |
923 | integrity sha512-FmcGSz0v7Bqpl1SE8G1Gc0CtDpug+rvqNCG/szn86JApD/f5x8oByjbEiAyTU2ZH2VevUntx6EW68ulHyH+x+w== | 950 | integrity sha512-FmcGSz0v7Bqpl1SE8G1Gc0CtDpug+rvqNCG/szn86JApD/f5x8oByjbEiAyTU2ZH2VevUntx6EW68ulHyH+x+w== |
924 | dependencies: | 951 | dependencies: |
925 | tslib "^2.3.1" | 952 | tslib "^2.3.1" |
926 | 953 | ||
927 | "@aws-sdk/util-utf8-node@3.109.0": | 954 | "@aws-sdk/util-utf8-node@3.188.0": |
928 | version "3.109.0" | 955 | version "3.188.0" |
929 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-node/-/util-utf8-node-3.109.0.tgz#89e06d916f5b246c7265f59bac742973ac0767ac" | 956 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-node/-/util-utf8-node-3.188.0.tgz#935bc58a71f2792ac6a4ec881f72bf9ceee008b4" |
930 | integrity sha512-Ti/ZBdvz2eSTElsucjzNmzpyg2MwfD1rXmxD0hZuIF8bPON/0+sZYnWd5CbDw9kgmhy28dmKue086tbZ1G0iLQ== | 957 | integrity sha512-hCgP4+C0Lekjpjt2zFJ2R/iHes5sBGljXa5bScOFAEkRUc0Qw0VNgTv7LpEbIOAwGmqyxBoCwBW0YHPW1DfmYQ== |
931 | dependencies: | 958 | dependencies: |
932 | "@aws-sdk/util-buffer-from" "3.55.0" | 959 | "@aws-sdk/util-buffer-from" "3.188.0" |
933 | tslib "^2.3.1" | 960 | tslib "^2.3.1" |
934 | 961 | ||
935 | "@aws-sdk/util-waiter@3.162.0": | 962 | "@aws-sdk/util-waiter@3.190.0": |
936 | version "3.162.0" | 963 | version "3.190.0" |
937 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-waiter/-/util-waiter-3.162.0.tgz#369499ec934a47aa8f0340876a9228e6d8989736" | 964 | resolved "https://registry.yarnpkg.com/@aws-sdk/util-waiter/-/util-waiter-3.190.0.tgz#01348830fbd6a9a1a8e1fb22e87a29185d8e69fc" |
938 | integrity sha512-RDMimLdgffkBiFjXyGO0DYjUhDisBHx5OZIaj57bCWRqvMj4lSz5+eS3fpVEZaRDFo/P3i/86lvjPEqXStTlZA== | 965 | integrity sha512-wlc56EElap8ua+9VCSqXaC4QsJQecYmC0C6A5EfFDtFlFyyd+vjpiLMU34juzrqJfVCx6aAUD2c9f+ezvk1G5Q== |
939 | dependencies: | 966 | dependencies: |
940 | "@aws-sdk/abort-controller" "3.162.0" | 967 | "@aws-sdk/abort-controller" "3.190.0" |
941 | "@aws-sdk/types" "3.162.0" | 968 | "@aws-sdk/types" "3.190.0" |
942 | tslib "^2.3.1" | 969 | tslib "^2.3.1" |
943 | 970 | ||
944 | "@aws-sdk/xml-builder@3.142.0": | 971 | "@aws-sdk/xml-builder@3.188.0": |
945 | version "3.142.0" | 972 | version "3.188.0" |
946 | resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.142.0.tgz#55d03f1a1d1b3b02f07e26ec05d6855151f94c4e" | 973 | resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.188.0.tgz#d3f72f5e490be577670b6532343f5682e38ac000" |
947 | integrity sha512-e8rFjm5y9ngFc/cPwWMNn/CmMMrLx98CajWew9q7OzP6OOXQJ0H6TaRps2uQPM5XUv3/Ab5YQCV3NiaLJLqqNg== | 974 | integrity sha512-/Hah3gAtrBpEaDInX3eSS0nXw/IUeb+rWiGspXxb5O8bh5kyjQqeu8/sVJQlpOtq4aPDbMDmloH4k696qTqgbw== |
948 | dependencies: | 975 | dependencies: |
949 | tslib "^2.3.1" | 976 | tslib "^2.3.1" |
950 | 977 | ||
@@ -4145,7 +4172,7 @@ engine.io@~6.2.0: | |||
4145 | engine.io-parser "~5.0.3" | 4172 | engine.io-parser "~5.0.3" |
4146 | ws "~8.2.3" | 4173 | ws "~8.2.3" |
4147 | 4174 | ||
4148 | entities@2.2.0, entities@^2.0.0: | 4175 | entities@^2.0.0: |
4149 | version "2.2.0" | 4176 | version "2.2.0" |
4150 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" | 4177 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" |
4151 | integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== | 4178 | integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== |
@@ -4748,10 +4775,12 @@ fast-safe-stringify@^2.1.1: | |||
4748 | resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" | 4775 | resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" |
4749 | integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== | 4776 | integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== |
4750 | 4777 | ||
4751 | fast-xml-parser@3.19.0: | 4778 | fast-xml-parser@4.0.11: |
4752 | version "3.19.0" | 4779 | version "4.0.11" |
4753 | resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01" | 4780 | resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz#42332a9aca544520631c8919e6ea871c0185a985" |
4754 | integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg== | 4781 | integrity sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA== |
4782 | dependencies: | ||
4783 | strnum "^1.0.5" | ||
4755 | 4784 | ||
4756 | fast-xml-parser@^4.0.0-beta.8: | 4785 | fast-xml-parser@^4.0.0-beta.8: |
4757 | version "4.0.9" | 4786 | version "4.0.9" |