@arcjet/analyze 1.0.0-alpha.21 → 1.0.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_virtual/arcjet_analyze_js_req.component.core.js +1 -1
- package/_virtual/arcjet_analyze_js_req.component.core2.js +1 -1
- package/_virtual/arcjet_analyze_js_req.component.core3.js +1 -1
- package/edge-light.d.ts +18 -4
- package/edge-light.js +27 -3
- package/edge-light.ts +65 -5
- package/index.d.ts +18 -4
- package/index.js +27 -3
- package/index.ts +66 -5
- package/package.json +7 -10
- package/wasm/arcjet_analyze_js_req.component.core.wasm +0 -0
- package/wasm/arcjet_analyze_js_req.component.core2.wasm +0 -0
- package/wasm/arcjet_analyze_js_req.component.core3.wasm +0 -0
- package/wasm/arcjet_analyze_js_req.component.d.ts +39 -6
- package/wasm/arcjet_analyze_js_req.component.js +643 -331
- package/wasm/arcjet_analyze_js_req.component.wasm +0 -0
- package/wasm/interfaces/arcjet-js-req-sensitive-information-identifier.d.ts +20 -0
- package/workerd.d.ts +18 -4
- package/workerd.js +27 -3
- package/workerd.ts +66 -5
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* properly support consistent asset bundling techniques.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
const wasmBase64 = "data:application/wasm;base64,
|
|
27
|
+
const wasmBase64 = "data:application/wasm;base64,AGFzbQEAAAABEgNgAn9/AGACf38Bf2ADf39/AAMIBwAAAQEBAQIEBQFwAQcHBygIATAAAAExAAEBMgACATMAAwE0AAQBNQAFATYABggkaW1wb3J0cwEAClcHCwAgACABQQARAAALCwAgACABQQERAAALCwAgACABQQIRAQALCwAgACABQQMRAQALCwAgACABQQQRAQALCwAgACABQQURAQALDQAgACABIAJBBhECAAsALwlwcm9kdWNlcnMBDHByb2Nlc3NlZC1ieQENd2l0LWNvbXBvbmVudAcwLjIxMC4wAK4DBG5hbWUAExJ3aXQtY29tcG9uZW50OnNoaW0BkQMHACNpbmRpcmVjdC1hcmNqZXQ6anMtcmVxL2xvZ2dlci1kZWJ1ZwEjaW5kaXJlY3QtYXJjamV0OmpzLXJlcS9sb2dnZXItZXJyb3ICPmluZGlyZWN0LWFyY2pldDpqcy1yZXEvZW1haWwtdmFsaWRhdG9yLW92ZXJyaWRlcy1pcy1mcmVlLWVtYWlsA0RpbmRpcmVjdC1hcmNqZXQ6anMtcmVxL2VtYWlsLXZhbGlkYXRvci1vdmVycmlkZXMtaXMtZGlzcG9zYWJsZS1lbWFpbAQ/aW5kaXJlY3QtYXJjamV0OmpzLXJlcS9lbWFpbC12YWxpZGF0b3Itb3ZlcnJpZGVzLWhhcy1teC1yZWNvcmRzBT1pbmRpcmVjdC1hcmNqZXQ6anMtcmVxL2VtYWlsLXZhbGlkYXRvci1vdmVycmlkZXMtaGFzLWdyYXZhdGFyBj5pbmRpcmVjdC1hcmNqZXQ6anMtcmVxL3NlbnNpdGl2ZS1pbmZvcm1hdGlvbi1pZGVudGlmaWVyLWRldGVjdA==";
|
|
28
28
|
/**
|
|
29
29
|
* Returns a WebAssembly.Module for an Arcjet Wasm binary, decoded from a base64
|
|
30
30
|
* Data URL.
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* properly support consistent asset bundling techniques.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
const wasmBase64 = "data:application/wasm;base64,
|
|
27
|
+
const wasmBase64 = "data:application/wasm;base64,AGFzbQEAAAABEgNgAn9/AGACf38Bf2ADf39/AAIzCAABMAAAAAExAAAAATIAAQABMwABAAE0AAEAATUAAQABNgACAAgkaW1wb3J0cwFwAQcHCQ0BAEEACwcAAQIDBAUGAC8JcHJvZHVjZXJzAQxwcm9jZXNzZWQtYnkBDXdpdC1jb21wb25lbnQHMC4yMTAuMAAcBG5hbWUAFRR3aXQtY29tcG9uZW50OmZpeHVwcw==";
|
|
28
28
|
/**
|
|
29
29
|
* Returns a WebAssembly.Module for an Arcjet Wasm binary, decoded from a base64
|
|
30
30
|
* Data URL.
|
package/edge-light.d.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import type { ArcjetLogger
|
|
2
|
-
import type { EmailValidationConfig, BotDetectionResult, BotType, EmailValidationResult } from "./wasm/arcjet_analyze_js_req.component.js";
|
|
1
|
+
import type { ArcjetLogger } from "@arcjet/protocol";
|
|
2
|
+
import type { EmailValidationConfig, BotDetectionResult, BotType, EmailValidationResult, DetectedSensitiveInfoEntity, SensitiveInfoEntities, SensitiveInfoEntity, SensitiveInfoResult } from "./wasm/arcjet_analyze_js_req.component.js";
|
|
3
|
+
import type { ArcjetJsReqSensitiveInformationIdentifier } from "./wasm/interfaces/arcjet-js-req-sensitive-information-identifier.js";
|
|
4
|
+
type AnalyzeRequest = {
|
|
5
|
+
ip?: string;
|
|
6
|
+
method?: string;
|
|
7
|
+
protocol?: string;
|
|
8
|
+
host?: string;
|
|
9
|
+
path?: string;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
cookies?: string;
|
|
12
|
+
query?: string;
|
|
13
|
+
extra?: Record<string, string>;
|
|
14
|
+
};
|
|
3
15
|
interface AnalyzeContext {
|
|
4
16
|
log: ArcjetLogger;
|
|
5
17
|
characteristics: string[];
|
|
6
18
|
}
|
|
19
|
+
type DetectSensitiveInfoFunction = typeof ArcjetJsReqSensitiveInformationIdentifier.detect;
|
|
7
20
|
export { type EmailValidationConfig, type BotType,
|
|
8
21
|
/**
|
|
9
22
|
* Represents the result of the bot detection.
|
|
@@ -17,7 +30,7 @@ export { type EmailValidationConfig, type BotType,
|
|
|
17
30
|
* confidence level. `BotType.LikelyNotABot` with a score of 99 means we are
|
|
18
31
|
* almost certain this request was not a bot.
|
|
19
32
|
*/
|
|
20
|
-
type BotDetectionResult, };
|
|
33
|
+
type BotDetectionResult, type DetectedSensitiveInfoEntity, type SensitiveInfoEntity, type DetectSensitiveInfoFunction, };
|
|
21
34
|
/**
|
|
22
35
|
* Generate a fingerprint for the client. This is used to identify the client
|
|
23
36
|
* across multiple requests.
|
|
@@ -25,6 +38,7 @@ type BotDetectionResult, };
|
|
|
25
38
|
* @param request - The request to fingerprint.
|
|
26
39
|
* @returns A SHA-256 string fingerprint.
|
|
27
40
|
*/
|
|
28
|
-
export declare function generateFingerprint(context: AnalyzeContext, request:
|
|
41
|
+
export declare function generateFingerprint(context: AnalyzeContext, request: AnalyzeRequest): Promise<string>;
|
|
29
42
|
export declare function isValidEmail(context: AnalyzeContext, candidate: string, options?: EmailValidationConfig): Promise<EmailValidationResult>;
|
|
30
43
|
export declare function detectBot(context: AnalyzeContext, headers: string, patterns_add: string, patterns_remove: string): Promise<BotDetectionResult>;
|
|
44
|
+
export declare function detectSensitiveInfo(context: AnalyzeContext, candidate: string, entities: SensitiveInfoEntities, contextWindowSize: number, detect?: DetectSensitiveInfoFunction): Promise<SensitiveInfoResult>;
|
package/edge-light.js
CHANGED
|
@@ -22,8 +22,14 @@ async function moduleFromPath(path) {
|
|
|
22
22
|
}
|
|
23
23
|
throw new Error(`Unknown path: ${path}`);
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
function noOpDetect() {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
async function init(context, detectSensitiveInfo) {
|
|
26
29
|
const { log } = context;
|
|
30
|
+
if (typeof detectSensitiveInfo !== "function") {
|
|
31
|
+
detectSensitiveInfo = noOpDetect;
|
|
32
|
+
}
|
|
27
33
|
const coreImports = {
|
|
28
34
|
"arcjet:js-req/logger": {
|
|
29
35
|
debug(msg) {
|
|
@@ -50,9 +56,13 @@ async function init(context) {
|
|
|
50
56
|
return "unknown";
|
|
51
57
|
},
|
|
52
58
|
},
|
|
59
|
+
"arcjet:js-req/sensitive-information-identifier": {
|
|
60
|
+
detect: detectSensitiveInfo,
|
|
61
|
+
},
|
|
53
62
|
};
|
|
54
63
|
try {
|
|
55
|
-
|
|
64
|
+
// Await the instantiation to catch the failure
|
|
65
|
+
return await instantiate(moduleFromPath, coreImports);
|
|
56
66
|
}
|
|
57
67
|
catch {
|
|
58
68
|
log.debug("WebAssembly is not supported in this runtime");
|
|
@@ -104,5 +114,19 @@ async function detectBot(context, headers, patterns_add, patterns_remove) {
|
|
|
104
114
|
};
|
|
105
115
|
}
|
|
106
116
|
}
|
|
117
|
+
async function detectSensitiveInfo(context, candidate, entities, contextWindowSize, detect) {
|
|
118
|
+
const analyze = await init(context, detect);
|
|
119
|
+
if (typeof analyze !== "undefined") {
|
|
120
|
+
const skipCustomDetect = typeof detect !== "function";
|
|
121
|
+
return analyze.detectSensitiveInfo(candidate, {
|
|
122
|
+
entities,
|
|
123
|
+
contextWindowSize,
|
|
124
|
+
skipCustomDetect,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
throw new Error("SENSITIVE_INFO rule failed to run because Wasm is not supported in this environment.");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
107
131
|
|
|
108
|
-
export { detectBot, generateFingerprint, isValidEmail };
|
|
132
|
+
export { detectBot, detectSensitiveInfo, generateFingerprint, isValidEmail };
|
package/edge-light.ts
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
-
import type { ArcjetLogger
|
|
1
|
+
import type { ArcjetLogger } from "@arcjet/protocol";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { instantiate } from "./wasm/arcjet_analyze_js_req.component.js";
|
|
4
4
|
import type {
|
|
5
5
|
ImportObject,
|
|
6
6
|
EmailValidationConfig,
|
|
7
7
|
BotDetectionResult,
|
|
8
8
|
BotType,
|
|
9
9
|
EmailValidationResult,
|
|
10
|
+
DetectedSensitiveInfoEntity,
|
|
11
|
+
SensitiveInfoEntities,
|
|
12
|
+
SensitiveInfoEntity,
|
|
13
|
+
SensitiveInfoResult,
|
|
10
14
|
} from "./wasm/arcjet_analyze_js_req.component.js";
|
|
15
|
+
import type { ArcjetJsReqSensitiveInformationIdentifier } from "./wasm/interfaces/arcjet-js-req-sensitive-information-identifier.js";
|
|
11
16
|
|
|
12
17
|
import componentCoreWasm from "./wasm/arcjet_analyze_js_req.component.core.wasm?module";
|
|
13
18
|
import componentCore2Wasm from "./wasm/arcjet_analyze_js_req.component.core2.wasm?module";
|
|
14
19
|
import componentCore3Wasm from "./wasm/arcjet_analyze_js_req.component.core3.wasm?module";
|
|
15
20
|
|
|
21
|
+
type AnalyzeRequest = {
|
|
22
|
+
ip?: string;
|
|
23
|
+
method?: string;
|
|
24
|
+
protocol?: string;
|
|
25
|
+
host?: string;
|
|
26
|
+
path?: string;
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
cookies?: string;
|
|
29
|
+
query?: string;
|
|
30
|
+
extra?: Record<string, string>;
|
|
31
|
+
};
|
|
32
|
+
|
|
16
33
|
const FREE_EMAIL_PROVIDERS = [
|
|
17
34
|
"gmail.com",
|
|
18
35
|
"yahoo.com",
|
|
@@ -26,6 +43,9 @@ interface AnalyzeContext {
|
|
|
26
43
|
characteristics: string[];
|
|
27
44
|
}
|
|
28
45
|
|
|
46
|
+
type DetectSensitiveInfoFunction =
|
|
47
|
+
typeof ArcjetJsReqSensitiveInformationIdentifier.detect;
|
|
48
|
+
|
|
29
49
|
async function moduleFromPath(path: string): Promise<WebAssembly.Module> {
|
|
30
50
|
if (path === "arcjet_analyze_js_req.component.core.wasm") {
|
|
31
51
|
return componentCoreWasm;
|
|
@@ -40,9 +60,20 @@ async function moduleFromPath(path: string): Promise<WebAssembly.Module> {
|
|
|
40
60
|
throw new Error(`Unknown path: ${path}`);
|
|
41
61
|
}
|
|
42
62
|
|
|
43
|
-
|
|
63
|
+
function noOpDetect(): SensitiveInfoEntity[] {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function init(
|
|
68
|
+
context: AnalyzeContext,
|
|
69
|
+
detectSensitiveInfo?: DetectSensitiveInfoFunction,
|
|
70
|
+
) {
|
|
44
71
|
const { log } = context;
|
|
45
72
|
|
|
73
|
+
if (typeof detectSensitiveInfo !== "function") {
|
|
74
|
+
detectSensitiveInfo = noOpDetect;
|
|
75
|
+
}
|
|
76
|
+
|
|
46
77
|
const coreImports: ImportObject = {
|
|
47
78
|
"arcjet:js-req/logger": {
|
|
48
79
|
debug(msg) {
|
|
@@ -69,10 +100,14 @@ async function init(context: AnalyzeContext) {
|
|
|
69
100
|
return "unknown";
|
|
70
101
|
},
|
|
71
102
|
},
|
|
103
|
+
"arcjet:js-req/sensitive-information-identifier": {
|
|
104
|
+
detect: detectSensitiveInfo,
|
|
105
|
+
},
|
|
72
106
|
};
|
|
73
107
|
|
|
74
108
|
try {
|
|
75
|
-
|
|
109
|
+
// Await the instantiation to catch the failure
|
|
110
|
+
return await instantiate(moduleFromPath, coreImports);
|
|
76
111
|
} catch {
|
|
77
112
|
log.debug("WebAssembly is not supported in this runtime");
|
|
78
113
|
}
|
|
@@ -94,6 +129,9 @@ export {
|
|
|
94
129
|
* almost certain this request was not a bot.
|
|
95
130
|
*/
|
|
96
131
|
type BotDetectionResult,
|
|
132
|
+
type DetectedSensitiveInfoEntity,
|
|
133
|
+
type SensitiveInfoEntity,
|
|
134
|
+
type DetectSensitiveInfoFunction,
|
|
97
135
|
};
|
|
98
136
|
|
|
99
137
|
/**
|
|
@@ -105,7 +143,7 @@ export {
|
|
|
105
143
|
*/
|
|
106
144
|
export async function generateFingerprint(
|
|
107
145
|
context: AnalyzeContext,
|
|
108
|
-
request:
|
|
146
|
+
request: AnalyzeRequest,
|
|
109
147
|
): Promise<string> {
|
|
110
148
|
const analyze = await init(context);
|
|
111
149
|
|
|
@@ -161,3 +199,25 @@ export async function detectBot(
|
|
|
161
199
|
};
|
|
162
200
|
}
|
|
163
201
|
}
|
|
202
|
+
export async function detectSensitiveInfo(
|
|
203
|
+
context: AnalyzeContext,
|
|
204
|
+
candidate: string,
|
|
205
|
+
entities: SensitiveInfoEntities,
|
|
206
|
+
contextWindowSize: number,
|
|
207
|
+
detect?: DetectSensitiveInfoFunction,
|
|
208
|
+
): Promise<SensitiveInfoResult> {
|
|
209
|
+
const analyze = await init(context, detect);
|
|
210
|
+
|
|
211
|
+
if (typeof analyze !== "undefined") {
|
|
212
|
+
const skipCustomDetect = typeof detect !== "function";
|
|
213
|
+
return analyze.detectSensitiveInfo(candidate, {
|
|
214
|
+
entities,
|
|
215
|
+
contextWindowSize,
|
|
216
|
+
skipCustomDetect,
|
|
217
|
+
});
|
|
218
|
+
} else {
|
|
219
|
+
throw new Error(
|
|
220
|
+
"SENSITIVE_INFO rule failed to run because Wasm is not supported in this environment.",
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import type { ArcjetLogger
|
|
2
|
-
import type { EmailValidationConfig, BotDetectionResult, BotType, EmailValidationResult } from "./wasm/arcjet_analyze_js_req.component.js";
|
|
1
|
+
import type { ArcjetLogger } from "@arcjet/protocol";
|
|
2
|
+
import type { EmailValidationConfig, BotDetectionResult, BotType, EmailValidationResult, DetectedSensitiveInfoEntity, SensitiveInfoEntities, SensitiveInfoEntity, SensitiveInfoResult } from "./wasm/arcjet_analyze_js_req.component.js";
|
|
3
|
+
import type { ArcjetJsReqSensitiveInformationIdentifier } from "./wasm/interfaces/arcjet-js-req-sensitive-information-identifier.js";
|
|
4
|
+
type AnalyzeRequest = {
|
|
5
|
+
ip?: string;
|
|
6
|
+
method?: string;
|
|
7
|
+
protocol?: string;
|
|
8
|
+
host?: string;
|
|
9
|
+
path?: string;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
cookies?: string;
|
|
12
|
+
query?: string;
|
|
13
|
+
extra?: Record<string, string>;
|
|
14
|
+
};
|
|
3
15
|
interface AnalyzeContext {
|
|
4
16
|
log: ArcjetLogger;
|
|
5
17
|
characteristics: string[];
|
|
6
18
|
}
|
|
19
|
+
type DetectSensitiveInfoFunction = typeof ArcjetJsReqSensitiveInformationIdentifier.detect;
|
|
7
20
|
export { type EmailValidationConfig, type BotType,
|
|
8
21
|
/**
|
|
9
22
|
* Represents the result of the bot detection.
|
|
@@ -17,7 +30,7 @@ export { type EmailValidationConfig, type BotType,
|
|
|
17
30
|
* confidence level. `BotType.LikelyNotABot` with a score of 99 means we are
|
|
18
31
|
* almost certain this request was not a bot.
|
|
19
32
|
*/
|
|
20
|
-
type BotDetectionResult, };
|
|
33
|
+
type BotDetectionResult, type DetectedSensitiveInfoEntity, type SensitiveInfoEntity, type DetectSensitiveInfoFunction, };
|
|
21
34
|
/**
|
|
22
35
|
* Generate a fingerprint for the client. This is used to identify the client
|
|
23
36
|
* across multiple requests.
|
|
@@ -25,6 +38,7 @@ type BotDetectionResult, };
|
|
|
25
38
|
* @param request - The request to fingerprint.
|
|
26
39
|
* @returns A SHA-256 string fingerprint.
|
|
27
40
|
*/
|
|
28
|
-
export declare function generateFingerprint(context: AnalyzeContext, request:
|
|
41
|
+
export declare function generateFingerprint(context: AnalyzeContext, request: AnalyzeRequest): Promise<string>;
|
|
29
42
|
export declare function isValidEmail(context: AnalyzeContext, candidate: string, options?: EmailValidationConfig): Promise<EmailValidationResult>;
|
|
30
43
|
export declare function detectBot(context: AnalyzeContext, headers: string, patterns_add: string, patterns_remove: string): Promise<BotDetectionResult>;
|
|
44
|
+
export declare function detectSensitiveInfo(context: AnalyzeContext, candidate: string, entities: SensitiveInfoEntities, contextWindowSize: number, detect?: DetectSensitiveInfoFunction): Promise<SensitiveInfoResult>;
|
package/index.js
CHANGED
|
@@ -34,8 +34,14 @@ async function moduleFromPath(path) {
|
|
|
34
34
|
}
|
|
35
35
|
throw new Error(`Unknown path: ${path}`);
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
function noOpDetect() {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
async function init(context, detectSensitiveInfo) {
|
|
38
41
|
const { log } = context;
|
|
42
|
+
if (typeof detectSensitiveInfo !== "function") {
|
|
43
|
+
detectSensitiveInfo = noOpDetect;
|
|
44
|
+
}
|
|
39
45
|
const coreImports = {
|
|
40
46
|
"arcjet:js-req/logger": {
|
|
41
47
|
debug(msg) {
|
|
@@ -62,9 +68,13 @@ async function init(context) {
|
|
|
62
68
|
return "unknown";
|
|
63
69
|
},
|
|
64
70
|
},
|
|
71
|
+
"arcjet:js-req/sensitive-information-identifier": {
|
|
72
|
+
detect: detectSensitiveInfo,
|
|
73
|
+
},
|
|
65
74
|
};
|
|
66
75
|
try {
|
|
67
|
-
|
|
76
|
+
// Await the instantiation to catch the failure
|
|
77
|
+
return await instantiate(moduleFromPath, coreImports);
|
|
68
78
|
}
|
|
69
79
|
catch {
|
|
70
80
|
log.debug("WebAssembly is not supported in this runtime");
|
|
@@ -116,5 +126,19 @@ async function detectBot(context, headers, patterns_add, patterns_remove) {
|
|
|
116
126
|
};
|
|
117
127
|
}
|
|
118
128
|
}
|
|
129
|
+
async function detectSensitiveInfo(context, candidate, entities, contextWindowSize, detect) {
|
|
130
|
+
const analyze = await init(context, detect);
|
|
131
|
+
if (typeof analyze !== "undefined") {
|
|
132
|
+
const skipCustomDetect = typeof detect !== "function";
|
|
133
|
+
return analyze.detectSensitiveInfo(candidate, {
|
|
134
|
+
entities,
|
|
135
|
+
contextWindowSize,
|
|
136
|
+
skipCustomDetect,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw new Error("SENSITIVE_INFO rule failed to run because Wasm is not supported in this environment.");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
119
143
|
|
|
120
|
-
export { detectBot, generateFingerprint, isValidEmail };
|
|
144
|
+
export { detectBot, detectSensitiveInfo, generateFingerprint, isValidEmail };
|
package/index.ts
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
-
import type { ArcjetLogger
|
|
1
|
+
import type { ArcjetLogger } from "@arcjet/protocol";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { instantiate } from "./wasm/arcjet_analyze_js_req.component.js";
|
|
4
4
|
import type {
|
|
5
5
|
ImportObject,
|
|
6
6
|
EmailValidationConfig,
|
|
7
7
|
BotDetectionResult,
|
|
8
8
|
BotType,
|
|
9
9
|
EmailValidationResult,
|
|
10
|
+
DetectedSensitiveInfoEntity,
|
|
11
|
+
SensitiveInfoEntities,
|
|
12
|
+
SensitiveInfoEntity,
|
|
13
|
+
SensitiveInfoResult,
|
|
10
14
|
} from "./wasm/arcjet_analyze_js_req.component.js";
|
|
15
|
+
import type { ArcjetJsReqSensitiveInformationIdentifier } from "./wasm/interfaces/arcjet-js-req-sensitive-information-identifier.js";
|
|
11
16
|
|
|
12
17
|
import { wasm as componentCoreWasm } from "./wasm/arcjet_analyze_js_req.component.core.wasm?js";
|
|
13
18
|
import { wasm as componentCore2Wasm } from "./wasm/arcjet_analyze_js_req.component.core2.wasm?js";
|
|
14
19
|
import { wasm as componentCore3Wasm } from "./wasm/arcjet_analyze_js_req.component.core3.wasm?js";
|
|
15
20
|
|
|
21
|
+
type AnalyzeRequest = {
|
|
22
|
+
ip?: string;
|
|
23
|
+
method?: string;
|
|
24
|
+
protocol?: string;
|
|
25
|
+
host?: string;
|
|
26
|
+
path?: string;
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
cookies?: string;
|
|
29
|
+
query?: string;
|
|
30
|
+
extra?: Record<string, string>;
|
|
31
|
+
};
|
|
32
|
+
|
|
16
33
|
const FREE_EMAIL_PROVIDERS = [
|
|
17
34
|
"gmail.com",
|
|
18
35
|
"yahoo.com",
|
|
@@ -26,6 +43,9 @@ interface AnalyzeContext {
|
|
|
26
43
|
characteristics: string[];
|
|
27
44
|
}
|
|
28
45
|
|
|
46
|
+
type DetectSensitiveInfoFunction =
|
|
47
|
+
typeof ArcjetJsReqSensitiveInformationIdentifier.detect;
|
|
48
|
+
|
|
29
49
|
// TODO: Do we actually need this wasmCache or does `import` cache correctly?
|
|
30
50
|
const wasmCache = new Map<string, WebAssembly.Module>();
|
|
31
51
|
|
|
@@ -54,9 +74,20 @@ async function moduleFromPath(path: string): Promise<WebAssembly.Module> {
|
|
|
54
74
|
throw new Error(`Unknown path: ${path}`);
|
|
55
75
|
}
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
function noOpDetect(): SensitiveInfoEntity[] {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function init(
|
|
82
|
+
context: AnalyzeContext,
|
|
83
|
+
detectSensitiveInfo?: DetectSensitiveInfoFunction,
|
|
84
|
+
) {
|
|
58
85
|
const { log } = context;
|
|
59
86
|
|
|
87
|
+
if (typeof detectSensitiveInfo !== "function") {
|
|
88
|
+
detectSensitiveInfo = noOpDetect;
|
|
89
|
+
}
|
|
90
|
+
|
|
60
91
|
const coreImports: ImportObject = {
|
|
61
92
|
"arcjet:js-req/logger": {
|
|
62
93
|
debug(msg) {
|
|
@@ -83,10 +114,14 @@ async function init(context: AnalyzeContext) {
|
|
|
83
114
|
return "unknown";
|
|
84
115
|
},
|
|
85
116
|
},
|
|
117
|
+
"arcjet:js-req/sensitive-information-identifier": {
|
|
118
|
+
detect: detectSensitiveInfo,
|
|
119
|
+
},
|
|
86
120
|
};
|
|
87
121
|
|
|
88
122
|
try {
|
|
89
|
-
|
|
123
|
+
// Await the instantiation to catch the failure
|
|
124
|
+
return await instantiate(moduleFromPath, coreImports);
|
|
90
125
|
} catch {
|
|
91
126
|
log.debug("WebAssembly is not supported in this runtime");
|
|
92
127
|
}
|
|
@@ -108,6 +143,9 @@ export {
|
|
|
108
143
|
* almost certain this request was not a bot.
|
|
109
144
|
*/
|
|
110
145
|
type BotDetectionResult,
|
|
146
|
+
type DetectedSensitiveInfoEntity,
|
|
147
|
+
type SensitiveInfoEntity,
|
|
148
|
+
type DetectSensitiveInfoFunction,
|
|
111
149
|
};
|
|
112
150
|
|
|
113
151
|
/**
|
|
@@ -119,7 +157,7 @@ export {
|
|
|
119
157
|
*/
|
|
120
158
|
export async function generateFingerprint(
|
|
121
159
|
context: AnalyzeContext,
|
|
122
|
-
request:
|
|
160
|
+
request: AnalyzeRequest,
|
|
123
161
|
): Promise<string> {
|
|
124
162
|
const analyze = await init(context);
|
|
125
163
|
|
|
@@ -175,3 +213,26 @@ export async function detectBot(
|
|
|
175
213
|
};
|
|
176
214
|
}
|
|
177
215
|
}
|
|
216
|
+
|
|
217
|
+
export async function detectSensitiveInfo(
|
|
218
|
+
context: AnalyzeContext,
|
|
219
|
+
candidate: string,
|
|
220
|
+
entities: SensitiveInfoEntities,
|
|
221
|
+
contextWindowSize: number,
|
|
222
|
+
detect?: DetectSensitiveInfoFunction,
|
|
223
|
+
): Promise<SensitiveInfoResult> {
|
|
224
|
+
const analyze = await init(context, detect);
|
|
225
|
+
|
|
226
|
+
if (typeof analyze !== "undefined") {
|
|
227
|
+
const skipCustomDetect = typeof detect !== "function";
|
|
228
|
+
return analyze.detectSensitiveInfo(candidate, {
|
|
229
|
+
entities,
|
|
230
|
+
contextWindowSize,
|
|
231
|
+
skipCustomDetect,
|
|
232
|
+
});
|
|
233
|
+
} else {
|
|
234
|
+
throw new Error(
|
|
235
|
+
"SENSITIVE_INFO rule failed to run because Wasm is not supported in this environment.",
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcjet/analyze",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.23",
|
|
4
4
|
"description": "Arcjet local analysis engine",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://arcjet.com",
|
|
@@ -47,19 +47,16 @@
|
|
|
47
47
|
"pretest": "npm run build",
|
|
48
48
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest --passWithNoTests"
|
|
49
49
|
},
|
|
50
|
-
"sideEffects": [
|
|
51
|
-
"./wasm/arcjet_analyze_js_req_bg.js"
|
|
52
|
-
],
|
|
53
50
|
"dependencies": {
|
|
54
|
-
"@arcjet/protocol": "1.0.0-alpha.
|
|
51
|
+
"@arcjet/protocol": "1.0.0-alpha.23"
|
|
55
52
|
},
|
|
56
53
|
"devDependencies": {
|
|
57
|
-
"@arcjet/eslint-config": "1.0.0-alpha.
|
|
58
|
-
"@arcjet/rollup-config": "1.0.0-alpha.
|
|
59
|
-
"@arcjet/tsconfig": "1.0.0-alpha.
|
|
60
|
-
"@bytecodealliance/jco": "1.
|
|
54
|
+
"@arcjet/eslint-config": "1.0.0-alpha.23",
|
|
55
|
+
"@arcjet/rollup-config": "1.0.0-alpha.23",
|
|
56
|
+
"@arcjet/tsconfig": "1.0.0-alpha.23",
|
|
57
|
+
"@bytecodealliance/jco": "1.5.0",
|
|
61
58
|
"@jest/globals": "29.7.0",
|
|
62
|
-
"@rollup/wasm-node": "4.
|
|
59
|
+
"@rollup/wasm-node": "4.21.2",
|
|
63
60
|
"@types/node": "18.18.0",
|
|
64
61
|
"jest": "29.7.0",
|
|
65
62
|
"typescript": "5.5.4"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { SensitiveInfoEntity } from './interfaces/arcjet-js-req-sensitive-information-identifier.js';
|
|
2
|
+
export { SensitiveInfoEntity };
|
|
1
3
|
/**
|
|
2
4
|
* # Variants
|
|
3
5
|
*
|
|
@@ -28,23 +30,49 @@ export interface BotDetectionResult {
|
|
|
28
30
|
export type EmailValidity = 'valid' | 'invalid';
|
|
29
31
|
export interface EmailValidationResult {
|
|
30
32
|
validity: EmailValidity,
|
|
31
|
-
blocked: string
|
|
33
|
+
blocked: Array<string>,
|
|
32
34
|
}
|
|
33
35
|
export interface EmailValidationConfig {
|
|
34
36
|
requireTopLevelDomain: boolean,
|
|
35
37
|
allowDomainLiteral: boolean,
|
|
36
|
-
blockedEmails: string
|
|
38
|
+
blockedEmails: Array<string>,
|
|
39
|
+
}
|
|
40
|
+
export type SensitiveInfoEntities = SensitiveInfoEntitiesAllow | SensitiveInfoEntitiesDeny;
|
|
41
|
+
export interface SensitiveInfoEntitiesAllow {
|
|
42
|
+
tag: 'allow',
|
|
43
|
+
val: Array<SensitiveInfoEntity>,
|
|
44
|
+
}
|
|
45
|
+
export interface SensitiveInfoEntitiesDeny {
|
|
46
|
+
tag: 'deny',
|
|
47
|
+
val: Array<SensitiveInfoEntity>,
|
|
48
|
+
}
|
|
49
|
+
export interface SensitiveInfoConfig {
|
|
50
|
+
entities: SensitiveInfoEntities,
|
|
51
|
+
contextWindowSize?: number,
|
|
52
|
+
skipCustomDetect: boolean,
|
|
53
|
+
}
|
|
54
|
+
export interface DetectedSensitiveInfoEntity {
|
|
55
|
+
start: number,
|
|
56
|
+
end: number,
|
|
57
|
+
identifiedType: SensitiveInfoEntity,
|
|
58
|
+
}
|
|
59
|
+
export interface SensitiveInfoResult {
|
|
60
|
+
allowed: Array<DetectedSensitiveInfoEntity>,
|
|
61
|
+
denied: Array<DetectedSensitiveInfoEntity>,
|
|
37
62
|
}
|
|
38
63
|
import { ArcjetJsReqEmailValidatorOverrides } from './interfaces/arcjet-js-req-email-validator-overrides.js';
|
|
39
64
|
import { ArcjetJsReqLogger } from './interfaces/arcjet-js-req-logger.js';
|
|
65
|
+
import { ArcjetJsReqSensitiveInformationIdentifier } from './interfaces/arcjet-js-req-sensitive-information-identifier.js';
|
|
40
66
|
export interface ImportObject {
|
|
41
67
|
'arcjet:js-req/email-validator-overrides': typeof ArcjetJsReqEmailValidatorOverrides,
|
|
42
68
|
'arcjet:js-req/logger': typeof ArcjetJsReqLogger,
|
|
69
|
+
'arcjet:js-req/sensitive-information-identifier': typeof ArcjetJsReqSensitiveInformationIdentifier,
|
|
43
70
|
}
|
|
44
71
|
export interface Root {
|
|
45
72
|
detectBot(headers: string, patternsAdd: string, patternsRemove: string): BotDetectionResult,
|
|
46
|
-
generateFingerprint(request: string, characteristics: string
|
|
73
|
+
generateFingerprint(request: string, characteristics: Array<string>): string,
|
|
47
74
|
isValidEmail(candidate: string, options: EmailValidationConfig): EmailValidationResult,
|
|
75
|
+
detectSensitiveInfo(content: string, options: SensitiveInfoConfig): SensitiveInfoResult,
|
|
48
76
|
}
|
|
49
77
|
|
|
50
78
|
/**
|
|
@@ -67,8 +95,13 @@ export interface Root {
|
|
|
67
95
|
* on the web, for example.
|
|
68
96
|
*/
|
|
69
97
|
export function instantiate(
|
|
70
|
-
getCoreModule: (path: string) =>
|
|
98
|
+
getCoreModule: (path: string) => WebAssembly.Module,
|
|
99
|
+
imports: ImportObject,
|
|
100
|
+
instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => WebAssembly.Instance
|
|
101
|
+
): Root;
|
|
102
|
+
export function instantiate(
|
|
103
|
+
getCoreModule: (path: string) => WebAssembly.Module | Promise<WebAssembly.Module>,
|
|
71
104
|
imports: ImportObject,
|
|
72
|
-
instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => Promise<WebAssembly.Instance>
|
|
73
|
-
): Promise<Root>;
|
|
105
|
+
instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => WebAssembly.Instance | Promise<WebAssembly.Instance>
|
|
106
|
+
): Root | Promise<Root>;
|
|
74
107
|
|