@nr1e/commons 0.3.4 → 0.4.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/dist/encryption/api-key.d.mts +59 -0
- package/dist/encryption/api-key.d.mts.map +1 -0
- package/dist/encryption/api-key.mjs +78 -0
- package/dist/encryption/api-key.mjs.map +1 -0
- package/dist/encryption/api-key.test.d.mts +2 -0
- package/dist/encryption/api-key.test.d.mts.map +1 -0
- package/dist/encryption/api-key.test.mjs +75 -0
- package/dist/encryption/api-key.test.mjs.map +1 -0
- package/dist/encryption/crypto-generator.d.mts +0 -1
- package/dist/encryption/crypto-generator.d.mts.map +1 -1
- package/dist/encryption/crypto-generator.mjs +0 -3
- package/dist/encryption/crypto-generator.mjs.map +1 -1
- package/dist/encryption/crypto-generator.test.mjs +1 -6
- package/dist/encryption/crypto-generator.test.mjs.map +1 -1
- package/dist/encryption/encryption.d.mts +4 -6
- package/dist/encryption/encryption.d.mts.map +1 -1
- package/dist/encryption/index.d.mts +1 -0
- package/dist/encryption/index.d.mts.map +1 -1
- package/dist/encryption/index.mjs +1 -0
- package/dist/encryption/index.mjs.map +1 -1
- package/dist/encryption/rsa-encryption.browser.d.mts +0 -1
- package/dist/encryption/rsa-encryption.browser.d.mts.map +1 -1
- package/dist/encryption/rsa-encryption.d.mts +0 -2
- package/dist/encryption/rsa-encryption.d.mts.map +1 -1
- package/package.json +8 -9
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generated API key.
|
|
3
|
+
*/
|
|
4
|
+
export interface GeneratedApiKey {
|
|
5
|
+
/**
|
|
6
|
+
* The raw key to give to the user. Do not store.
|
|
7
|
+
*/
|
|
8
|
+
readonly rawKey: string;
|
|
9
|
+
/**
|
|
10
|
+
* The ID of the key. This should be used for lookup.
|
|
11
|
+
*/
|
|
12
|
+
readonly keyId: string;
|
|
13
|
+
/**
|
|
14
|
+
* The SHA256 hash of the secret. This should be stored with the keyId.
|
|
15
|
+
*/
|
|
16
|
+
readonly secretHash: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Generates a new API key with a random ID and secret using SHA256.
|
|
20
|
+
*
|
|
21
|
+
* @param prefix - A prefix to add to the key ID and secret. Must be lowercase letters. Default is 'ak'.
|
|
22
|
+
* @param idLength - Length of the key ID. Default is 12.
|
|
23
|
+
* @param secretLength - Length of the secret. Default is 32.
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateApiKey(prefix?: string, idLength?: number, secretLength?: number): GeneratedApiKey;
|
|
26
|
+
export interface ParsedApiKey {
|
|
27
|
+
readonly prefix: string;
|
|
28
|
+
readonly keyId: string;
|
|
29
|
+
readonly secret: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse and validate raw API key format.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseApiKey(rawKey: string): ParsedApiKey;
|
|
35
|
+
/**
|
|
36
|
+
* A stored API key.
|
|
37
|
+
*/
|
|
38
|
+
export interface StoredApiKeyRecord {
|
|
39
|
+
/**
|
|
40
|
+
* The ID of the key.
|
|
41
|
+
*/
|
|
42
|
+
keyId: string;
|
|
43
|
+
/**
|
|
44
|
+
* The SHA256 hash of the secret. This should be stored with the keyId.
|
|
45
|
+
*/
|
|
46
|
+
secretHash: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A function that looks up a stored API key record by key ID.
|
|
50
|
+
*/
|
|
51
|
+
export type ApiKeyLookupFn = (keyId: string) => Promise<StoredApiKeyRecord | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Verifies an API key secret against a stored hash.
|
|
54
|
+
*
|
|
55
|
+
* @param rawKey - The raw API key to verify.
|
|
56
|
+
* @param lookupFn - The function to use to lookup the stored hash.
|
|
57
|
+
*/
|
|
58
|
+
export declare function verifyApiKey(rawKey: string, lookupFn: ApiKeyLookupFn): Promise<StoredApiKeyRecord | null>;
|
|
59
|
+
//# sourceMappingURL=api-key.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.d.mts","sourceRoot":"","sources":["../../src/encryption/api-key.mts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,GAAE,MAAa,EACrB,QAAQ,GAAE,MAAW,EACrB,YAAY,GAAE,MAAW,GACxB,eAAe,CAejB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAkBxD;AAkBD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;AAExC;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAgBpC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { nanoid, customAlphabet } from 'nanoid';
|
|
2
|
+
import { createHash, timingSafeEqual } from 'crypto';
|
|
3
|
+
const PREFIX_REGEX = /^[a-z]+$/;
|
|
4
|
+
const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
5
|
+
/**
|
|
6
|
+
* Generates a new API key with a random ID and secret using SHA256.
|
|
7
|
+
*
|
|
8
|
+
* @param prefix - A prefix to add to the key ID and secret. Must be lowercase letters. Default is 'ak'.
|
|
9
|
+
* @param idLength - Length of the key ID. Default is 12.
|
|
10
|
+
* @param secretLength - Length of the secret. Default is 32.
|
|
11
|
+
*/
|
|
12
|
+
export function generateApiKey(prefix = 'ak', idLength = 12, secretLength = 32) {
|
|
13
|
+
if (!PREFIX_REGEX.test(prefix)) {
|
|
14
|
+
throw new Error('Prefix must contain only lowercase letters (a-z) and no other characters.');
|
|
15
|
+
}
|
|
16
|
+
const keyId = customAlphabet(ALPHABET, idLength)();
|
|
17
|
+
const secret = nanoid(secretLength);
|
|
18
|
+
const fullKey = `${prefix}_${keyId}_${secret}`;
|
|
19
|
+
const secretHash = createHash('sha256').update(secret).digest('hex');
|
|
20
|
+
return {
|
|
21
|
+
rawKey: fullKey,
|
|
22
|
+
keyId,
|
|
23
|
+
secretHash,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse and validate raw API key format.
|
|
28
|
+
*/
|
|
29
|
+
export function parseApiKey(rawKey) {
|
|
30
|
+
const parts = rawKey.split('_');
|
|
31
|
+
if (parts.length < 3) {
|
|
32
|
+
throw new Error('Invalid API key format.');
|
|
33
|
+
}
|
|
34
|
+
const prefix = parts[0];
|
|
35
|
+
const keyId = parts[1];
|
|
36
|
+
const secret = rawKey.substring(prefix.length + keyId.length + 2);
|
|
37
|
+
if (!PREFIX_REGEX.test(prefix)) {
|
|
38
|
+
throw new Error('Invalid API key prefix.');
|
|
39
|
+
}
|
|
40
|
+
if (!keyId || !secret) {
|
|
41
|
+
throw new Error('Malformed API key.');
|
|
42
|
+
}
|
|
43
|
+
return { prefix, keyId, secret };
|
|
44
|
+
}
|
|
45
|
+
function verifySecret(providedSecret, storedSecretHash) {
|
|
46
|
+
const providedHash = createHash('sha256').update(providedSecret).digest();
|
|
47
|
+
const storedHashBuffer = Buffer.from(storedSecretHash, 'hex');
|
|
48
|
+
// Prevent length mismatch timing leaks
|
|
49
|
+
if (providedHash.length !== storedHashBuffer.length) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return timingSafeEqual(providedHash, storedHashBuffer);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Verifies an API key secret against a stored hash.
|
|
56
|
+
*
|
|
57
|
+
* @param rawKey - The raw API key to verify.
|
|
58
|
+
* @param lookupFn - The function to use to lookup the stored hash.
|
|
59
|
+
*/
|
|
60
|
+
export async function verifyApiKey(rawKey, lookupFn) {
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = parseApiKey(rawKey);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const record = await lookupFn(parsed.keyId);
|
|
69
|
+
if (!record) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const valid = verifySecret(parsed.secret, record.secretHash);
|
|
73
|
+
if (!valid) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return record;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=api-key.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.mjs","sourceRoot":"","sources":["../../src/encryption/api-key.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.test.d.mts","sourceRoot":"","sources":["../../src/encryption/api-key.test.mts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { expect, test } from 'vitest';
|
|
2
|
+
import { generateApiKey, parseApiKey, verifyApiKey, } from './api-key.mjs';
|
|
3
|
+
test('generateApiKey creates valid API key with defaults', () => {
|
|
4
|
+
const result = generateApiKey();
|
|
5
|
+
expect(result.rawKey).toMatch(/^ak_[\w-]+_[\w-]+$/);
|
|
6
|
+
expect(result.keyId).toHaveLength(12);
|
|
7
|
+
expect(result.secretHash).toMatch(/^[a-f0-9]{64}$/);
|
|
8
|
+
});
|
|
9
|
+
test('generateApiKey accepts custom parameters', () => {
|
|
10
|
+
const result = generateApiKey('custom', 16, 40);
|
|
11
|
+
expect(result.rawKey.startsWith('custom_')).toBe(true);
|
|
12
|
+
expect(result.keyId).toHaveLength(16);
|
|
13
|
+
});
|
|
14
|
+
test('generateApiKey throws error for invalid prefix', () => {
|
|
15
|
+
expect(() => generateApiKey('AK')).toThrow('Prefix must contain only lowercase letters');
|
|
16
|
+
expect(() => generateApiKey('ak1')).toThrow('Prefix must contain only lowercase letters');
|
|
17
|
+
});
|
|
18
|
+
test('parseApiKey parses valid API key', () => {
|
|
19
|
+
const generated = generateApiKey('test', 12, 32);
|
|
20
|
+
const parsed = parseApiKey(generated.rawKey);
|
|
21
|
+
expect(parsed.prefix).toBe('test');
|
|
22
|
+
expect(parsed.keyId).toBe(generated.keyId);
|
|
23
|
+
expect(parsed.secret).toHaveLength(32);
|
|
24
|
+
});
|
|
25
|
+
test('parseApiKey throws error for invalid format', () => {
|
|
26
|
+
expect(() => parseApiKey('invalid_format')).toThrow('Invalid API key format.');
|
|
27
|
+
expect(() => parseApiKey('AK_keyid_secret')).toThrow('Invalid API key prefix.');
|
|
28
|
+
expect(() => parseApiKey('ak__secret')).toThrow('Malformed API key');
|
|
29
|
+
});
|
|
30
|
+
test('verifyApiKey verifies valid key successfully', async () => {
|
|
31
|
+
const generated = generateApiKey();
|
|
32
|
+
const storedRecord = {
|
|
33
|
+
keyId: generated.keyId,
|
|
34
|
+
secretHash: generated.secretHash,
|
|
35
|
+
};
|
|
36
|
+
const lookupFn = async (keyId) => {
|
|
37
|
+
return keyId === storedRecord.keyId ? storedRecord : null;
|
|
38
|
+
};
|
|
39
|
+
const result = await verifyApiKey(generated.rawKey, lookupFn);
|
|
40
|
+
expect(result).toEqual(storedRecord);
|
|
41
|
+
});
|
|
42
|
+
test('verifyApiKey returns null for invalid key', async () => {
|
|
43
|
+
const lookupFn = async () => null;
|
|
44
|
+
const result = await verifyApiKey('invalid_key_format', lookupFn);
|
|
45
|
+
expect(result).toBeNull();
|
|
46
|
+
});
|
|
47
|
+
test('verifyApiKey returns null when secret does not match', async () => {
|
|
48
|
+
const generated = generateApiKey();
|
|
49
|
+
const storedRecord = {
|
|
50
|
+
keyId: generated.keyId,
|
|
51
|
+
secretHash: 'wronghash123456789012345678901234567890123456789012345678901234',
|
|
52
|
+
};
|
|
53
|
+
const lookupFn = async () => storedRecord;
|
|
54
|
+
const result = await verifyApiKey(generated.rawKey, lookupFn);
|
|
55
|
+
expect(result).toBeNull();
|
|
56
|
+
});
|
|
57
|
+
test('full flow: generate, store, and verify', async () => {
|
|
58
|
+
// Generate key
|
|
59
|
+
const generated = generateApiKey('api', 12, 32);
|
|
60
|
+
console.log(generated.rawKey);
|
|
61
|
+
// Simulate storage
|
|
62
|
+
const database = new Map();
|
|
63
|
+
database.set(generated.keyId, {
|
|
64
|
+
keyId: generated.keyId,
|
|
65
|
+
secretHash: generated.secretHash,
|
|
66
|
+
});
|
|
67
|
+
// Verify
|
|
68
|
+
const lookupFn = async (keyId) => {
|
|
69
|
+
return database.get(keyId) || null;
|
|
70
|
+
};
|
|
71
|
+
const verified = await verifyApiKey(generated.rawKey, lookupFn);
|
|
72
|
+
expect(verified).not.toBeNull();
|
|
73
|
+
expect(verified?.keyId).toBe(generated.keyId);
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=api-key.test.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.test.mjs","sourceRoot":"","sources":["../../src/encryption/api-key.test.mts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-generator.d.mts","sourceRoot":"","sources":["../../src/encryption/crypto-generator.mts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAEtD
|
|
1
|
+
{"version":3,"file":"crypto-generator.d.mts","sourceRoot":"","sources":["../../src/encryption/crypto-generator.mts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAEtD"}
|
|
@@ -2,7 +2,4 @@ import { randomBytes } from 'crypto';
|
|
|
2
2
|
export function generateId(length = 16) {
|
|
3
3
|
return randomBytes(length).toString('base64url');
|
|
4
4
|
}
|
|
5
|
-
export function generateApiKey(length = 32) {
|
|
6
|
-
return randomBytes(length).toString('base64url');
|
|
7
|
-
}
|
|
8
5
|
//# sourceMappingURL=crypto-generator.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-generator.mjs","sourceRoot":"","sources":["../../src/encryption/crypto-generator.mts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,QAAQ,CAAC;AAEnC,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE;IAC5C,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnD,CAAC
|
|
1
|
+
{"version":3,"file":"crypto-generator.mjs","sourceRoot":"","sources":["../../src/encryption/crypto-generator.mts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,QAAQ,CAAC;AAEnC,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE;IAC5C,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { test, expect } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { generateId } from './crypto-generator.mjs';
|
|
3
3
|
test('generateId', () => {
|
|
4
4
|
const id = generateId();
|
|
5
5
|
console.log(id);
|
|
6
6
|
expect(id.length).toBe(22);
|
|
7
7
|
});
|
|
8
|
-
test('Test generateApiKey', () => {
|
|
9
|
-
const apiKey = generateApiKey();
|
|
10
|
-
console.log(apiKey);
|
|
11
|
-
expect(apiKey).toBeDefined();
|
|
12
|
-
}, 10000);
|
|
13
8
|
//# sourceMappingURL=crypto-generator.test.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-generator.test.mjs","sourceRoot":"","sources":["../../src/encryption/crypto-generator.test.mts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,MAAM,EAAC,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"crypto-generator.test.mjs","sourceRoot":"","sources":["../../src/encryption/crypto-generator.test.mts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,MAAM,EAAC,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,wBAAwB,CAAC;AAElD,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE;IACtB,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IACxB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
3
1
|
export declare function localEncrypt(val: object, key: Buffer | string): string;
|
|
4
2
|
export declare function localDecrypt(encrypted: string, key: Buffer | string): any;
|
|
5
|
-
export declare function generateKey(size?: number):
|
|
3
|
+
export declare function generateKey(size?: number): NonSharedBuffer;
|
|
6
4
|
export declare function generateEncodedKey(size?: number): string;
|
|
7
|
-
export declare function generateIV(size?: number):
|
|
5
|
+
export declare function generateIV(size?: number): NonSharedBuffer;
|
|
8
6
|
export declare function generateEncodedIV(size?: number): string;
|
|
9
|
-
export declare function decodeKey(encodedKey: string): Buffer
|
|
10
|
-
export declare function decodeIV(encodedIV: string): Buffer
|
|
7
|
+
export declare function decodeKey(encodedKey: string): Buffer<ArrayBuffer>;
|
|
8
|
+
export declare function decodeIV(encodedIV: string): Buffer<ArrayBuffer>;
|
|
11
9
|
//# sourceMappingURL=encryption.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.d.mts","sourceRoot":"","sources":["../../src/encryption/encryption.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encryption.d.mts","sourceRoot":"","sources":["../../src/encryption/encryption.mts"],"names":[],"mappings":"AAMA,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,UAS7D;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,OAanE;AAED,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,mBAExC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,UAE/C;AAED,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,mBAEvC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,UAE9C;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,uBAE3C;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,uBAEzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/encryption/index.mts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/encryption/index.mts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/encryption/index.mts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/encryption/index.mts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Browser-compatible RSA encryption using Web Crypto API
|
|
3
3
|
* This module provides RSA encryption functionality that works in browsers
|
|
4
4
|
*/
|
|
5
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
6
5
|
export type KeyFormat = 'pem' | 'base64';
|
|
7
6
|
export interface EncryptionOptions {
|
|
8
7
|
encoding?: BufferEncoding;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-encryption.browser.d.mts","sourceRoot":"","sources":["../../src/encryption/rsa-encryption.browser.mts"],"names":[],"mappings":"AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"rsa-encryption.browser.d.mts","sourceRoot":"","sources":["../../src/encryption/rsa-encryption.browser.mts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEzC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AA0DD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,SAAS,EAAE,MAAM,EAEjB,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAapE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,QAAQ,GAAG,SAAoB,GACpC,MAAM,CAqBR;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAM9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-encryption.d.mts","sourceRoot":"","sources":["../../src/encryption/rsa-encryption.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rsa-encryption.d.mts","sourceRoot":"","sources":["../../src/encryption/rsa-encryption.mts"],"names":[],"mappings":"AAAA,OAAO,EAML,SAAS,EAGV,MAAM,QAAQ,CAAC;AAKhB,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEzC,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAoDD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,sBAA2B,GACnC,UAAU,CAuBZ;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,UAAU,CAAC,CAuBrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAqBR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,GAAG,MAAM,CA8BjB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAG,UAAU,CAiB7E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,iBAAiB,CAQnB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAYrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsB9C"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nr1e/commons",
|
|
3
3
|
"description": "Common utilities for TypeScript projects",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "NR1E, Inc.",
|
|
7
7
|
"publishConfig": {
|
|
@@ -16,19 +16,18 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@eslint/js": "
|
|
20
|
-
"@types/node": "^
|
|
21
|
-
"@types/uuid": "^10.0.0",
|
|
19
|
+
"@eslint/js": "^9.39.2",
|
|
20
|
+
"@types/node": "^24.10.13",
|
|
22
21
|
"eslint": "9.39.2",
|
|
23
22
|
"prettier": "3.8.1",
|
|
24
|
-
"typescript": "5.
|
|
25
|
-
"typescript-eslint": "8.
|
|
23
|
+
"typescript": "5.9.3",
|
|
24
|
+
"typescript-eslint": "8.56.0",
|
|
26
25
|
"vitest": "4.0.18"
|
|
27
26
|
},
|
|
28
27
|
"dependencies": {
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
28
|
+
"ksuid": "3.0.0",
|
|
29
|
+
"nanoid": "^5.1.6",
|
|
30
|
+
"uuid": "^13.0.0"
|
|
32
31
|
},
|
|
33
32
|
"exports": {
|
|
34
33
|
"./bitsnbytes": {
|