kripoint 1.0.0

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/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "kripoint",
3
+ "version": "1.0.0",
4
+ "description": "AES-256-CBC axios interceptor + .NET middleware pair for encrypted HTTP payloads",
5
+ "type": "module",
6
+ "main": "./src/index.js",
7
+ "module": "./src/index.js",
8
+ "types": "./src/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./src/index.js",
12
+ "types": "./src/index.d.ts"
13
+ }
14
+ },
15
+ "files": ["src/"],
16
+ "peerDependencies": {
17
+ "axios": ">=1.0.0"
18
+ },
19
+ "keywords": ["kripoint", "axios", "interceptor", "encryption", "aes", "security", "enterprise"],
20
+ "license": "MIT",
21
+ "engines": { "node": ">=18.0.0" }
22
+ }
@@ -0,0 +1,79 @@
1
+ import { encrypt, decrypt } from "./crypto.js";
2
+
3
+ export function attachKriPointInterceptor(axiosInstance, options = {}) {
4
+ const {
5
+ key,
6
+ decryptResponse = false,
7
+ excludePaths = [],
8
+ onEncryptError = null,
9
+ onDecryptError = null,
10
+ } = options;
11
+
12
+ if (!key) {
13
+ throw new Error("[KriPoint] attachKriPointInterceptor: `key` option is required.");
14
+ }
15
+
16
+ const requestId = axiosInstance.interceptors.request.use(
17
+ async (config) => {
18
+ const method = (config.method || "get").toLowerCase();
19
+ const hasBody = ["post", "put", "patch", "delete"].includes(method);
20
+ const isExcluded = excludePaths.some((p) => (config.url || "").includes(p));
21
+
22
+ if (!hasBody || isExcluded || config.data === undefined || config.data === null) {
23
+ return config;
24
+ }
25
+
26
+ try {
27
+ const value =
28
+ typeof config.data === "string" ? JSON.parse(config.data) : config.data;
29
+
30
+ const encrypted = await encrypt(value, key);
31
+
32
+ config.data = encrypted;
33
+ config.headers["Content-Type"] = "application/json";
34
+ config.headers["X-KriPoint"] = "1";
35
+ } catch (err) {
36
+ if (onEncryptError) {
37
+ onEncryptError(err);
38
+ } else {
39
+ throw err;
40
+ }
41
+ }
42
+
43
+ return config;
44
+ },
45
+ (error) => Promise.reject(error)
46
+ );
47
+
48
+ const responseId = axiosInstance.interceptors.response.use(
49
+ async (response) => {
50
+ if (!decryptResponse) return response;
51
+
52
+ const data = response.data;
53
+ if (data && typeof data.payload === "string" && typeof data.iv === "string") {
54
+ try {
55
+ response.data = await decrypt(data.payload, data.iv, key);
56
+ } catch (err) {
57
+ if (onDecryptError) onDecryptError(err);
58
+ }
59
+ }
60
+
61
+ return response;
62
+ },
63
+ (error) => Promise.reject(error)
64
+ );
65
+
66
+ return {
67
+ detach() {
68
+ axiosInstance.interceptors.request.eject(requestId);
69
+ axiosInstance.interceptors.response.eject(responseId);
70
+ },
71
+ };
72
+ }
73
+
74
+ export async function createKriPointAxios(axiosConfig = {}, interceptorOptions = {}) {
75
+ const axios = (await import("axios")).default;
76
+ const instance = axios.create(axiosConfig);
77
+ attachKriPointInterceptor(instance, interceptorOptions);
78
+ return instance;
79
+ }
package/src/crypto.js ADDED
@@ -0,0 +1,55 @@
1
+ const ALGO = "AES-CBC";
2
+
3
+ function toBase64(buffer) {
4
+ return btoa(String.fromCharCode(...new Uint8Array(buffer)));
5
+ }
6
+
7
+ function fromBase64(b64) {
8
+ return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
9
+ }
10
+
11
+ async function importKey(base64Key) {
12
+ return crypto.subtle.importKey(
13
+ "raw",
14
+ fromBase64(base64Key),
15
+ { name: ALGO },
16
+ false,
17
+ ["encrypt", "decrypt"]
18
+ );
19
+ }
20
+
21
+ export async function encrypt(value, base64Key) {
22
+ const key = await importKey(base64Key);
23
+ const iv = crypto.getRandomValues(new Uint8Array(16));
24
+ const plain = new TextEncoder().encode(JSON.stringify(value));
25
+ const cipher = await crypto.subtle.encrypt({ name: ALGO, iv }, key, plain);
26
+ return { payload: toBase64(cipher), iv: toBase64(iv) };
27
+ }
28
+
29
+ export async function decrypt(payload, iv, base64Key) {
30
+ const key = await importKey(base64Key);
31
+ const plain = await crypto.subtle.decrypt(
32
+ { name: ALGO, iv: fromBase64(iv) },
33
+ key,
34
+ fromBase64(payload)
35
+ );
36
+ return JSON.parse(new TextDecoder().decode(plain));
37
+ }
38
+
39
+ export async function generateBase64Key() {
40
+ const key = await crypto.subtle.generateKey(
41
+ { name: ALGO, length: 256 },
42
+ true,
43
+ ["encrypt", "decrypt"]
44
+ );
45
+ const raw = await crypto.subtle.exportKey("raw", key);
46
+ return toBase64(raw);
47
+ }
48
+
49
+ export function isValidKey(base64Key) {
50
+ try {
51
+ return fromBase64(base64Key).length === 32;
52
+ } catch {
53
+ return false;
54
+ }
55
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import type { AxiosInstance, CreateAxiosDefaults } from "axios";
2
+
3
+ export interface KriPointPayload {
4
+ payload: string;
5
+ iv: string;
6
+ }
7
+
8
+ export interface KriPointInterceptorOptions {
9
+ key: string;
10
+ decryptResponse?: boolean;
11
+ excludePaths?: string[];
12
+ onEncryptError?: (error: Error) => void;
13
+ onDecryptError?: (error: Error) => void;
14
+ }
15
+
16
+ export interface KriPointDetachHandle {
17
+ detach(): void;
18
+ }
19
+
20
+ export declare function attachKriPointInterceptor(
21
+ axiosInstance: AxiosInstance,
22
+ options: KriPointInterceptorOptions
23
+ ): KriPointDetachHandle;
24
+
25
+ export declare function createKriPointAxios(
26
+ axiosConfig?: CreateAxiosDefaults,
27
+ interceptorOptions?: KriPointInterceptorOptions
28
+ ): Promise<AxiosInstance>;
29
+
30
+ export declare function encrypt(value: unknown, base64Key: string): Promise<KriPointPayload>;
31
+ export declare function decrypt(payload: string, iv: string, base64Key: string): Promise<unknown>;
32
+ export declare function generateBase64Key(): Promise<string>;
33
+ export declare function isValidKey(base64Key: string): boolean;
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { attachKriPointInterceptor, createKriPointAxios } from "./axiosInterceptor.js";
2
+ export { encrypt, decrypt, generateBase64Key, isValidKey } from "./crypto.js";