Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
"typecheck": "tsc --noEmit",
"prepare": "husky"
},
"dependencies": {
"@mswjs/interceptors": "^0.41.4"
},
"devDependencies": {
"@commitlint/cli": "^19.8.0",
"@commitlint/config-conventional": "^19.8.0",
Expand All @@ -80,6 +83,9 @@
"oxfmt --write"
]
},
"engines": {
"node": ">=18"
},
"packageManager": "pnpm@10.27.0",
"pnpm": {
"onlyBuiltDependencies": [
Expand Down
50 changes: 50 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 41 additions & 1 deletion src/enkryptify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import { Logger } from "@/logger";
import { retrieveToken } from "@/internal/token-store";
import { TokenExchangeManager } from "@/token-exchange";
import { KubernetesExchangeManager } from "@/kubernetes-exchange";
import { EnkryptifyProxy } from "@/proxy";
import { EnkryptifyProxy, sendProxyWire } from "@/proxy";
import { HttpInterceptor } from "@/interceptor";

const DEFAULT_PROXY_URL = "https://proxy-poc-black.vercel.app";

Expand All @@ -35,6 +36,7 @@ export class Enkryptify implements IEnkryptify {
#tokenExchange: TokenExchange | null = null;
#proxy: EnkryptifyProxy;
#proxyOnly: boolean;
#interceptor: HttpInterceptor | null = null;

constructor(config: EnkryptifyConfig) {
if (!config.workspace) {
Expand Down Expand Up @@ -124,6 +126,32 @@ export class Enkryptify implements IEnkryptify {
isDestroyed: () => this.#destroyed,
});

// HTTP interceptor: patches the Node HTTP stack so matching outbound
// requests from third-party SDKs (axios, got, OpenAI, Stripe, etc.)
// are rerouted through the Enkryptify proxy. Enabled when the user
// configures rules; disabled on destroy().
const interceptorConfig = config.interceptor;
if (interceptorConfig && interceptorConfig.enabled !== false && interceptorConfig.rules.length > 0) {
const proxyCtx = this.#proxy._ctx;
Comment thread
SiebeBaree marked this conversation as resolved.
this.#interceptor = new HttpInterceptor({
config: interceptorConfig,
sendWire: (body, signal) => sendProxyWire(proxyCtx, body, signal),
defaults: {
workspace: this.#workspace,
project: this.#project,
environment: this.#environment,
usePersonalValues: this.#usePersonalValues,
},
logger: this.#logger,
});
// Fire-and-forget: dynamic import is async, but we don't want
// construction to be async. Any failure is logged; requests
// issued before `ready` resolves simply aren't intercepted.
this.#interceptor.enable().catch((err: unknown) => {
this.#logger.error(`Interceptor failed to enable: ${(err as Error).message}`);
});
}

this.#logger.info(
`Initialized for workspace "${this.#workspace}", project "${this.#project}", environment "${this.#environment}"`,
);
Expand All @@ -134,6 +162,16 @@ export class Enkryptify implements IEnkryptify {
return this.#proxy;
}

/**
* @internal Resolves once the HTTP interceptor has patched the global
* HTTP stack (or immediately if no interceptor was configured). Exposed
* for tests and for users who want to guarantee interception before
* issuing their first request.
*/
_interceptorReady(): Promise<void> {
return this.#interceptor?.ready ?? Promise.resolve();
}

static fromEnv(): EnkryptifyAuthProvider {
return new EnvAuthProvider();
}
Expand Down Expand Up @@ -233,6 +271,8 @@ export class Enkryptify implements IEnkryptify {

destroy(): void {
if (this.#destroyed) return;
this.#interceptor?.disable();
this.#interceptor = null;
this.#tokenExchange?.destroy();
this.#cache?.clear();
this.#destroyed = true;
Expand Down
7 changes: 7 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,10 @@ export class ProxyValidationError extends EnkryptifyError {
this.detail = detail;
}
}

export class InterceptorError extends EnkryptifyError {
constructor(message: string) {
super(`${message}\nDocs: https://docs.enkryptify.com/sdk/interceptor`);
this.name = "InterceptorError";
}
}
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {
KubernetesAuthError,
ProxyError,
ProxyValidationError,
InterceptorError,
} from "@/errors";
export type {
IEnkryptify,
Expand All @@ -23,4 +24,7 @@ export type {
ProxyRequestInit,
ProxyRequestOptions,
JsonValue,
InterceptorConfig,
InterceptorRule,
InterceptorUrlMatcher,
} from "@/types";
Loading
Loading