tiny-essentials 1.1.0 โ 1.2.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/README.md +3 -0
- package/dist/TinyBasicsEs.js +2784 -0
- package/dist/TinyBasicsEs.min.js +2 -0
- package/dist/TinyBasicsEs.min.js.LICENSE.txt +8 -0
- package/dist/TinyCertCrypto.js +76229 -0
- package/dist/TinyCertCrypto.min.js +2 -0
- package/dist/TinyCertCrypto.min.js.LICENSE.txt +10 -0
- package/dist/TinyCrypto.js +48115 -0
- package/dist/TinyCrypto.min.js +2 -0
- package/dist/TinyCrypto.min.js.LICENSE.txt +10 -0
- package/dist/TinyEssentials.js +77599 -0
- package/dist/TinyEssentials.min.js +2 -1
- package/dist/TinyEssentials.min.js.LICENSE.txt +10 -0
- package/dist/TinyLevelUp.js +173 -0
- package/dist/TinyLevelUp.min.js +1 -0
- package/dist/v1/basics/index.cjs +27 -0
- package/dist/v1/basics/index.d.mts +17 -0
- package/dist/v1/basics/index.mjs +7 -0
- package/dist/v1/basics/objFilter.cjs +5 -3
- package/dist/v1/basics/objFilter.mjs +3 -2
- package/dist/v1/build/TinyCertCrypto.cjs +7 -0
- package/dist/v1/build/TinyCertCrypto.d.mts +2 -0
- package/dist/v1/build/TinyCertCrypto.mjs +2 -0
- package/dist/v1/build/TinyCrypto.cjs +7 -0
- package/dist/v1/build/TinyCrypto.d.mts +2 -0
- package/dist/v1/build/TinyCrypto.mjs +2 -0
- package/dist/v1/build/TinyLevelUp.cjs +7 -0
- package/dist/v1/build/TinyLevelUp.d.mts +2 -0
- package/dist/v1/build/TinyLevelUp.mjs +2 -0
- package/dist/v1/index.cjs +2 -0
- package/dist/v1/index.d.mts +2 -1
- package/dist/v1/index.mjs +2 -1
- package/dist/v1/libs/TinyCertCrypto.cjs +514 -0
- package/dist/v1/libs/TinyCertCrypto.d.mts +191 -0
- package/dist/v1/libs/TinyCertCrypto.mjs +450 -0
- package/dist/v1/libs/TinyCrypto.cjs +69 -62
- package/dist/v1/libs/TinyCrypto.d.mts +1 -0
- package/dist/v1/libs/TinyCrypto.mjs +59 -50
- package/docs/README.md +2 -0
- package/docs/libs/TinyCertCrypto.md +202 -0
- package/docs/libs/TinyCrypto.md +2 -2
- package/package.json +11 -6
- package/webpack.config.mjs +69 -0
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
4
|
var fs = require('fs');
|
|
5
|
+
var buffer = require('buffer');
|
|
5
6
|
var objFilter = require('../basics/objFilter.cjs');
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Determines if the environment is a browser.
|
|
10
|
+
*
|
|
11
|
+
* This constant checks if the code is running in a browser environment by verifying if
|
|
12
|
+
* the `window` object and the `window.document` object are available. It will return `true`
|
|
13
|
+
* if the environment is a browser, and `false` otherwise (e.g., in a Node.js environment).
|
|
14
|
+
*
|
|
15
|
+
* @constant {boolean}
|
|
16
|
+
*/
|
|
8
17
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
9
18
|
|
|
10
19
|
/**
|
|
@@ -99,7 +108,7 @@ class TinyCrypto {
|
|
|
99
108
|
});
|
|
100
109
|
|
|
101
110
|
let encrypted = cipher.update(plainText, this.inputEncoding);
|
|
102
|
-
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
|
111
|
+
encrypted = buffer.Buffer.concat([encrypted, cipher.final()]);
|
|
103
112
|
const authTag = cipher.getAuthTag();
|
|
104
113
|
|
|
105
114
|
return {
|
|
@@ -134,9 +143,9 @@ class TinyCrypto {
|
|
|
134
143
|
* console.log(decrypted); // Outputs: 'Hello, world!'
|
|
135
144
|
*/
|
|
136
145
|
decrypt({ iv, encrypted, authTag }, expectedType = null) {
|
|
137
|
-
const ivBuffer = Buffer.from(iv, this.outputEncoding);
|
|
138
|
-
const encryptedBuffer = Buffer.from(encrypted, this.outputEncoding);
|
|
139
|
-
const authTagBuffer = Buffer.from(authTag, this.outputEncoding);
|
|
146
|
+
const ivBuffer = buffer.Buffer.from(iv, this.outputEncoding);
|
|
147
|
+
const encryptedBuffer = buffer.Buffer.from(encrypted, this.outputEncoding);
|
|
148
|
+
const authTagBuffer = buffer.Buffer.from(authTag, this.outputEncoding);
|
|
140
149
|
|
|
141
150
|
const decipher = crypto.createDecipheriv(this.algorithm, this.key, ivBuffer, {
|
|
142
151
|
authTagLength: this.authTagLength,
|
|
@@ -174,9 +183,9 @@ class TinyCrypto {
|
|
|
174
183
|
* console.log(dataType); // Outputs: 'string'
|
|
175
184
|
*/
|
|
176
185
|
getTypeFromEncrypted({ iv, encrypted, authTag }) {
|
|
177
|
-
const ivBuffer = Buffer.from(iv, this.outputEncoding);
|
|
178
|
-
const encryptedBuffer = Buffer.from(encrypted, this.outputEncoding);
|
|
179
|
-
const authTagBuffer = Buffer.from(authTag, this.outputEncoding);
|
|
186
|
+
const ivBuffer = buffer.Buffer.from(iv, this.outputEncoding);
|
|
187
|
+
const encryptedBuffer = buffer.Buffer.from(encrypted, this.outputEncoding);
|
|
188
|
+
const authTagBuffer = buffer.Buffer.from(authTag, this.outputEncoding);
|
|
180
189
|
|
|
181
190
|
const decipher = crypto.createDecipheriv(this.algorithm, this.key, ivBuffer, {
|
|
182
191
|
authTagLength: this.authTagLength,
|
|
@@ -188,7 +197,7 @@ class TinyCrypto {
|
|
|
188
197
|
decrypted += decipher.final(this.inputEncoding);
|
|
189
198
|
|
|
190
199
|
const { type } = this.#deserialize(decrypted);
|
|
191
|
-
return typeof type === 'string' ? type
|
|
200
|
+
return typeof type === 'string' ? type : 'unknown';
|
|
192
201
|
}
|
|
193
202
|
|
|
194
203
|
/**
|
|
@@ -322,7 +331,7 @@ class TinyCrypto {
|
|
|
322
331
|
const reader = new FileReader();
|
|
323
332
|
reader.onload = () => {
|
|
324
333
|
const hexKey = reader.result.trim();
|
|
325
|
-
const keyBuffer = Buffer.from(hexKey, 'hex');
|
|
334
|
+
const keyBuffer = buffer.Buffer.from(hexKey, 'hex');
|
|
326
335
|
this.key = keyBuffer;
|
|
327
336
|
resolve(keyBuffer);
|
|
328
337
|
};
|
|
@@ -331,7 +340,7 @@ class TinyCrypto {
|
|
|
331
340
|
});
|
|
332
341
|
} else {
|
|
333
342
|
const hexKey = fs.readFileSync(file, 'utf8');
|
|
334
|
-
const keyBuffer = Buffer.from(hexKey, 'hex');
|
|
343
|
+
const keyBuffer = buffer.Buffer.from(hexKey, 'hex');
|
|
335
344
|
this.key = keyBuffer;
|
|
336
345
|
return keyBuffer;
|
|
337
346
|
}
|
|
@@ -409,7 +418,7 @@ class TinyCrypto {
|
|
|
409
418
|
else if (typeof config.authTagLength !== 'undefined')
|
|
410
419
|
throw new Error('Invalid or missing "authTagLength" property. Expected a number.');
|
|
411
420
|
|
|
412
|
-
if (typeof config.key === 'string') this.key = Buffer.from(config.key, 'hex');
|
|
421
|
+
if (typeof config.key === 'string') this.key = buffer.Buffer.from(config.key, 'hex');
|
|
413
422
|
else if (typeof config.key !== 'undefined')
|
|
414
423
|
throw new Error('Invalid or missing "key" property. Expected a hexadecimal string.');
|
|
415
424
|
}
|
|
@@ -458,29 +467,29 @@ class TinyCrypto {
|
|
|
458
467
|
function: () => {
|
|
459
468
|
throw new Error('Function cannot be serialized');
|
|
460
469
|
},
|
|
461
|
-
regexp: (data) => JSON.stringify({ __type: '
|
|
462
|
-
htmlElement: (data) => JSON.stringify({ __type: '
|
|
463
|
-
date: (data) => JSON.stringify({ __type: '
|
|
464
|
-
bigint: (data) => JSON.stringify({ __type: '
|
|
465
|
-
number: (data) => JSON.stringify({ __type: '
|
|
466
|
-
boolean: (data) => JSON.stringify({ __type: '
|
|
467
|
-
string: (data) => JSON.stringify({ __type: '
|
|
468
|
-
null: (data) => JSON.stringify({ __type: '
|
|
469
|
-
undefined: (data) => JSON.stringify({ __type: '
|
|
470
|
+
regexp: (data) => JSON.stringify({ __type: 'regexp', value: data.toString() }),
|
|
471
|
+
htmlElement: (data) => JSON.stringify({ __type: 'htmlelement', value: data.outerHTML }),
|
|
472
|
+
date: (data) => JSON.stringify({ __type: 'date', value: data.toISOString() }),
|
|
473
|
+
bigint: (data) => JSON.stringify({ __type: 'bigint', value: data.toString() }),
|
|
474
|
+
number: (data) => JSON.stringify({ __type: 'number', value: data }),
|
|
475
|
+
boolean: (data) => JSON.stringify({ __type: 'boolean', value: data }),
|
|
476
|
+
string: (data) => JSON.stringify({ __type: 'string', value: data }),
|
|
477
|
+
null: (data) => JSON.stringify({ __type: 'null' }),
|
|
478
|
+
undefined: (data) => JSON.stringify({ __type: 'undefined' }),
|
|
470
479
|
map: (data) =>
|
|
471
480
|
JSON.stringify({
|
|
472
|
-
__type: '
|
|
481
|
+
__type: 'map',
|
|
473
482
|
value: Array.from(data.entries()),
|
|
474
483
|
}),
|
|
475
484
|
set: (data) =>
|
|
476
485
|
JSON.stringify({
|
|
477
|
-
__type: '
|
|
486
|
+
__type: 'set',
|
|
478
487
|
value: Array.from(data.values()),
|
|
479
488
|
}),
|
|
480
|
-
symbol: (data) => JSON.stringify({ __type: '
|
|
481
|
-
array: (data) => JSON.stringify({ __type: '
|
|
482
|
-
object: (data) => JSON.stringify({ __type: '
|
|
483
|
-
buffer: (data) => JSON.stringify({ __type: '
|
|
489
|
+
symbol: (data) => JSON.stringify({ __type: 'symbol', value: data.description }),
|
|
490
|
+
array: (data) => JSON.stringify({ __type: 'array', value: data }),
|
|
491
|
+
object: (data) => JSON.stringify({ __type: 'object', value: data }),
|
|
492
|
+
buffer: (data) => JSON.stringify({ __type: 'buffer', value: data.toString('base64') }),
|
|
484
493
|
};
|
|
485
494
|
|
|
486
495
|
/**
|
|
@@ -492,47 +501,47 @@ class TinyCrypto {
|
|
|
492
501
|
* and the value is a function that deserializes the value to its original format.
|
|
493
502
|
*
|
|
494
503
|
* @type {Object}
|
|
495
|
-
* @property {Function}
|
|
496
|
-
* @property {Function}
|
|
497
|
-
* @property {Function}
|
|
498
|
-
* @property {Function}
|
|
499
|
-
* @property {Function}
|
|
500
|
-
* @property {Function}
|
|
501
|
-
* @property {Function}
|
|
502
|
-
* @property {Function}
|
|
503
|
-
* @property {Function}
|
|
504
|
-
* @property {Function}
|
|
505
|
-
* @property {Function}
|
|
506
|
-
* @property {Function}
|
|
507
|
-
* @property {Function}
|
|
508
|
-
* @property {Function}
|
|
509
|
-
* @property {Function}
|
|
504
|
+
* @property {Function} regexp - Deserializes a regular expression from its string representation (e.g., `/pattern/flags`).
|
|
505
|
+
* @property {Function} htmlelement - Deserializes an HTML element from its serialized outerHTML string (only works in browser environments).
|
|
506
|
+
* @property {Function} date - Deserializes a date from its ISO string representation.
|
|
507
|
+
* @property {Function} bigint - Deserializes a BigInt from its string representation.
|
|
508
|
+
* @property {Function} number - Deserializes a number from its string or numeric representation.
|
|
509
|
+
* @property {Function} boolean - Deserializes a boolean value from its string representation.
|
|
510
|
+
* @property {Function} null - Deserializes the `null` value.
|
|
511
|
+
* @property {Function} undefined - Deserializes the `undefined` value.
|
|
512
|
+
* @property {Function} map - Deserializes a Map from an array of key-value pairs.
|
|
513
|
+
* @property {Function} set - Deserializes a Set from an array of values.
|
|
514
|
+
* @property {Function} symbol - Deserializes a Symbol from its string description.
|
|
515
|
+
* @property {Function} array - Deserializes an array from its serialized representation.
|
|
516
|
+
* @property {Function} object - Deserializes a plain JSON object from its serialized representation.
|
|
517
|
+
* @property {Function} string - Deserializes a string from its serialized representation.
|
|
518
|
+
* @property {Function} buffer - Deserializes a Buffer from its base64-encoded string representation.
|
|
510
519
|
*/
|
|
511
520
|
#valueTypes = {
|
|
512
|
-
|
|
521
|
+
regexp: (value) => {
|
|
513
522
|
const match = value.match(/^\/(.*)\/([gimsuy]*)$/);
|
|
514
523
|
return match ? new RegExp(match[1], match[2]) : new RegExp(value);
|
|
515
524
|
},
|
|
516
|
-
|
|
525
|
+
htmlelement: (value) => {
|
|
517
526
|
if (typeof document === 'undefined')
|
|
518
527
|
throw new Error('HTMLElement deserialization is only supported in browsers');
|
|
519
528
|
const div = document.createElement('div');
|
|
520
529
|
div.innerHTML = value;
|
|
521
530
|
return div.firstElementChild;
|
|
522
531
|
},
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
532
|
+
date: (value) => new Date(value),
|
|
533
|
+
bigint: (value) => BigInt(value),
|
|
534
|
+
number: (value) => Number(value),
|
|
535
|
+
boolean: (value) => Boolean(value),
|
|
536
|
+
null: (value) => null,
|
|
537
|
+
undefined: (value) => undefined,
|
|
538
|
+
map: (value) => new Map(value),
|
|
539
|
+
set: (value) => new Set(value),
|
|
540
|
+
symbol: (value) => Symbol(value),
|
|
541
|
+
array: (value) => value,
|
|
542
|
+
object: (value) => value,
|
|
543
|
+
string: (value) => String(value),
|
|
544
|
+
buffer: (value) => buffer.Buffer.from(value, 'base64'),
|
|
536
545
|
};
|
|
537
546
|
|
|
538
547
|
/**
|
|
@@ -564,7 +573,7 @@ class TinyCrypto {
|
|
|
564
573
|
const parsed = JSON.parse(text);
|
|
565
574
|
const type = parsed.__type;
|
|
566
575
|
|
|
567
|
-
if (typeof type !== 'string') return { value: text, type: '
|
|
576
|
+
if (typeof type !== 'string') return { value: text, type: 'string' };
|
|
568
577
|
if (typeof this.#valueTypes[type] === 'function')
|
|
569
578
|
return {
|
|
570
579
|
value: this.#valueTypes[type](parsed.value),
|
|
@@ -586,10 +595,8 @@ class TinyCrypto {
|
|
|
586
595
|
* @throws {Error} If the types do not match.
|
|
587
596
|
*/
|
|
588
597
|
#validateDeserializedType(expected, actual) {
|
|
589
|
-
if (expected
|
|
590
|
-
throw new Error(
|
|
591
|
-
`Type mismatch: expected ${expected.toLowerCase()}, but got ${actual.toLowerCase()}`,
|
|
592
|
-
);
|
|
598
|
+
if (expected !== actual)
|
|
599
|
+
throw new Error(`Type mismatch: expected ${expected}, but got ${actual}`);
|
|
593
600
|
}
|
|
594
601
|
}
|
|
595
602
|
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
import fs from 'fs';
|
|
3
|
+
import { Buffer } from 'buffer';
|
|
3
4
|
import { objType } from '../../v1/basics/objFilter.mjs';
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Determines if the environment is a browser.
|
|
7
|
+
*
|
|
8
|
+
* This constant checks if the code is running in a browser environment by verifying if
|
|
9
|
+
* the `window` object and the `window.document` object are available. It will return `true`
|
|
10
|
+
* if the environment is a browser, and `false` otherwise (e.g., in a Node.js environment).
|
|
11
|
+
*
|
|
12
|
+
* @constant {boolean}
|
|
13
|
+
*/
|
|
5
14
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
6
15
|
/**
|
|
7
16
|
* TinyCrypto is a utility class that provides methods for secure key generation,
|
|
@@ -169,7 +178,7 @@ class TinyCrypto {
|
|
|
169
178
|
let decrypted = decipher.update(encryptedBuffer, null, this.inputEncoding);
|
|
170
179
|
decrypted += decipher.final(this.inputEncoding);
|
|
171
180
|
const { type } = this.#deserialize(decrypted);
|
|
172
|
-
return typeof type === 'string' ? type
|
|
181
|
+
return typeof type === 'string' ? type : 'unknown';
|
|
173
182
|
}
|
|
174
183
|
/**
|
|
175
184
|
* Saves the cryptographic key to a file.
|
|
@@ -440,27 +449,27 @@ class TinyCrypto {
|
|
|
440
449
|
function: () => {
|
|
441
450
|
throw new Error('Function cannot be serialized');
|
|
442
451
|
},
|
|
443
|
-
regexp: (data) => JSON.stringify({ __type: '
|
|
444
|
-
htmlElement: (data) => JSON.stringify({ __type: '
|
|
445
|
-
date: (data) => JSON.stringify({ __type: '
|
|
446
|
-
bigint: (data) => JSON.stringify({ __type: '
|
|
447
|
-
number: (data) => JSON.stringify({ __type: '
|
|
448
|
-
boolean: (data) => JSON.stringify({ __type: '
|
|
449
|
-
string: (data) => JSON.stringify({ __type: '
|
|
450
|
-
null: (data) => JSON.stringify({ __type: '
|
|
451
|
-
undefined: (data) => JSON.stringify({ __type: '
|
|
452
|
+
regexp: (data) => JSON.stringify({ __type: 'regexp', value: data.toString() }),
|
|
453
|
+
htmlElement: (data) => JSON.stringify({ __type: 'htmlelement', value: data.outerHTML }),
|
|
454
|
+
date: (data) => JSON.stringify({ __type: 'date', value: data.toISOString() }),
|
|
455
|
+
bigint: (data) => JSON.stringify({ __type: 'bigint', value: data.toString() }),
|
|
456
|
+
number: (data) => JSON.stringify({ __type: 'number', value: data }),
|
|
457
|
+
boolean: (data) => JSON.stringify({ __type: 'boolean', value: data }),
|
|
458
|
+
string: (data) => JSON.stringify({ __type: 'string', value: data }),
|
|
459
|
+
null: (data) => JSON.stringify({ __type: 'null' }),
|
|
460
|
+
undefined: (data) => JSON.stringify({ __type: 'undefined' }),
|
|
452
461
|
map: (data) => JSON.stringify({
|
|
453
|
-
__type: '
|
|
462
|
+
__type: 'map',
|
|
454
463
|
value: Array.from(data.entries()),
|
|
455
464
|
}),
|
|
456
465
|
set: (data) => JSON.stringify({
|
|
457
|
-
__type: '
|
|
466
|
+
__type: 'set',
|
|
458
467
|
value: Array.from(data.values()),
|
|
459
468
|
}),
|
|
460
|
-
symbol: (data) => JSON.stringify({ __type: '
|
|
461
|
-
array: (data) => JSON.stringify({ __type: '
|
|
462
|
-
object: (data) => JSON.stringify({ __type: '
|
|
463
|
-
buffer: (data) => JSON.stringify({ __type: '
|
|
469
|
+
symbol: (data) => JSON.stringify({ __type: 'symbol', value: data.description }),
|
|
470
|
+
array: (data) => JSON.stringify({ __type: 'array', value: data }),
|
|
471
|
+
object: (data) => JSON.stringify({ __type: 'object', value: data }),
|
|
472
|
+
buffer: (data) => JSON.stringify({ __type: 'buffer', value: data.toString('base64') }),
|
|
464
473
|
};
|
|
465
474
|
/**
|
|
466
475
|
* A mapping of data types to their deserialization functions.
|
|
@@ -471,47 +480,47 @@ class TinyCrypto {
|
|
|
471
480
|
* and the value is a function that deserializes the value to its original format.
|
|
472
481
|
*
|
|
473
482
|
* @type {Object}
|
|
474
|
-
* @property {Function}
|
|
475
|
-
* @property {Function}
|
|
476
|
-
* @property {Function}
|
|
477
|
-
* @property {Function}
|
|
478
|
-
* @property {Function}
|
|
479
|
-
* @property {Function}
|
|
480
|
-
* @property {Function}
|
|
481
|
-
* @property {Function}
|
|
482
|
-
* @property {Function}
|
|
483
|
-
* @property {Function}
|
|
484
|
-
* @property {Function}
|
|
485
|
-
* @property {Function}
|
|
486
|
-
* @property {Function}
|
|
487
|
-
* @property {Function}
|
|
488
|
-
* @property {Function}
|
|
483
|
+
* @property {Function} regexp - Deserializes a regular expression from its string representation (e.g., `/pattern/flags`).
|
|
484
|
+
* @property {Function} htmlelement - Deserializes an HTML element from its serialized outerHTML string (only works in browser environments).
|
|
485
|
+
* @property {Function} date - Deserializes a date from its ISO string representation.
|
|
486
|
+
* @property {Function} bigint - Deserializes a BigInt from its string representation.
|
|
487
|
+
* @property {Function} number - Deserializes a number from its string or numeric representation.
|
|
488
|
+
* @property {Function} boolean - Deserializes a boolean value from its string representation.
|
|
489
|
+
* @property {Function} null - Deserializes the `null` value.
|
|
490
|
+
* @property {Function} undefined - Deserializes the `undefined` value.
|
|
491
|
+
* @property {Function} map - Deserializes a Map from an array of key-value pairs.
|
|
492
|
+
* @property {Function} set - Deserializes a Set from an array of values.
|
|
493
|
+
* @property {Function} symbol - Deserializes a Symbol from its string description.
|
|
494
|
+
* @property {Function} array - Deserializes an array from its serialized representation.
|
|
495
|
+
* @property {Function} object - Deserializes a plain JSON object from its serialized representation.
|
|
496
|
+
* @property {Function} string - Deserializes a string from its serialized representation.
|
|
497
|
+
* @property {Function} buffer - Deserializes a Buffer from its base64-encoded string representation.
|
|
489
498
|
*/
|
|
490
499
|
#valueTypes = {
|
|
491
|
-
|
|
500
|
+
regexp: (value) => {
|
|
492
501
|
const match = value.match(/^\/(.*)\/([gimsuy]*)$/);
|
|
493
502
|
return match ? new RegExp(match[1], match[2]) : new RegExp(value);
|
|
494
503
|
},
|
|
495
|
-
|
|
504
|
+
htmlelement: (value) => {
|
|
496
505
|
if (typeof document === 'undefined')
|
|
497
506
|
throw new Error('HTMLElement deserialization is only supported in browsers');
|
|
498
507
|
const div = document.createElement('div');
|
|
499
508
|
div.innerHTML = value;
|
|
500
509
|
return div.firstElementChild;
|
|
501
510
|
},
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
511
|
+
date: (value) => new Date(value),
|
|
512
|
+
bigint: (value) => BigInt(value),
|
|
513
|
+
number: (value) => Number(value),
|
|
514
|
+
boolean: (value) => Boolean(value),
|
|
515
|
+
null: (value) => null,
|
|
516
|
+
undefined: (value) => undefined,
|
|
517
|
+
map: (value) => new Map(value),
|
|
518
|
+
set: (value) => new Set(value),
|
|
519
|
+
symbol: (value) => Symbol(value),
|
|
520
|
+
array: (value) => value,
|
|
521
|
+
object: (value) => value,
|
|
522
|
+
string: (value) => String(value),
|
|
523
|
+
buffer: (value) => Buffer.from(value, 'base64'),
|
|
515
524
|
};
|
|
516
525
|
/**
|
|
517
526
|
* Serializes a given data value into a JSON-compatible format based on its type.
|
|
@@ -542,7 +551,7 @@ class TinyCrypto {
|
|
|
542
551
|
const parsed = JSON.parse(text);
|
|
543
552
|
const type = parsed.__type;
|
|
544
553
|
if (typeof type !== 'string')
|
|
545
|
-
return { value: text, type: '
|
|
554
|
+
return { value: text, type: 'string' };
|
|
546
555
|
if (typeof this.#valueTypes[type] === 'function')
|
|
547
556
|
return {
|
|
548
557
|
value: this.#valueTypes[type](parsed.value),
|
|
@@ -565,8 +574,8 @@ class TinyCrypto {
|
|
|
565
574
|
* @throws {Error} If the types do not match.
|
|
566
575
|
*/
|
|
567
576
|
#validateDeserializedType(expected, actual) {
|
|
568
|
-
if (expected
|
|
569
|
-
throw new Error(`Type mismatch: expected ${expected
|
|
577
|
+
if (expected !== actual)
|
|
578
|
+
throw new Error(`Type mismatch: expected ${expected}, but got ${actual}`);
|
|
570
579
|
}
|
|
571
580
|
}
|
|
572
581
|
export default TinyCrypto;
|
package/docs/README.md
CHANGED
|
@@ -14,6 +14,8 @@ This folder contains external libraries and utility modules that are designed to
|
|
|
14
14
|
|
|
15
15
|
- ๐ **[TinyCrypto.md](./libs/TinyCrypto.md)** โ A flexible and browser-compatible AES-256-GCM encryption utility with support for complex JavaScript types like `Date`, `RegExp`, `Buffer`, and even DOM elements (in the browser).
|
|
16
16
|
|
|
17
|
+
- ๐ **[TinyCertCrypto.md](./libs/TinyCertCrypto.md)** โ A lightweight tool for managing RSA key pairs and X.509 certificates with support for generation, PEM parsing, encryption/decryption of JSON, and certificate metadata extraction. Works in both Node.js and browser environments (with limitations in browser).
|
|
18
|
+
|
|
17
19
|
---
|
|
18
20
|
|
|
19
21
|
### 2. **`basics/`**
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# โจ Tiny Cert Crypto
|
|
2
|
+
|
|
3
|
+
A lightweight ๐ utility for managing, generating, and handling **X.509 certificates** and **RSA key pairs**.
|
|
4
|
+
Built with flexibility in mind โ runs seamlessly in both **Node.js** and **browser** environments! ๐
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## ๐ฆ Features
|
|
9
|
+
|
|
10
|
+
- ๐ ๏ธ RSA key pair generation (**Node.js only**)
|
|
11
|
+
- ๐งพ Self-signed X.509 certificate creation
|
|
12
|
+
- ๐งฌ Support for PEM-based ๐ public/private keys and certificates
|
|
13
|
+
- ๐ง JSON encryption & decryption using Base64 encoding
|
|
14
|
+
- ๐ต๏ธ Metadata extraction from certificates (issuer, subject, validity, etc.)
|
|
15
|
+
- ๐ Flexible key loading: from memory, local files (Node.js), or URLs (browser)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## ๐ Getting Started
|
|
20
|
+
|
|
21
|
+
### ๐ Constructor
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
const instance = new TinyCertCrypto({
|
|
25
|
+
publicCertPath: 'cert.pem', // Path to public cert (Node.js)
|
|
26
|
+
privateKeyPath: 'key.pem', // Path to private key (Node.js)
|
|
27
|
+
publicCertBuffer: null, // String or Buffer in memory (Node.js/browser)
|
|
28
|
+
privateKeyBuffer: null, // String or Buffer in memory (Node.js/browser)
|
|
29
|
+
cryptoType: 'RSA-OAEP', // Encryption algorithm (default: 'RSA-OAEP')
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> ๐ In **browser environments**, at least `publicCertPath` or `publicCertBuffer` must be provided.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## ๐งช Core Methods
|
|
38
|
+
|
|
39
|
+
### ๐ง `async init()`
|
|
40
|
+
Initializes the certificate and key system from files, memory buffers, or URLs.
|
|
41
|
+
|
|
42
|
+
- Loads the public certificate/key.
|
|
43
|
+
- Optionally loads the private key.
|
|
44
|
+
- Detects whether youโre running in Node.js or the browser and adjusts behavior accordingly.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### ๐ `extractCertMetadata()`
|
|
49
|
+
Returns parsed metadata from the loaded certificate.
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
{
|
|
53
|
+
subject: { names: {}, shortNames: {}, raw: "CN=example.com,O=MyOrg" },
|
|
54
|
+
issuer: { names: {}, shortNames: {}, raw: "CN=example.com,O=MyOrg" },
|
|
55
|
+
serialNumber: '...',
|
|
56
|
+
validFrom: Date,
|
|
57
|
+
validTo: Date
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### ๐ก๏ธ `encryptJson(jsonObject)`
|
|
64
|
+
Encrypts a JavaScript object using the loaded **public key**, returning a **Base64-encoded string**.
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const encrypted = instance.encryptJson({ hello: "world" });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### ๐ `decryptToJson(base64String)`
|
|
73
|
+
Decrypts a Base64 string using the **private key**, returning the original JSON object.
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
const json = instance.decryptToJson(encrypted);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
### ๐ `hasKeys()`
|
|
82
|
+
Returns `true` if both `publicKey` and `privateKey` are loaded.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### ๐ `hasCert()`
|
|
87
|
+
Returns `true` if a certificate (`publicCert`) is loaded.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### โป๏ธ `reset()`
|
|
92
|
+
Resets the internal state, clearing:
|
|
93
|
+
- `publicKey`
|
|
94
|
+
- `privateKey`
|
|
95
|
+
- `publicCert`
|
|
96
|
+
- `metadata`
|
|
97
|
+
- `source`
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### ๐ฆ `fetchNodeForge()` & `getNodeForge()`
|
|
102
|
+
Handles lazy-loading and reuse of the `node-forge` module.
|
|
103
|
+
|
|
104
|
+
Use if you want to access Forge directly without importing it yourself:
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
const forge = await instance.fetchNodeForge();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## ๐ง Internals & Design
|
|
113
|
+
|
|
114
|
+
- ๐ Uses regular expressions to detect PEM types (`CERTIFICATE`, `PUBLIC KEY`, `PRIVATE KEY`)
|
|
115
|
+
- ๐งช Automatically parses PEM buffers and files depending on the runtime
|
|
116
|
+
- ๐ Encrypts data with the selected algorithm (`RSA-OAEP`, etc.)
|
|
117
|
+
- ๐งฌ X.509 certificate metadata extraction is done via `node-forge`
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## ๐งฐ Requirements
|
|
122
|
+
|
|
123
|
+
| Environment | Requirement |
|
|
124
|
+
|-------------|--------------------|
|
|
125
|
+
| Node.js | `node-forge` |
|
|
126
|
+
| Browser | Works with native `fetch()` and `TextDecoder` |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## ๐บ Example Use Case
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
const crypto = new TinyCertCrypto({ publicCertPath: 'cert.pem', privateKeyPath: 'key.pem' });
|
|
134
|
+
await crypto.init();
|
|
135
|
+
|
|
136
|
+
const data = { secret: 'I love ponies' };
|
|
137
|
+
const encrypted = crypto.encryptJson(data);
|
|
138
|
+
const decrypted = crypto.decryptToJson(encrypted);
|
|
139
|
+
|
|
140
|
+
console.log(decrypted); // { secret: 'I love ponies' }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### ๐งพ `async generateX509Cert(subjectFields, options = {})`
|
|
146
|
+
Generates a new **RSA key pair** and a **self-signed X.509 certificate** using the provided subject information.
|
|
147
|
+
|
|
148
|
+
๐ This is ideal for internal services, development environments, or cryptographic testing tools where a trusted CA is not required.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
**๐งฌ Parameters:**
|
|
153
|
+
|
|
154
|
+
- `subjectFields` (`Object`) โ Describes the identity fields that will be embedded into the certificate's subject and issuer:
|
|
155
|
+
- Common fields include:
|
|
156
|
+
- `CN`: Common Name (e.g. domain or hostname)
|
|
157
|
+
- `O`: Organization Name
|
|
158
|
+
- `OU`: Organizational Unit
|
|
159
|
+
- `L`: Locality (City)
|
|
160
|
+
- `ST`: State or Province
|
|
161
|
+
- `C`: Country (2-letter code)
|
|
162
|
+
- `emailAddress`: Optional email field
|
|
163
|
+
|
|
164
|
+
- `options` (`Object`) โ Optional configuration:
|
|
165
|
+
- `keySize` (`number`) โ RSA key size in bits (default: `2048`)
|
|
166
|
+
- `validityInYears` (`number`) โ Certificate validity period (default: `1`)
|
|
167
|
+
- `randomBytesLength` (`number`) โ Length of the serial number (default: `16`)
|
|
168
|
+
- `digestAlgorithm` (`string`) โ Digest algorithm used to sign the certificate (default: `'sha256'`)
|
|
169
|
+
- `forgeInstance` (`object`) โ Optionally inject a specific instance of `node-forge`
|
|
170
|
+
- `cryptoType` (`string`) โ Encryption scheme used for later operations (e.g., `'RSA-OAEP'`, `'RSAES-PKCS1-V1_5'`)
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
**โ
Returns:**
|
|
175
|
+
|
|
176
|
+
An object containing all the generated artifacts:
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
{
|
|
180
|
+
publicKey: '-----BEGIN PUBLIC KEY-----...',
|
|
181
|
+
privateKey: '-----BEGIN PRIVATE KEY-----...',
|
|
182
|
+
cert: '-----BEGIN CERTIFICATE-----...'
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
- `publicKey`: The newly generated **PEM-encoded RSA public key**
|
|
187
|
+
- `privateKey`: The corresponding **PEM-encoded RSA private key**
|
|
188
|
+
- `cert`: A **PEM-encoded X.509 certificate** that is **self-signed** with the private key and matches the provided subject
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
**๐ Notes:**
|
|
193
|
+
|
|
194
|
+
- ๐ The `subject` and `issuer` of the certificate are the same (self-signed).
|
|
195
|
+
- โณ The certificate `validFrom` is set to the current date, and `validTo` is based on the `validityInYears` option.
|
|
196
|
+
- ๐ข A secure random `serialNumber` is generated using `crypto.randomBytes`.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
**โ ๏ธ Availability:**
|
|
201
|
+
|
|
202
|
+
> This method is only available in **Node.js environments** due to its dependency on the native `crypto` module and synchronous file access via `fs`.
|
package/docs/libs/TinyCrypto.md
CHANGED
|
@@ -79,7 +79,7 @@ const result = crypto.encrypt('Hello!');
|
|
|
79
79
|
Decrypts a previously encrypted value and returns the original data. You can optionally pass an `expectedType` to validate it.
|
|
80
80
|
|
|
81
81
|
```js
|
|
82
|
-
const plain = crypto.decrypt(result, '
|
|
82
|
+
const plain = crypto.decrypt(result, 'string');
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
---
|
|
@@ -136,7 +136,7 @@ Returns an object with the current settings:
|
|
|
136
136
|
"outputEncoding": "hex",
|
|
137
137
|
"inputEncoding": "utf8",
|
|
138
138
|
"authTagLength": 16,
|
|
139
|
-
"key": "..."
|
|
139
|
+
"key": "..."
|
|
140
140
|
}
|
|
141
141
|
```
|
|
142
142
|
|