@webiny/api-file-manager-s3 5.42.0 → 5.42.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,2 @@
1
- import { createAssetDelivery as createBaseAssetDelivery } from "@webiny/api-file-manager";
2
- export type AssetDeliveryParams = Parameters<typeof createBaseAssetDelivery>[0] & {
3
- imageResizeWidths?: number[];
4
- /**
5
- * BE CAREFUL!
6
- * Setting this to more than 1 hour may cause your URLs to still expire before the desired expiration time.
7
- * @see https://repost.aws/knowledge-center/presigned-url-s3-bucket-expiration
8
- */
9
- presignedUrlTtl?: number;
10
- assetStreamingMaxSize?: number;
11
- };
1
+ import type { AssetDeliveryParams } from "./types";
12
2
  export declare const assetDeliveryConfig: (params: AssetDeliveryParams) => (import("@webiny/api-file-manager").AssetDeliveryConfigModifierPlugin | (import("@webiny/api-file-manager").AssetDeliveryConfigModifierPlugin | import("@webiny/handler").ModifyFastifyPlugin)[])[];
@@ -1 +1 @@
1
- {"version":3,"names":["_apiFileManager","require","_clientS","_S3AssetResolver","_S3OutputStrategy","_SharpTransform","assetDeliveryConfig","params","bucket","process","env","S3_BUCKET","region","AWS_REGION","presignedUrlTtl","imageResizeWidths","assetStreamingMaxSize","baseParams","createBaseAssetDelivery","createAssetDeliveryConfig","config","s3","S3","decorateAssetResolver","S3AssetResolver","decorateAssetOutputStrategy","S3OutputStrategy","decorateAssetTransformationStrategy","SharpTransform","exports"],"sources":["assetDeliveryConfig.ts"],"sourcesContent":["import {\n createAssetDelivery as createBaseAssetDelivery,\n createAssetDeliveryConfig\n} from \"@webiny/api-file-manager\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { S3AssetResolver } from \"~/assetDelivery/s3/S3AssetResolver\";\nimport { S3OutputStrategy } from \"~/assetDelivery/s3/S3OutputStrategy\";\nimport { SharpTransform } from \"~/assetDelivery/s3/SharpTransform\";\n\nexport type AssetDeliveryParams = Parameters<typeof createBaseAssetDelivery>[0] & {\n imageResizeWidths?: number[];\n /**\n * BE CAREFUL!\n * Setting this to more than 1 hour may cause your URLs to still expire before the desired expiration time.\n * @see https://repost.aws/knowledge-center/presigned-url-s3-bucket-expiration\n */\n presignedUrlTtl?: number;\n assetStreamingMaxSize?: number;\n};\n\nexport const assetDeliveryConfig = (params: AssetDeliveryParams) => {\n const bucket = process.env.S3_BUCKET as string;\n const region = process.env.AWS_REGION as string;\n\n const {\n // Presigned URLs last 1 hour\n presignedUrlTtl = 3600,\n imageResizeWidths = [100, 300, 500, 750, 1000, 1500, 2500],\n /**\n * Even though Lambda's response payload limit is 6,291,556 bytes, we leave some room for the response envelope.\n * We had situations where a 4.7MB file would cause the payload to go over the limit, so let's be on the safe side.\n */\n assetStreamingMaxSize = 4718592,\n ...baseParams\n } = params;\n\n return [\n // Base asset delivery\n createBaseAssetDelivery(baseParams),\n // S3 plugins\n createAssetDeliveryConfig(config => {\n const s3 = new S3({ region });\n\n config.decorateAssetResolver(() => {\n // This resolver loads file information from the `.metadata` file.\n return new S3AssetResolver(s3, bucket);\n });\n\n config.decorateAssetOutputStrategy(() => {\n return new S3OutputStrategy(s3, bucket, presignedUrlTtl, assetStreamingMaxSize);\n });\n\n config.decorateAssetTransformationStrategy(() => {\n return new SharpTransform({ s3, bucket, imageResizeWidths });\n });\n })\n ];\n};\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAIA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,gBAAA,GAAAF,OAAA;AACA,IAAAG,iBAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AAaO,MAAMK,mBAAmB,GAAIC,MAA2B,IAAK;EAChE,MAAMC,MAAM,GAAGC,OAAO,CAACC,GAAG,CAACC,SAAmB;EAC9C,MAAMC,MAAM,GAAGH,OAAO,CAACC,GAAG,CAACG,UAAoB;EAE/C,MAAM;IACF;IACAC,eAAe,GAAG,IAAI;IACtBC,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC1D;AACR;AACA;AACA;IACQC,qBAAqB,GAAG,OAAO;IAC/B,GAAGC;EACP,CAAC,GAAGV,MAAM;EAEV,OAAO;EACH;EACA,IAAAW,mCAAuB,EAACD,UAAU,CAAC;EACnC;EACA,IAAAE,yCAAyB,EAACC,MAAM,IAAI;IAChC,MAAMC,EAAE,GAAG,IAAIC,WAAE,CAAC;MAAEV;IAAO,CAAC,CAAC;IAE7BQ,MAAM,CAACG,qBAAqB,CAAC,MAAM;MAC/B;MACA,OAAO,IAAIC,gCAAe,CAACH,EAAE,EAAEb,MAAM,CAAC;IAC1C,CAAC,CAAC;IAEFY,MAAM,CAACK,2BAA2B,CAAC,MAAM;MACrC,OAAO,IAAIC,kCAAgB,CAACL,EAAE,EAAEb,MAAM,EAAEM,eAAe,EAAEE,qBAAqB,CAAC;IACnF,CAAC,CAAC;IAEFI,MAAM,CAACO,mCAAmC,CAAC,MAAM;MAC7C,OAAO,IAAIC,8BAAc,CAAC;QAAEP,EAAE;QAAEb,MAAM;QAAEO;MAAkB,CAAC,CAAC;IAChE,CAAC,CAAC;EACN,CAAC,CAAC,CACL;AACL,CAAC;AAACc,OAAA,CAAAvB,mBAAA,GAAAA,mBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_apiFileManager","require","_clientS","_S3AssetResolver","_S3OutputStrategy","_SharpTransform","assetDeliveryConfig","params","bucket","process","env","S3_BUCKET","region","AWS_REGION","presignedUrlTtl","imageResizeWidths","assetStreamingMaxSize","baseParams","createBaseAssetDelivery","createAssetDeliveryConfig","config","s3","S3","decorateAssetResolver","S3AssetResolver","decorateAssetOutputStrategy","S3OutputStrategy","decorateAssetTransformationStrategy","SharpTransform","exports"],"sources":["assetDeliveryConfig.ts"],"sourcesContent":["import {\n createAssetDelivery as createBaseAssetDelivery,\n createAssetDeliveryConfig\n} from \"@webiny/api-file-manager\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { S3AssetResolver } from \"~/assetDelivery/s3/S3AssetResolver\";\nimport { S3OutputStrategy } from \"~/assetDelivery/s3/S3OutputStrategy\";\nimport { SharpTransform } from \"~/assetDelivery/s3/SharpTransform\";\nimport type { AssetDeliveryParams } from \"~/assetDelivery/types\";\n\nexport const assetDeliveryConfig = (params: AssetDeliveryParams) => {\n const bucket = process.env.S3_BUCKET as string;\n const region = process.env.AWS_REGION as string;\n\n const {\n // Presigned URLs last 1 hour\n presignedUrlTtl = 3600,\n imageResizeWidths = [100, 300, 500, 750, 1000, 1500, 2500],\n /**\n * Even though Lambda's response payload limit is 6,291,556 bytes, we leave some room for the response envelope.\n * We had situations where a 4.7MB file would cause the payload to go over the limit, so let's be on the safe side.\n */\n assetStreamingMaxSize = 4718592,\n ...baseParams\n } = params;\n\n return [\n // Base asset delivery\n createBaseAssetDelivery(baseParams),\n // S3 plugins\n createAssetDeliveryConfig(config => {\n const s3 = new S3({ region });\n\n config.decorateAssetResolver(() => {\n // This resolver loads file information from the `.metadata` file.\n return new S3AssetResolver(s3, bucket);\n });\n\n config.decorateAssetOutputStrategy(() => {\n return new S3OutputStrategy(s3, bucket, presignedUrlTtl, assetStreamingMaxSize);\n });\n\n config.decorateAssetTransformationStrategy(() => {\n return new SharpTransform({ s3, bucket, imageResizeWidths });\n });\n })\n ];\n};\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAIA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,gBAAA,GAAAF,OAAA;AACA,IAAAG,iBAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AAGO,MAAMK,mBAAmB,GAAIC,MAA2B,IAAK;EAChE,MAAMC,MAAM,GAAGC,OAAO,CAACC,GAAG,CAACC,SAAmB;EAC9C,MAAMC,MAAM,GAAGH,OAAO,CAACC,GAAG,CAACG,UAAoB;EAE/C,MAAM;IACF;IACAC,eAAe,GAAG,IAAI;IACtBC,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC1D;AACR;AACA;AACA;IACQC,qBAAqB,GAAG,OAAO;IAC/B,GAAGC;EACP,CAAC,GAAGV,MAAM;EAEV,OAAO;EACH;EACA,IAAAW,mCAAuB,EAACD,UAAU,CAAC;EACnC;EACA,IAAAE,yCAAyB,EAACC,MAAM,IAAI;IAChC,MAAMC,EAAE,GAAG,IAAIC,WAAE,CAAC;MAAEV;IAAO,CAAC,CAAC;IAE7BQ,MAAM,CAACG,qBAAqB,CAAC,MAAM;MAC/B;MACA,OAAO,IAAIC,gCAAe,CAACH,EAAE,EAAEb,MAAM,CAAC;IAC1C,CAAC,CAAC;IAEFY,MAAM,CAACK,2BAA2B,CAAC,MAAM;MACrC,OAAO,IAAIC,kCAAgB,CAACL,EAAE,EAAEb,MAAM,EAAEM,eAAe,EAAEE,qBAAqB,CAAC;IACnF,CAAC,CAAC;IAEFI,MAAM,CAACO,mCAAmC,CAAC,MAAM;MAC7C,OAAO,IAAIC,8BAAc,CAAC;QAAEP,EAAE;QAAEb,MAAM;QAAEO;MAAkB,CAAC,CAAC;IAChE,CAAC,CAAC;EACN,CAAC,CAAC,CACL;AACL,CAAC;AAACc,OAAA,CAAAvB,mBAAA,GAAAA,mBAAA","ignoreList":[]}
@@ -1,3 +1,3 @@
1
1
  import { PluginFactory } from "@webiny/plugins/types";
2
- import type { AssetDeliveryParams } from "./assetDeliveryConfig";
3
- export declare const createAssetDelivery: (params: AssetDeliveryParams) => PluginFactory;
2
+ import type { AssetDeliveryParams } from "./types";
3
+ export declare const createAssetDelivery: (params: AssetDeliveryParams) => PluginFactory[];
@@ -5,15 +5,25 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createAssetDelivery = void 0;
7
7
  var _apiFileManager = require("@webiny/api-file-manager");
8
+ var _threatDetection = require("./threatDetection");
8
9
  const createAssetDelivery = params => {
10
+ return [
9
11
  /**
10
12
  * We only want to load this plugin in the context of the Asset Delivery Lambda function.
11
13
  */
12
- return (0, _apiFileManager.createAssetDeliveryPluginLoader)(() => {
14
+ (0, _apiFileManager.createAssetDeliveryPluginLoader)(() => {
13
15
  return import(/* webpackChunkName: "s3AssetDelivery" */"./assetDeliveryConfig").then(({
14
16
  assetDeliveryConfig
15
17
  }) => assetDeliveryConfig(params));
16
- });
18
+ }),
19
+ /**
20
+ * We only want to load this plugin in the context of the Threat Detection Lambda function.
21
+ */
22
+ (0, _threatDetection.createThreatDetectionPluginLoader)(() => {
23
+ return import(/* webpackChunkName: "threatDetectionEventHandler" */"./threatDetection/createThreatDetectionEventHandler").then(({
24
+ createThreatDetectionEventHandler
25
+ }) => createThreatDetectionEventHandler());
26
+ })];
17
27
  };
18
28
  exports.createAssetDelivery = createAssetDelivery;
19
29
 
@@ -1 +1 @@
1
- {"version":3,"names":["_apiFileManager","require","createAssetDelivery","params","createAssetDeliveryPluginLoader","then","assetDeliveryConfig","exports"],"sources":["createAssetDelivery.ts"],"sourcesContent":["import { createAssetDeliveryPluginLoader } from \"@webiny/api-file-manager\";\nimport { PluginFactory } from \"@webiny/plugins/types\";\nimport type { AssetDeliveryParams } from \"./assetDeliveryConfig\";\n\nexport const createAssetDelivery = (params: AssetDeliveryParams): PluginFactory => {\n /**\n * We only want to load this plugin in the context of the Asset Delivery Lambda function.\n */\n return createAssetDeliveryPluginLoader(() => {\n return import(/* webpackChunkName: \"s3AssetDelivery\" */ \"./assetDeliveryConfig\").then(\n ({ assetDeliveryConfig }) => assetDeliveryConfig(params)\n );\n });\n};\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAIO,MAAMC,mBAAmB,GAAIC,MAA2B,IAAoB;EAC/E;AACJ;AACA;EACI,OAAO,IAAAC,+CAA+B,EAAC,MAAM;IACzC,OAAO,MAAM,CAAC,gEAAiE,CAAC,CAACC,IAAI,CACjF,CAAC;MAAEC;IAAoB,CAAC,KAAKA,mBAAmB,CAACH,MAAM,CAC3D,CAAC;EACL,CAAC,CAAC;AACN,CAAC;AAACI,OAAA,CAAAL,mBAAA,GAAAA,mBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_apiFileManager","require","_threatDetection","createAssetDelivery","params","createAssetDeliveryPluginLoader","then","assetDeliveryConfig","createThreatDetectionPluginLoader","createThreatDetectionEventHandler","exports"],"sources":["createAssetDelivery.ts"],"sourcesContent":["import { createAssetDeliveryPluginLoader } from \"@webiny/api-file-manager\";\nimport { PluginFactory } from \"@webiny/plugins/types\";\nimport { createThreatDetectionPluginLoader } from \"~/assetDelivery/threatDetection\";\nimport type { AssetDeliveryParams } from \"~/assetDelivery/types\";\n\nexport const createAssetDelivery = (params: AssetDeliveryParams): PluginFactory[] => {\n return [\n /**\n * We only want to load this plugin in the context of the Asset Delivery Lambda function.\n */\n createAssetDeliveryPluginLoader(() => {\n return import(/* webpackChunkName: \"s3AssetDelivery\" */ \"./assetDeliveryConfig\").then(\n ({ assetDeliveryConfig }) => assetDeliveryConfig(params)\n );\n }),\n /**\n * We only want to load this plugin in the context of the Threat Detection Lambda function.\n */\n createThreatDetectionPluginLoader(() => {\n return import(\n /* webpackChunkName: \"threatDetectionEventHandler\" */ \"./threatDetection/createThreatDetectionEventHandler\"\n ).then(({ createThreatDetectionEventHandler }) => createThreatDetectionEventHandler());\n })\n ];\n};\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAEA,IAAAC,gBAAA,GAAAD,OAAA;AAGO,MAAME,mBAAmB,GAAIC,MAA2B,IAAsB;EACjF,OAAO;EACH;AACR;AACA;EACQ,IAAAC,+CAA+B,EAAC,MAAM;IAClC,OAAO,MAAM,CAAC,gEAAiE,CAAC,CAACC,IAAI,CACjF,CAAC;MAAEC;IAAoB,CAAC,KAAKA,mBAAmB,CAACH,MAAM,CAC3D,CAAC;EACL,CAAC,CAAC;EACF;AACR;AACA;EACQ,IAAAI,kDAAiC,EAAC,MAAM;IACpC,OAAO,MAAM,CACT,0GACJ,CAAC,CAACF,IAAI,CAAC,CAAC;MAAEG;IAAkC,CAAC,KAAKA,iCAAiC,CAAC,CAAC,CAAC;EAC1F,CAAC,CAAC,CACL;AACL,CAAC;AAACC,OAAA,CAAAP,mBAAA,GAAAA,mBAAA","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import { GuardDutyEvent } from "./types";
2
+ export declare const createThreatDetectionEventHandler: () => (import("@webiny/handler").HandlerOnRequestPlugin | import("@webiny/handler-aws").EventBridgeEventHandler<"GuardDuty Malware Protection Object Scan Result", GuardDutyEvent, any>)[];
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createThreatDetectionEventHandler = void 0;
7
+ var _clientS = require("@webiny/aws-sdk/client-s3");
8
+ var _handlerAws = require("@webiny/handler-aws");
9
+ var _handler = require("@webiny/handler");
10
+ var _processThreatScanResult = require("./processThreatScanResult");
11
+ var _S3AssetMetadataReader = require("../s3/S3AssetMetadataReader");
12
+ const detailType = "GuardDuty Malware Protection Object Scan Result";
13
+ const bucket = process.env.S3_BUCKET;
14
+ const region = process.env.AWS_REGION;
15
+ const createThreatDetectionEventHandler = () => {
16
+ const s3 = new _clientS.S3({
17
+ region
18
+ });
19
+ const handlerOnRequest = (0, _handler.createHandlerOnRequest)(async request => {
20
+ const payload = request.body;
21
+ if (payload["detail-type"] !== detailType) {
22
+ return;
23
+ }
24
+ const objectKey = payload.detail.s3ObjectDetails.objectKey;
25
+ if (objectKey.endsWith(".metadata")) {
26
+ return;
27
+ }
28
+ try {
29
+ const s3Metadata = new _S3AssetMetadataReader.S3AssetMetadataReader(s3, bucket);
30
+ const metadata = await s3Metadata.getMetadata(payload.detail.s3ObjectDetails.objectKey);
31
+ request.headers = {
32
+ ...request.headers,
33
+ "x-tenant": metadata.tenant,
34
+ "x-i18n-locale": `default:${metadata.locale};content:${metadata.locale};`
35
+ };
36
+ } catch {
37
+ // If metadata can't be loaded, we ignore the file.
38
+ // Most likely it's because the file is a rendition of the original file,
39
+ // so we don't need to do anything with it.
40
+ }
41
+ });
42
+ // Guard Duty event handler.
43
+ const threatScanEventHandler = (0, _handlerAws.createEventBridgeEventHandler)(async ({
44
+ payload,
45
+ next,
46
+ ...rest
47
+ }) => {
48
+ const context = rest.context;
49
+ const threatDetectionEnabled = context.wcp.canUseFileManagerThreatDetection();
50
+ if (!threatDetectionEnabled || payload["detail-type"] !== detailType) {
51
+ return next();
52
+ }
53
+ await (0, _processThreatScanResult.processThreatScanResult)(context, payload.detail);
54
+ });
55
+
56
+ // Assign a human-readable name for easier debugging.
57
+ threatScanEventHandler.name = threatScanEventHandler.type + ".threatDetectionEventHandler";
58
+ return [handlerOnRequest, threatScanEventHandler];
59
+ };
60
+ exports.createThreatDetectionEventHandler = createThreatDetectionEventHandler;
61
+
62
+ //# sourceMappingURL=createThreatDetectionEventHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_clientS","require","_handlerAws","_handler","_processThreatScanResult","_S3AssetMetadataReader","detailType","bucket","process","env","S3_BUCKET","region","AWS_REGION","createThreatDetectionEventHandler","s3","S3","handlerOnRequest","createHandlerOnRequest","request","payload","body","objectKey","detail","s3ObjectDetails","endsWith","s3Metadata","S3AssetMetadataReader","metadata","getMetadata","headers","tenant","locale","threatScanEventHandler","createEventBridgeEventHandler","next","rest","context","threatDetectionEnabled","wcp","canUseFileManagerThreatDetection","processThreatScanResult","name","type","exports"],"sources":["createThreatDetectionEventHandler.ts"],"sourcesContent":["import { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { createEventBridgeEventHandler } from \"@webiny/handler-aws\";\nimport { createHandlerOnRequest } from \"@webiny/handler\";\nimport { GuardDutyEvent, ThreatDetectionContext } from \"./types\";\nimport { processThreatScanResult } from \"./processThreatScanResult\";\nimport { S3AssetMetadataReader } from \"~/assetDelivery/s3/S3AssetMetadataReader\";\nimport { EventBridgeEvent } from \"@webiny/aws-sdk/types\";\n\nconst detailType = \"GuardDuty Malware Protection Object Scan Result\";\n\nconst bucket = process.env.S3_BUCKET as string;\nconst region = process.env.AWS_REGION as string;\n\nexport const createThreatDetectionEventHandler = () => {\n const s3 = new S3({ region });\n\n const handlerOnRequest = createHandlerOnRequest(async request => {\n const payload = request.body as EventBridgeEvent<string, GuardDutyEvent>;\n\n if (payload[\"detail-type\"] !== detailType) {\n return;\n }\n\n const objectKey = payload.detail.s3ObjectDetails.objectKey;\n if (objectKey.endsWith(\".metadata\")) {\n return;\n }\n\n try {\n const s3Metadata = new S3AssetMetadataReader(s3, bucket);\n const metadata = await s3Metadata.getMetadata(payload.detail.s3ObjectDetails.objectKey);\n\n request.headers = {\n ...request.headers,\n \"x-tenant\": metadata.tenant,\n \"x-i18n-locale\": `default:${metadata.locale};content:${metadata.locale};`\n };\n } catch {\n // If metadata can't be loaded, we ignore the file.\n // Most likely it's because the file is a rendition of the original file,\n // so we don't need to do anything with it.\n }\n });\n // Guard Duty event handler.\n const threatScanEventHandler = createEventBridgeEventHandler<typeof detailType, GuardDutyEvent>(\n async ({ payload, next, ...rest }) => {\n const context = rest.context as ThreatDetectionContext;\n\n const threatDetectionEnabled = context.wcp.canUseFileManagerThreatDetection();\n\n if (!threatDetectionEnabled || payload[\"detail-type\"] !== detailType) {\n return next();\n }\n\n await processThreatScanResult(context, payload.detail);\n }\n );\n\n // Assign a human-readable name for easier debugging.\n threatScanEventHandler.name = threatScanEventHandler.type + \".threatDetectionEventHandler\";\n\n return [handlerOnRequest, threatScanEventHandler];\n};\n"],"mappings":";;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,QAAA,GAAAF,OAAA;AAEA,IAAAG,wBAAA,GAAAH,OAAA;AACA,IAAAI,sBAAA,GAAAJ,OAAA;AAGA,MAAMK,UAAU,GAAG,iDAAiD;AAEpE,MAAMC,MAAM,GAAGC,OAAO,CAACC,GAAG,CAACC,SAAmB;AAC9C,MAAMC,MAAM,GAAGH,OAAO,CAACC,GAAG,CAACG,UAAoB;AAExC,MAAMC,iCAAiC,GAAGA,CAAA,KAAM;EACnD,MAAMC,EAAE,GAAG,IAAIC,WAAE,CAAC;IAAEJ;EAAO,CAAC,CAAC;EAE7B,MAAMK,gBAAgB,GAAG,IAAAC,+BAAsB,EAAC,MAAMC,OAAO,IAAI;IAC7D,MAAMC,OAAO,GAAGD,OAAO,CAACE,IAAgD;IAExE,IAAID,OAAO,CAAC,aAAa,CAAC,KAAKb,UAAU,EAAE;MACvC;IACJ;IAEA,MAAMe,SAAS,GAAGF,OAAO,CAACG,MAAM,CAACC,eAAe,CAACF,SAAS;IAC1D,IAAIA,SAAS,CAACG,QAAQ,CAAC,WAAW,CAAC,EAAE;MACjC;IACJ;IAEA,IAAI;MACA,MAAMC,UAAU,GAAG,IAAIC,4CAAqB,CAACZ,EAAE,EAAEP,MAAM,CAAC;MACxD,MAAMoB,QAAQ,GAAG,MAAMF,UAAU,CAACG,WAAW,CAACT,OAAO,CAACG,MAAM,CAACC,eAAe,CAACF,SAAS,CAAC;MAEvFH,OAAO,CAACW,OAAO,GAAG;QACd,GAAGX,OAAO,CAACW,OAAO;QAClB,UAAU,EAAEF,QAAQ,CAACG,MAAM;QAC3B,eAAe,EAAE,WAAWH,QAAQ,CAACI,MAAM,YAAYJ,QAAQ,CAACI,MAAM;MAC1E,CAAC;IACL,CAAC,CAAC,MAAM;MACJ;MACA;MACA;IAAA;EAER,CAAC,CAAC;EACF;EACA,MAAMC,sBAAsB,GAAG,IAAAC,yCAA6B,EACxD,OAAO;IAAEd,OAAO;IAAEe,IAAI;IAAE,GAAGC;EAAK,CAAC,KAAK;IAClC,MAAMC,OAAO,GAAGD,IAAI,CAACC,OAAiC;IAEtD,MAAMC,sBAAsB,GAAGD,OAAO,CAACE,GAAG,CAACC,gCAAgC,CAAC,CAAC;IAE7E,IAAI,CAACF,sBAAsB,IAAIlB,OAAO,CAAC,aAAa,CAAC,KAAKb,UAAU,EAAE;MAClE,OAAO4B,IAAI,CAAC,CAAC;IACjB;IAEA,MAAM,IAAAM,gDAAuB,EAACJ,OAAO,EAAEjB,OAAO,CAACG,MAAM,CAAC;EAC1D,CACJ,CAAC;;EAED;EACAU,sBAAsB,CAACS,IAAI,GAAGT,sBAAsB,CAACU,IAAI,GAAG,8BAA8B;EAE1F,OAAO,CAAC1B,gBAAgB,EAAEgB,sBAAsB,CAAC;AACrD,CAAC;AAACW,OAAA,CAAA9B,iCAAA,GAAAA,iCAAA","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import { PluginFactory } from "@webiny/plugins/types";
2
+ export declare const createThreatDetectionPluginLoader: (cb: PluginFactory) => PluginFactory;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createThreatDetectionPluginLoader = void 0;
7
+ var _api = require("@webiny/api");
8
+ const createThreatDetectionPluginLoader = cb => {
9
+ return (0, _api.createConditionalPluginFactory)(() => process.env.WEBINY_FUNCTION_TYPE === "threat-detection-event-handler", cb);
10
+ };
11
+ exports.createThreatDetectionPluginLoader = createThreatDetectionPluginLoader;
12
+
13
+ //# sourceMappingURL=createThreatDetectionPluginLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_api","require","createThreatDetectionPluginLoader","cb","createConditionalPluginFactory","process","env","WEBINY_FUNCTION_TYPE","exports"],"sources":["createThreatDetectionPluginLoader.ts"],"sourcesContent":["import { PluginFactory } from \"@webiny/plugins/types\";\nimport { createConditionalPluginFactory } from \"@webiny/api\";\n\nexport const createThreatDetectionPluginLoader = (cb: PluginFactory) => {\n return createConditionalPluginFactory(\n () => process.env.WEBINY_FUNCTION_TYPE === \"threat-detection-event-handler\",\n cb\n );\n};\n"],"mappings":";;;;;;AACA,IAAAA,IAAA,GAAAC,OAAA;AAEO,MAAMC,iCAAiC,GAAIC,EAAiB,IAAK;EACpE,OAAO,IAAAC,mCAA8B,EACjC,MAAMC,OAAO,CAACC,GAAG,CAACC,oBAAoB,KAAK,gCAAgC,EAC3EJ,EACJ,CAAC;AACL,CAAC;AAACK,OAAA,CAAAN,iCAAA,GAAAA,iCAAA","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export * from "./createThreatDetectionEventHandler";
2
+ export * from "./createThreatDetectionPluginLoader";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _createThreatDetectionEventHandler = require("./createThreatDetectionEventHandler");
7
+ Object.keys(_createThreatDetectionEventHandler).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _createThreatDetectionEventHandler[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _createThreatDetectionEventHandler[key];
14
+ }
15
+ });
16
+ });
17
+ var _createThreatDetectionPluginLoader = require("./createThreatDetectionPluginLoader");
18
+ Object.keys(_createThreatDetectionPluginLoader).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _createThreatDetectionPluginLoader[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _createThreatDetectionPluginLoader[key];
25
+ }
26
+ });
27
+ });
28
+
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_createThreatDetectionEventHandler","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_createThreatDetectionPluginLoader"],"sources":["index.ts"],"sourcesContent":["export * from \"./createThreatDetectionEventHandler\";\nexport * from \"./createThreatDetectionPluginLoader\";\n"],"mappings":";;;;;AAAA,IAAAA,kCAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,kCAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,kCAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,kCAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,kCAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,kCAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,kCAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,kCAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import { GuardDutyEvent, ThreatDetectionContext } from "./types";
2
+ export declare const processThreatScanResult: (context: ThreatDetectionContext, eventDetail: GuardDutyEvent) => Promise<void>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.processThreatScanResult = void 0;
7
+ const processThreatScanResult = async (context, eventDetail) => {
8
+ await context.security.withoutAuthorization(async () => {
9
+ try {
10
+ const scanStatus = eventDetail.scanResultDetails.scanResultStatus;
11
+ const s3Object = eventDetail.s3ObjectDetails;
12
+ const [[file]] = await context.fileManager.listFiles({
13
+ limit: 1,
14
+ where: {
15
+ key: s3Object.objectKey
16
+ }
17
+ });
18
+ if (!file) {
19
+ return;
20
+ }
21
+ const allConnections = await context.websockets.listConnections();
22
+ if (scanStatus === "NO_THREATS_FOUND") {
23
+ const newTags = file.tags.filter(tag => tag !== "threatScanInProgress");
24
+ await context.fileManager.updateFile(file.id, {
25
+ tags: newTags,
26
+ savedBy: file.savedBy
27
+ });
28
+ await context.websockets.sendToConnections(allConnections, {
29
+ action: "fm.threatScan.noThreatFound",
30
+ data: {
31
+ id: file.id,
32
+ tags: newTags
33
+ }
34
+ });
35
+ return;
36
+ }
37
+ if (scanStatus === "THREATS_FOUND") {
38
+ // Delete infected file.
39
+ await context.fileManager.deleteFile(file.id);
40
+ await context.websockets.sendToConnections(allConnections, {
41
+ action: "fm.threatScan.threatDetected",
42
+ data: {
43
+ id: file.id,
44
+ name: file.name
45
+ }
46
+ });
47
+ return;
48
+ }
49
+
50
+ // For all other outcomes, we delete the file, until better logic is implemented.
51
+ await context.fileManager.deleteFile(file.id);
52
+ await context.websockets.sendToConnections(allConnections, {
53
+ action: "fm.threatScan.unsupported",
54
+ data: {
55
+ id: file.id,
56
+ name: file.name
57
+ }
58
+ });
59
+ } catch (e) {
60
+ console.log(e.message);
61
+ }
62
+ });
63
+ };
64
+ exports.processThreatScanResult = processThreatScanResult;
65
+
66
+ //# sourceMappingURL=processThreatScanResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["processThreatScanResult","context","eventDetail","security","withoutAuthorization","scanStatus","scanResultDetails","scanResultStatus","s3Object","s3ObjectDetails","file","fileManager","listFiles","limit","where","key","objectKey","allConnections","websockets","listConnections","newTags","tags","filter","tag","updateFile","id","savedBy","sendToConnections","action","data","deleteFile","name","e","console","log","message","exports"],"sources":["processThreatScanResult.ts"],"sourcesContent":["import { GuardDutyEvent, ThreatDetectionContext } from \"./types\";\n\nexport const processThreatScanResult = async (\n context: ThreatDetectionContext,\n eventDetail: GuardDutyEvent\n) => {\n await context.security.withoutAuthorization(async () => {\n try {\n const scanStatus = eventDetail.scanResultDetails.scanResultStatus;\n const s3Object = eventDetail.s3ObjectDetails;\n\n const [[file]] = await context.fileManager.listFiles({\n limit: 1,\n where: {\n key: s3Object.objectKey\n }\n });\n\n if (!file) {\n return;\n }\n\n const allConnections = await context.websockets.listConnections();\n\n if (scanStatus === \"NO_THREATS_FOUND\") {\n const newTags = file.tags.filter(tag => tag !== \"threatScanInProgress\");\n await context.fileManager.updateFile(file.id, {\n tags: newTags,\n savedBy: file.savedBy\n });\n\n await context.websockets.sendToConnections(allConnections, {\n action: \"fm.threatScan.noThreatFound\",\n data: {\n id: file.id,\n tags: newTags\n }\n });\n\n return;\n }\n\n if (scanStatus === \"THREATS_FOUND\") {\n // Delete infected file.\n await context.fileManager.deleteFile(file.id);\n\n await context.websockets.sendToConnections(allConnections, {\n action: \"fm.threatScan.threatDetected\",\n data: {\n id: file.id,\n name: file.name\n }\n });\n\n return;\n }\n\n // For all other outcomes, we delete the file, until better logic is implemented.\n await context.fileManager.deleteFile(file.id);\n\n await context.websockets.sendToConnections(allConnections, {\n action: \"fm.threatScan.unsupported\",\n data: {\n id: file.id,\n name: file.name\n }\n });\n } catch (e) {\n console.log(e.message);\n }\n });\n};\n"],"mappings":";;;;;;AAEO,MAAMA,uBAAuB,GAAG,MAAAA,CACnCC,OAA+B,EAC/BC,WAA2B,KAC1B;EACD,MAAMD,OAAO,CAACE,QAAQ,CAACC,oBAAoB,CAAC,YAAY;IACpD,IAAI;MACA,MAAMC,UAAU,GAAGH,WAAW,CAACI,iBAAiB,CAACC,gBAAgB;MACjE,MAAMC,QAAQ,GAAGN,WAAW,CAACO,eAAe;MAE5C,MAAM,CAAC,CAACC,IAAI,CAAC,CAAC,GAAG,MAAMT,OAAO,CAACU,WAAW,CAACC,SAAS,CAAC;QACjDC,KAAK,EAAE,CAAC;QACRC,KAAK,EAAE;UACHC,GAAG,EAAEP,QAAQ,CAACQ;QAClB;MACJ,CAAC,CAAC;MAEF,IAAI,CAACN,IAAI,EAAE;QACP;MACJ;MAEA,MAAMO,cAAc,GAAG,MAAMhB,OAAO,CAACiB,UAAU,CAACC,eAAe,CAAC,CAAC;MAEjE,IAAId,UAAU,KAAK,kBAAkB,EAAE;QACnC,MAAMe,OAAO,GAAGV,IAAI,CAACW,IAAI,CAACC,MAAM,CAACC,GAAG,IAAIA,GAAG,KAAK,sBAAsB,CAAC;QACvE,MAAMtB,OAAO,CAACU,WAAW,CAACa,UAAU,CAACd,IAAI,CAACe,EAAE,EAAE;UAC1CJ,IAAI,EAAED,OAAO;UACbM,OAAO,EAAEhB,IAAI,CAACgB;QAClB,CAAC,CAAC;QAEF,MAAMzB,OAAO,CAACiB,UAAU,CAACS,iBAAiB,CAACV,cAAc,EAAE;UACvDW,MAAM,EAAE,6BAA6B;UACrCC,IAAI,EAAE;YACFJ,EAAE,EAAEf,IAAI,CAACe,EAAE;YACXJ,IAAI,EAAED;UACV;QACJ,CAAC,CAAC;QAEF;MACJ;MAEA,IAAIf,UAAU,KAAK,eAAe,EAAE;QAChC;QACA,MAAMJ,OAAO,CAACU,WAAW,CAACmB,UAAU,CAACpB,IAAI,CAACe,EAAE,CAAC;QAE7C,MAAMxB,OAAO,CAACiB,UAAU,CAACS,iBAAiB,CAACV,cAAc,EAAE;UACvDW,MAAM,EAAE,8BAA8B;UACtCC,IAAI,EAAE;YACFJ,EAAE,EAAEf,IAAI,CAACe,EAAE;YACXM,IAAI,EAAErB,IAAI,CAACqB;UACf;QACJ,CAAC,CAAC;QAEF;MACJ;;MAEA;MACA,MAAM9B,OAAO,CAACU,WAAW,CAACmB,UAAU,CAACpB,IAAI,CAACe,EAAE,CAAC;MAE7C,MAAMxB,OAAO,CAACiB,UAAU,CAACS,iBAAiB,CAACV,cAAc,EAAE;QACvDW,MAAM,EAAE,2BAA2B;QACnCC,IAAI,EAAE;UACFJ,EAAE,EAAEf,IAAI,CAACe,EAAE;UACXM,IAAI,EAAErB,IAAI,CAACqB;QACf;MACJ,CAAC,CAAC;IACN,CAAC,CAAC,OAAOC,CAAC,EAAE;MACRC,OAAO,CAACC,GAAG,CAACF,CAAC,CAACG,OAAO,CAAC;IAC1B;EACJ,CAAC,CAAC;AACN,CAAC;AAACC,OAAA,CAAApC,uBAAA,GAAAA,uBAAA","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ import type { Context as IWebsocketsContext } from "@webiny/api-websockets";
2
+ import type { WcpContext } from "@webiny/api-wcp/types";
3
+ import type { FileManagerContext } from "@webiny/api-file-manager/types";
4
+ export type ThreatDetectionContext = FileManagerContext & IWebsocketsContext & WcpContext;
5
+ export type GuardDutyEvent = {
6
+ scanResultDetails: {
7
+ scanResultStatus: "UNSUPPORTED" | "FAILED" | "ACCESS_DENIED" | "THREATS_FOUND" | "NO_THREATS_FOUND";
8
+ };
9
+ s3ObjectDetails: {
10
+ bucketName: string;
11
+ objectKey: string;
12
+ };
13
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { Context as IWebsocketsContext } from \"@webiny/api-websockets\";\nimport type { WcpContext } from \"@webiny/api-wcp/types\";\nimport type { FileManagerContext } from \"@webiny/api-file-manager/types\";\n\nexport type ThreatDetectionContext = FileManagerContext & IWebsocketsContext & WcpContext;\n\nexport type GuardDutyEvent = {\n scanResultDetails: {\n scanResultStatus:\n | \"UNSUPPORTED\"\n | \"FAILED\"\n | \"ACCESS_DENIED\"\n | \"THREATS_FOUND\"\n | \"NO_THREATS_FOUND\";\n };\n s3ObjectDetails: {\n bucketName: string;\n objectKey: string;\n };\n};\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { createAssetDelivery as createBaseAssetDelivery } from "@webiny/api-file-manager";
2
+ export type AssetDeliveryParams = Parameters<typeof createBaseAssetDelivery>[0] & {
3
+ imageResizeWidths?: number[];
4
+ /**
5
+ * BE CAREFUL!
6
+ * Setting this to more than 1 hour may cause your URLs to still expire before the desired expiration time.
7
+ * @see https://repost.aws/knowledge-center/presigned-url-s3-bucket-expiration
8
+ */
9
+ presignedUrlTtl?: number;
10
+ assetStreamingMaxSize?: number;
11
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import { createAssetDelivery as createBaseAssetDelivery } from \"@webiny/api-file-manager\";\n\nexport type AssetDeliveryParams = Parameters<typeof createBaseAssetDelivery>[0] & {\n imageResizeWidths?: number[];\n /**\n * BE CAREFUL!\n * Setting this to more than 1 hour may cause your URLs to still expire before the desired expiration time.\n * @see https://repost.aws/knowledge-center/presigned-url-s3-bucket-expiration\n */\n presignedUrlTtl?: number;\n assetStreamingMaxSize?: number;\n};\n"],"mappings":"","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-file-manager-s3",
3
- "version": "5.42.0",
3
+ "version": "5.42.1-beta.1",
4
4
  "main": "index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,17 +10,20 @@
10
10
  "author": "Webiny Ltd",
11
11
  "license": "MIT",
12
12
  "dependencies": {
13
- "@webiny/api": "5.42.0",
14
- "@webiny/api-file-manager": "5.42.0",
15
- "@webiny/api-security": "5.42.0",
16
- "@webiny/aws-sdk": "5.42.0",
17
- "@webiny/error": "5.42.0",
18
- "@webiny/handler": "5.42.0",
19
- "@webiny/handler-graphql": "5.42.0",
20
- "@webiny/plugins": "5.42.0",
21
- "@webiny/tasks": "5.42.0",
22
- "@webiny/utils": "5.42.0",
23
- "@webiny/validation": "5.42.0",
13
+ "@webiny/api": "5.42.1-beta.1",
14
+ "@webiny/api-file-manager": "5.42.1-beta.1",
15
+ "@webiny/api-security": "5.42.1-beta.1",
16
+ "@webiny/api-wcp": "5.42.1-beta.1",
17
+ "@webiny/api-websockets": "5.42.1-beta.1",
18
+ "@webiny/aws-sdk": "5.42.1-beta.1",
19
+ "@webiny/error": "5.42.1-beta.1",
20
+ "@webiny/handler": "5.42.1-beta.1",
21
+ "@webiny/handler-aws": "5.42.1-beta.1",
22
+ "@webiny/handler-graphql": "5.42.1-beta.1",
23
+ "@webiny/plugins": "5.42.1-beta.1",
24
+ "@webiny/tasks": "5.42.1-beta.1",
25
+ "@webiny/utils": "5.42.1-beta.1",
26
+ "@webiny/validation": "5.42.1-beta.1",
24
27
  "form-data": "4.0.0",
25
28
  "mime": "3.0.0",
26
29
  "node-fetch": "2.6.7",
@@ -32,8 +35,8 @@
32
35
  },
33
36
  "devDependencies": {
34
37
  "@types/node-fetch": "2.6.2",
35
- "@webiny/cli": "5.42.0",
36
- "@webiny/project-utils": "5.42.0",
38
+ "@webiny/cli": "5.42.1-beta.1",
39
+ "@webiny/project-utils": "5.42.1-beta.1",
37
40
  "rimraf": "6.0.1",
38
41
  "typescript": "4.9.5"
39
42
  },
@@ -45,5 +48,5 @@
45
48
  "build": "yarn webiny run build",
46
49
  "watch": "yarn webiny run watch"
47
50
  },
48
- "gitHead": "54553dc380e73678a22e132b20001b1f645b0e93"
51
+ "gitHead": "aa533cb9b24cfcd23c02f4ab64448082723d7dc1"
49
52
  }