Socket
Socket
Sign inDemoInstall

arcjet

Package Overview
Dependencies
Maintainers
2
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

arcjet - npm Package Compare versions

Comparing version 1.0.0-alpha.21 to 1.0.0-alpha.22

27

index.d.ts

@@ -1,3 +0,4 @@

import { ArcjetBotType, ArcjetEmailType, ArcjetMode, ArcjetDecision, ArcjetRule, ArcjetLogger } from "@arcjet/protocol";
import { Client } from "@arcjet/protocol/client.js";
import type { ArcjetRule, ArcjetLogger } from "@arcjet/protocol";
import { ArcjetBotType, ArcjetEmailType, ArcjetMode, ArcjetSensitiveInfoType, ArcjetDecision } from "@arcjet/protocol";
import type { Client } from "@arcjet/protocol/client.js";
export * from "@arcjet/protocol";

@@ -97,2 +98,18 @@ type Simplify<T> = {

};
type DetectSensitiveInfoEntities<T> = (tokens: string[]) => Array<ArcjetSensitiveInfoType | T | undefined>;
type SensitiveInfoOptionsAllow<Detect extends DetectSensitiveInfoEntities<CustomEntities>, CustomEntities extends string> = {
allow: Array<ArcjetSensitiveInfoType | Exclude<ReturnType<Detect>[number], undefined>>;
deny?: never;
contextWindowSize?: number;
mode?: ArcjetMode;
detect?: Detect;
};
type SensitiveInfoOptionsDeny<Detect extends DetectSensitiveInfoEntities<CustomEntities>, CustomEntities extends string> = {
allow?: never;
deny: Array<ArcjetSensitiveInfoType | Exclude<ReturnType<Detect>[number], undefined>>;
contextWindowSize?: number;
mode?: ArcjetMode;
detect?: Detect;
};
export type SensitiveInfoOptions<Detect extends DetectSensitiveInfoEntities<CustomEntities>, CustomEntities extends string> = SensitiveInfoOptionsAllow<Detect, CustomEntities> | SensitiveInfoOptionsDeny<Detect, CustomEntities>;
type PlainObject = {

@@ -113,3 +130,6 @@ [key: string]: unknown;

*/
export type ArcjetAdapterContext = Record<string, unknown>;
export type ArcjetAdapterContext = {
[key: string]: unknown;
getBody(): Promise<string | undefined>;
};
/**

@@ -143,2 +163,3 @@ * @property {string} ip - The IP address of the client.

export declare function slidingWindow<const Characteristics extends readonly string[] = []>(options?: SlidingWindowRateLimitOptions<Characteristics>, ...additionalOptions: SlidingWindowRateLimitOptions<Characteristics>[]): Primitive<Simplify<CharacteristicProps<Characteristics>>>;
export declare function sensitiveInfo<const Detect extends DetectSensitiveInfoEntities<CustomEntities>, const CustomEntities extends string>(options: SensitiveInfoOptions<Detect, CustomEntities>, ...additionalOptions: SensitiveInfoOptions<Detect, CustomEntities>[]): Primitive<{}>;
export declare function validateEmail(options?: EmailOptions, ...additionalOptions: EmailOptions[]): Primitive<{

@@ -145,0 +166,0 @@ email: string;

@@ -1,2 +0,2 @@

import { ArcjetRuleResult, ArcjetEmailReason, ArcjetBotType, ArcjetErrorReason, ArcjetBotReason, ArcjetErrorDecision, ArcjetReason, ArcjetDenyDecision } from '@arcjet/protocol';
import { ArcjetRuleResult, ArcjetErrorReason, ArcjetSensitiveInfoReason, ArcjetEmailReason, ArcjetBotType, ArcjetBotReason, ArcjetErrorDecision, ArcjetReason, ArcjetDenyDecision } from '@arcjet/protocol';
export * from '@arcjet/protocol';

@@ -102,6 +102,7 @@ import { ArcjetBotTypeToProtocol, isRateLimitRule } from '@arcjet/protocol/convert.js';

const Priority = {
Shield: 1,
RateLimit: 2,
BotDetection: 3,
EmailValidation: 4,
SensitiveInfo: 1,
Shield: 2,
RateLimit: 3,
BotDetection: 4,
EmailValidation: 5,
};

@@ -194,2 +195,124 @@ function isLocalRule(rule) {

}
function protocolSensitiveInfoEntitiesToAnalyze(entity) {
if (typeof entity !== "string") {
throw new Error("invalid entity type");
}
if (entity === "EMAIL") {
return { tag: "email" };
}
if (entity === "PHONE_NUMBER") {
return { tag: "phone-number" };
}
if (entity === "IP_ADDRESS") {
return { tag: "ip-address" };
}
if (entity === "CREDIT_CARD_NUMBER") {
return { tag: "credit-card-number" };
}
return {
tag: "custom",
val: entity,
};
}
function analyzeSensitiveInfoEntitiesToString(entity) {
if (entity.tag === "email") {
return "EMAIL";
}
if (entity.tag === "ip-address") {
return "IP_ADDRESS";
}
if (entity.tag === "credit-card-number") {
return "CREDIT_CARD_NUMBER";
}
if (entity.tag === "phone-number") {
return "PHONE_NUMBER";
}
return entity.val;
}
function convertAnalyzeDetectedSensitiveInfoEntity(detectedEntities) {
return detectedEntities.map((detectedEntity) => {
return {
...detectedEntity,
identifiedType: analyzeSensitiveInfoEntitiesToString(detectedEntity.identifiedType),
};
});
}
function sensitiveInfo(options, ...additionalOptions) {
const rules = [];
// Always create at least one SENSITIVE_INFO rule
for (const opt of [options, ...additionalOptions]) {
const mode = opt.mode === "LIVE" ? "LIVE" : "DRY_RUN";
if (typeof opt.allow !== "undefined" && typeof opt.deny !== "undefined") {
throw new Error("Both allow and deny cannot be provided to sensitiveInfo");
}
rules.push({
type: "SENSITIVE_INFO",
priority: Priority.SensitiveInfo,
mode,
allow: opt.allow || [],
deny: opt.deny || [],
validate(context, details) { },
async protect(context, details) {
const body = await context.getBody();
if (typeof body === "undefined") {
return new ArcjetRuleResult({
ttl: 0,
state: "NOT_RUN",
conclusion: "ERROR",
reason: new ArcjetErrorReason("Couldn't read the body of the request to perform sensitive info identification."),
});
}
let convertedDetect = undefined;
if (typeof opt.detect !== "undefined") {
const detect = opt.detect;
convertedDetect = (tokens) => {
return detect(tokens)
.filter((e) => typeof e !== "undefined")
.map(protocolSensitiveInfoEntitiesToAnalyze);
};
}
let entitiesTag = "allow";
let entitiesVal = [];
if (Array.isArray(opt.allow)) {
entitiesTag = "allow";
entitiesVal = opt.allow
.filter((e) => typeof e !== "undefined")
.map(protocolSensitiveInfoEntitiesToAnalyze);
}
if (Array.isArray(opt.deny)) {
entitiesTag = "deny";
entitiesVal = opt.deny
.filter((e) => typeof e !== "undefined")
.map(protocolSensitiveInfoEntitiesToAnalyze);
}
const entities = {
tag: entitiesTag,
val: entitiesVal,
};
const result = await analyze.detectSensitiveInfo(context, body, entities, options.contextWindowSize || 1, convertedDetect);
const reason = new ArcjetSensitiveInfoReason({
denied: convertAnalyzeDetectedSensitiveInfoEntity(result.denied),
allowed: convertAnalyzeDetectedSensitiveInfoEntity(result.allowed),
});
if (result.denied.length === 0) {
return new ArcjetRuleResult({
ttl: 0,
state: "RUN",
conclusion: "ALLOW",
reason,
});
}
else {
return new ArcjetRuleResult({
ttl: 0,
state: "RUN",
conclusion: "DENY",
reason,
});
}
},
});
}
return rules;
}
function validateEmail(options, ...additionalOptions) {

@@ -636,2 +759,2 @@ const rules = [];

export { arcjet as default, detectBot, fixedWindow, protectSignup, shield, slidingWindow, tokenBucket, validateEmail };
export { arcjet as default, detectBot, fixedWindow, protectSignup, sensitiveInfo, shield, slidingWindow, tokenBucket, validateEmail };

@@ -0,7 +1,20 @@

import type {
ArcjetContext,
ArcjetEmailRule,
ArcjetBotRule,
ArcjetRule,
ArcjetLocalRule,
ArcjetRequestDetails,
ArcjetTokenBucketRateLimitRule,
ArcjetFixedWindowRateLimitRule,
ArcjetSlidingWindowRateLimitRule,
ArcjetShieldRule,
ArcjetLogger,
ArcjetSensitiveInfoRule,
ArcjetIdentifiedEntity,
} from "@arcjet/protocol";
import {
ArcjetContext,
ArcjetBotReason,
ArcjetBotType,
ArcjetEmailReason,
ArcjetEmailRule,
ArcjetEmailType,

@@ -12,15 +25,7 @@ ArcjetErrorReason,

ArcjetRuleResult,
ArcjetSensitiveInfoType,
ArcjetSensitiveInfoReason,
ArcjetDecision,
ArcjetDenyDecision,
ArcjetErrorDecision,
ArcjetBotRule,
ArcjetRule,
ArcjetLocalRule,
ArcjetRequestDetails,
ArcjetTokenBucketRateLimitRule,
ArcjetFixedWindowRateLimitRule,
ArcjetSlidingWindowRateLimitRule,
ArcjetShieldRule,
ArcjetLogger,
ArcjetRateLimitRule,
} from "@arcjet/protocol";

@@ -31,4 +36,8 @@ import {

} from "@arcjet/protocol/convert.js";
import { Client } from "@arcjet/protocol/client.js";
import type { Client } from "@arcjet/protocol/client.js";
import * as analyze from "@arcjet/analyze";
import type {
DetectedSensitiveInfoEntity,
SensitiveInfoEntity,
} from "@arcjet/analyze";
import * as duration from "@arcjet/duration";

@@ -314,7 +323,45 @@ import ArcjetHeaders from "@arcjet/headers";

type DetectSensitiveInfoEntities<T> = (
tokens: string[],
) => Array<ArcjetSensitiveInfoType | T | undefined>;
type SensitiveInfoOptionsAllow<
Detect extends DetectSensitiveInfoEntities<CustomEntities>,
CustomEntities extends string,
> = {
allow: Array<
ArcjetSensitiveInfoType | Exclude<ReturnType<Detect>[number], undefined>
>;
deny?: never;
contextWindowSize?: number;
mode?: ArcjetMode;
detect?: Detect;
};
type SensitiveInfoOptionsDeny<
Detect extends DetectSensitiveInfoEntities<CustomEntities>,
CustomEntities extends string,
> = {
allow?: never;
deny: Array<
ArcjetSensitiveInfoType | Exclude<ReturnType<Detect>[number], undefined>
>;
contextWindowSize?: number;
mode?: ArcjetMode;
detect?: Detect;
};
export type SensitiveInfoOptions<
Detect extends DetectSensitiveInfoEntities<CustomEntities>,
CustomEntities extends string,
> =
| SensitiveInfoOptionsAllow<Detect, CustomEntities>
| SensitiveInfoOptionsDeny<Detect, CustomEntities>;
const Priority = {
Shield: 1,
RateLimit: 2,
BotDetection: 3,
EmailValidation: 4,
SensitiveInfo: 1,
Shield: 2,
RateLimit: 3,
BotDetection: 4,
EmailValidation: 5,
};

@@ -371,3 +418,6 @@

*/
export type ArcjetAdapterContext = Record<string, unknown>;
export type ArcjetAdapterContext = {
[key: string]: unknown;
getBody(): Promise<string | undefined>;
};

@@ -530,2 +580,181 @@ /**

function protocolSensitiveInfoEntitiesToAnalyze<Custom extends string>(
entity: ArcjetSensitiveInfoType | Custom,
) {
if (typeof entity !== "string") {
throw new Error("invalid entity type");
}
if (entity === "EMAIL") {
return { tag: "email" as const };
}
if (entity === "PHONE_NUMBER") {
return { tag: "phone-number" as const };
}
if (entity === "IP_ADDRESS") {
return { tag: "ip-address" as const };
}
if (entity === "CREDIT_CARD_NUMBER") {
return { tag: "credit-card-number" as const };
}
return {
tag: "custom" as const,
val: entity,
};
}
function analyzeSensitiveInfoEntitiesToString(
entity: SensitiveInfoEntity,
): string {
if (entity.tag === "email") {
return "EMAIL";
}
if (entity.tag === "ip-address") {
return "IP_ADDRESS";
}
if (entity.tag === "credit-card-number") {
return "CREDIT_CARD_NUMBER";
}
if (entity.tag === "phone-number") {
return "PHONE_NUMBER";
}
return entity.val;
}
function convertAnalyzeDetectedSensitiveInfoEntity(
detectedEntities: DetectedSensitiveInfoEntity[],
): ArcjetIdentifiedEntity[] {
return detectedEntities.map((detectedEntity) => {
return {
...detectedEntity,
identifiedType: analyzeSensitiveInfoEntitiesToString(
detectedEntity.identifiedType,
),
};
});
}
export function sensitiveInfo<
const Detect extends DetectSensitiveInfoEntities<CustomEntities>,
const CustomEntities extends string,
>(
options: SensitiveInfoOptions<Detect, CustomEntities>,
...additionalOptions: SensitiveInfoOptions<Detect, CustomEntities>[]
): Primitive<{}> {
const rules: ArcjetSensitiveInfoRule<{}>[] = [];
// Always create at least one SENSITIVE_INFO rule
for (const opt of [options, ...additionalOptions]) {
const mode = opt.mode === "LIVE" ? "LIVE" : "DRY_RUN";
if (typeof opt.allow !== "undefined" && typeof opt.deny !== "undefined") {
throw new Error(
"Both allow and deny cannot be provided to sensitiveInfo",
);
}
rules.push({
type: "SENSITIVE_INFO",
priority: Priority.SensitiveInfo,
mode,
allow: opt.allow || [],
deny: opt.deny || [],
validate(
context: ArcjetContext,
details: ArcjetRequestDetails,
): asserts details is ArcjetRequestDetails {},
async protect(
context: ArcjetContext,
details: ArcjetRequestDetails,
): Promise<ArcjetRuleResult> {
const body = await context.getBody();
if (typeof body === "undefined") {
return new ArcjetRuleResult({
ttl: 0,
state: "NOT_RUN",
conclusion: "ERROR",
reason: new ArcjetErrorReason(
"Couldn't read the body of the request to perform sensitive info identification.",
),
});
}
let convertedDetect = undefined;
if (typeof opt.detect !== "undefined") {
const detect = opt.detect;
convertedDetect = (tokens: string[]) => {
return detect(tokens)
.filter((e) => typeof e !== "undefined")
.map(protocolSensitiveInfoEntitiesToAnalyze);
};
}
let entitiesTag: "allow" | "deny" = "allow";
let entitiesVal: Array<
ReturnType<typeof protocolSensitiveInfoEntitiesToAnalyze>
> = [];
if (Array.isArray(opt.allow)) {
entitiesTag = "allow";
entitiesVal = opt.allow
.filter((e) => typeof e !== "undefined")
.map(protocolSensitiveInfoEntitiesToAnalyze);
}
if (Array.isArray(opt.deny)) {
entitiesTag = "deny";
entitiesVal = opt.deny
.filter((e) => typeof e !== "undefined")
.map(protocolSensitiveInfoEntitiesToAnalyze);
}
const entities = {
tag: entitiesTag,
val: entitiesVal,
};
const result = await analyze.detectSensitiveInfo(
context,
body,
entities,
options.contextWindowSize || 1,
convertedDetect,
);
const reason = new ArcjetSensitiveInfoReason({
denied: convertAnalyzeDetectedSensitiveInfoEntity(result.denied),
allowed: convertAnalyzeDetectedSensitiveInfoEntity(result.allowed),
});
if (result.denied.length === 0) {
return new ArcjetRuleResult({
ttl: 0,
state: "RUN",
conclusion: "ALLOW",
reason,
});
} else {
return new ArcjetRuleResult({
ttl: 0,
state: "RUN",
conclusion: "DENY",
reason,
});
}
},
});
}
return rules;
}
export function validateEmail(

@@ -532,0 +761,0 @@ options?: EmailOptions,

22

package.json
{
"name": "arcjet",
"version": "1.0.0-alpha.21",
"version": "1.0.0-alpha.22",
"description": "Arcjet TypeScript and JavaScript SDK core",

@@ -43,15 +43,15 @@ "license": "Apache-2.0",

"dependencies": {
"@arcjet/analyze": "1.0.0-alpha.21",
"@arcjet/duration": "1.0.0-alpha.21",
"@arcjet/headers": "1.0.0-alpha.21",
"@arcjet/protocol": "1.0.0-alpha.21",
"@arcjet/runtime": "1.0.0-alpha.21"
"@arcjet/analyze": "1.0.0-alpha.22",
"@arcjet/duration": "1.0.0-alpha.22",
"@arcjet/headers": "1.0.0-alpha.22",
"@arcjet/protocol": "1.0.0-alpha.22",
"@arcjet/runtime": "1.0.0-alpha.22"
},
"devDependencies": {
"@arcjet/eslint-config": "1.0.0-alpha.21",
"@arcjet/rollup-config": "1.0.0-alpha.21",
"@arcjet/tsconfig": "1.0.0-alpha.21",
"@edge-runtime/jest-environment": "3.0.1",
"@arcjet/eslint-config": "1.0.0-alpha.22",
"@arcjet/rollup-config": "1.0.0-alpha.22",
"@arcjet/tsconfig": "1.0.0-alpha.22",
"@edge-runtime/jest-environment": "3.0.2",
"@jest/globals": "29.7.0",
"@rollup/wasm-node": "4.20.0",
"@rollup/wasm-node": "4.21.0",
"@types/node": "18.18.0",

@@ -58,0 +58,0 @@ "jest": "29.7.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc