@excofy/utils 1.0.15 → 2.1.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/.github/workflows/publish.yml +0 -3
- package/dist/index.cjs +28 -2
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +28 -2
- package/package.json +1 -1
- package/src/helpers/crypto.ts +54 -1
- package/src/helpers/validator.ts +15 -0
package/dist/index.cjs
CHANGED
|
@@ -446,6 +446,15 @@ function createValidator() {
|
|
|
446
446
|
}
|
|
447
447
|
return validator;
|
|
448
448
|
},
|
|
449
|
+
sanitizeAlphanumeric() {
|
|
450
|
+
if (shouldSkipValidation()) return validator;
|
|
451
|
+
if (typeof current.value === "string") {
|
|
452
|
+
const cleaned = current.value.replace(/[^A-Za-z0-9]/g, "").trim();
|
|
453
|
+
current.value = cleaned;
|
|
454
|
+
current.inputs[current.field] = cleaned;
|
|
455
|
+
}
|
|
456
|
+
return validator;
|
|
457
|
+
},
|
|
449
458
|
sanitizeDigits() {
|
|
450
459
|
if (shouldSkipValidation()) return validator;
|
|
451
460
|
if (typeof current.value === "string") {
|
|
@@ -720,9 +729,24 @@ var decryptPayload = async ({
|
|
|
720
729
|
);
|
|
721
730
|
return decoder.decode(buffer);
|
|
722
731
|
};
|
|
732
|
+
async function generateDeterministicHash(code, secret) {
|
|
733
|
+
const key = await crypto.subtle.importKey(
|
|
734
|
+
"raw",
|
|
735
|
+
encoder.encode(secret),
|
|
736
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
737
|
+
false,
|
|
738
|
+
["sign"]
|
|
739
|
+
);
|
|
740
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(code));
|
|
741
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
742
|
+
}
|
|
743
|
+
async function verifyDeterministicHash(inputCode, storedHash, secret) {
|
|
744
|
+
const hash = await generateDeterministicHash(inputCode, secret);
|
|
745
|
+
return hash === storedHash;
|
|
746
|
+
}
|
|
723
747
|
var cryptoUtils = {
|
|
724
748
|
uuidV4: () => crypto.randomUUID(),
|
|
725
|
-
hash: async (password, salt) => {
|
|
749
|
+
hash: async (password, salt = 10) => {
|
|
726
750
|
const importedKey = await crypto.subtle.importKey(
|
|
727
751
|
"raw",
|
|
728
752
|
encoder.encode(password),
|
|
@@ -798,7 +822,9 @@ var cryptoUtils = {
|
|
|
798
822
|
return Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
799
823
|
},
|
|
800
824
|
encryptPayload,
|
|
801
|
-
decryptPayload
|
|
825
|
+
decryptPayload,
|
|
826
|
+
generateDeterministicHash,
|
|
827
|
+
verifyDeterministicHash
|
|
802
828
|
};
|
|
803
829
|
|
|
804
830
|
// src/helpers/slug.ts
|
package/dist/index.d.cts
CHANGED
|
@@ -32,6 +32,7 @@ interface ValidatorField {
|
|
|
32
32
|
slug(message: string): ValidatorField;
|
|
33
33
|
sanitize(): ValidatorField;
|
|
34
34
|
sanitizeAlphaSpaces(): ValidatorField;
|
|
35
|
+
sanitizeAlphanumeric(): ValidatorField;
|
|
35
36
|
sanitizeDigits(): ValidatorField;
|
|
36
37
|
sanitizePreservingNewlines(): ValidatorField;
|
|
37
38
|
sanitizeHTML(tags?: AllowedTag[]): ValidatorField;
|
|
@@ -132,6 +133,8 @@ interface ICrypto {
|
|
|
132
133
|
AUTH_PAYLOAD_SECRET: string;
|
|
133
134
|
token: string;
|
|
134
135
|
}) => Promise<string>;
|
|
136
|
+
generateDeterministicHash: (code: string, secret: string) => Promise<string>;
|
|
137
|
+
verifyDeterministicHash: (inputCode: string, storedHash: string, secret: string) => Promise<boolean>;
|
|
135
138
|
}
|
|
136
139
|
declare const cryptoUtils: ICrypto;
|
|
137
140
|
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ interface ValidatorField {
|
|
|
32
32
|
slug(message: string): ValidatorField;
|
|
33
33
|
sanitize(): ValidatorField;
|
|
34
34
|
sanitizeAlphaSpaces(): ValidatorField;
|
|
35
|
+
sanitizeAlphanumeric(): ValidatorField;
|
|
35
36
|
sanitizeDigits(): ValidatorField;
|
|
36
37
|
sanitizePreservingNewlines(): ValidatorField;
|
|
37
38
|
sanitizeHTML(tags?: AllowedTag[]): ValidatorField;
|
|
@@ -132,6 +133,8 @@ interface ICrypto {
|
|
|
132
133
|
AUTH_PAYLOAD_SECRET: string;
|
|
133
134
|
token: string;
|
|
134
135
|
}) => Promise<string>;
|
|
136
|
+
generateDeterministicHash: (code: string, secret: string) => Promise<string>;
|
|
137
|
+
verifyDeterministicHash: (inputCode: string, storedHash: string, secret: string) => Promise<boolean>;
|
|
135
138
|
}
|
|
136
139
|
declare const cryptoUtils: ICrypto;
|
|
137
140
|
|
package/dist/index.js
CHANGED
|
@@ -410,6 +410,15 @@ function createValidator() {
|
|
|
410
410
|
}
|
|
411
411
|
return validator;
|
|
412
412
|
},
|
|
413
|
+
sanitizeAlphanumeric() {
|
|
414
|
+
if (shouldSkipValidation()) return validator;
|
|
415
|
+
if (typeof current.value === "string") {
|
|
416
|
+
const cleaned = current.value.replace(/[^A-Za-z0-9]/g, "").trim();
|
|
417
|
+
current.value = cleaned;
|
|
418
|
+
current.inputs[current.field] = cleaned;
|
|
419
|
+
}
|
|
420
|
+
return validator;
|
|
421
|
+
},
|
|
413
422
|
sanitizeDigits() {
|
|
414
423
|
if (shouldSkipValidation()) return validator;
|
|
415
424
|
if (typeof current.value === "string") {
|
|
@@ -684,9 +693,24 @@ var decryptPayload = async ({
|
|
|
684
693
|
);
|
|
685
694
|
return decoder.decode(buffer);
|
|
686
695
|
};
|
|
696
|
+
async function generateDeterministicHash(code, secret) {
|
|
697
|
+
const key = await crypto.subtle.importKey(
|
|
698
|
+
"raw",
|
|
699
|
+
encoder.encode(secret),
|
|
700
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
701
|
+
false,
|
|
702
|
+
["sign"]
|
|
703
|
+
);
|
|
704
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(code));
|
|
705
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
706
|
+
}
|
|
707
|
+
async function verifyDeterministicHash(inputCode, storedHash, secret) {
|
|
708
|
+
const hash = await generateDeterministicHash(inputCode, secret);
|
|
709
|
+
return hash === storedHash;
|
|
710
|
+
}
|
|
687
711
|
var cryptoUtils = {
|
|
688
712
|
uuidV4: () => crypto.randomUUID(),
|
|
689
|
-
hash: async (password, salt) => {
|
|
713
|
+
hash: async (password, salt = 10) => {
|
|
690
714
|
const importedKey = await crypto.subtle.importKey(
|
|
691
715
|
"raw",
|
|
692
716
|
encoder.encode(password),
|
|
@@ -762,7 +786,9 @@ var cryptoUtils = {
|
|
|
762
786
|
return Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
763
787
|
},
|
|
764
788
|
encryptPayload,
|
|
765
|
-
decryptPayload
|
|
789
|
+
decryptPayload,
|
|
790
|
+
generateDeterministicHash,
|
|
791
|
+
verifyDeterministicHash
|
|
766
792
|
};
|
|
767
793
|
|
|
768
794
|
// src/helpers/slug.ts
|
package/package.json
CHANGED
package/src/helpers/crypto.ts
CHANGED
|
@@ -25,6 +25,12 @@ interface ICrypto {
|
|
|
25
25
|
AUTH_PAYLOAD_SECRET: string;
|
|
26
26
|
token: string;
|
|
27
27
|
}) => Promise<string>;
|
|
28
|
+
generateDeterministicHash: (code: string, secret: string) => Promise<string>;
|
|
29
|
+
verifyDeterministicHash: (
|
|
30
|
+
inputCode: string,
|
|
31
|
+
storedHash: string,
|
|
32
|
+
secret: string
|
|
33
|
+
) => Promise<boolean>;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
/* --------------------- Helpers básicos --------------------- */
|
|
@@ -94,11 +100,55 @@ const decryptPayload = async ({
|
|
|
94
100
|
return decoder.decode(buffer);
|
|
95
101
|
};
|
|
96
102
|
|
|
103
|
+
/* --------------------- Hash (generate/verify) --------------------- */
|
|
104
|
+
/**
|
|
105
|
+
* Gera um hash determinístico (HMAC) a partir de um código e um segredo.
|
|
106
|
+
*
|
|
107
|
+
* @param code
|
|
108
|
+
* @param secret
|
|
109
|
+
* @returns
|
|
110
|
+
*/
|
|
111
|
+
export async function generateDeterministicHash(
|
|
112
|
+
code: string,
|
|
113
|
+
secret: string
|
|
114
|
+
): Promise<string> {
|
|
115
|
+
const key = await crypto.subtle.importKey(
|
|
116
|
+
'raw',
|
|
117
|
+
encoder.encode(secret),
|
|
118
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
119
|
+
false,
|
|
120
|
+
['sign']
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(code));
|
|
124
|
+
|
|
125
|
+
return Array.from(new Uint8Array(signature))
|
|
126
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
127
|
+
.join('');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Verifica se o hash gerado a partir do código e segredo bate com o hash armazenado.
|
|
132
|
+
*
|
|
133
|
+
* @param inputCode
|
|
134
|
+
* @param storedHash
|
|
135
|
+
* @param secret
|
|
136
|
+
* @returns
|
|
137
|
+
*/
|
|
138
|
+
export async function verifyDeterministicHash(
|
|
139
|
+
inputCode: string,
|
|
140
|
+
storedHash: string,
|
|
141
|
+
secret: string
|
|
142
|
+
): Promise<boolean> {
|
|
143
|
+
const hash = await generateDeterministicHash(inputCode, secret);
|
|
144
|
+
return hash === storedHash;
|
|
145
|
+
}
|
|
146
|
+
|
|
97
147
|
/* --------------------- Main API --------------------- */
|
|
98
148
|
export const cryptoUtils: ICrypto = {
|
|
99
149
|
uuidV4: (): string => crypto.randomUUID(),
|
|
100
150
|
|
|
101
|
-
hash: async (password: string, salt: number): Promise<string> => {
|
|
151
|
+
hash: async (password: string, salt: number = 10): Promise<string> => {
|
|
102
152
|
const importedKey = await crypto.subtle.importKey(
|
|
103
153
|
'raw',
|
|
104
154
|
encoder.encode(password),
|
|
@@ -199,4 +249,7 @@ export const cryptoUtils: ICrypto = {
|
|
|
199
249
|
|
|
200
250
|
encryptPayload,
|
|
201
251
|
decryptPayload,
|
|
252
|
+
|
|
253
|
+
generateDeterministicHash,
|
|
254
|
+
verifyDeterministicHash,
|
|
202
255
|
};
|
package/src/helpers/validator.ts
CHANGED
|
@@ -39,6 +39,7 @@ interface ValidatorField {
|
|
|
39
39
|
slug(message: string): ValidatorField;
|
|
40
40
|
sanitize(): ValidatorField;
|
|
41
41
|
sanitizeAlphaSpaces(): ValidatorField;
|
|
42
|
+
sanitizeAlphanumeric(): ValidatorField;
|
|
42
43
|
sanitizeDigits(): ValidatorField;
|
|
43
44
|
sanitizePreservingNewlines(): ValidatorField;
|
|
44
45
|
sanitizeHTML(tags?: AllowedTag[]): ValidatorField;
|
|
@@ -421,6 +422,20 @@ export function createValidator<
|
|
|
421
422
|
return validator;
|
|
422
423
|
},
|
|
423
424
|
|
|
425
|
+
sanitizeAlphanumeric() {
|
|
426
|
+
if (shouldSkipValidation()) return validator;
|
|
427
|
+
|
|
428
|
+
if (typeof current.value === 'string') {
|
|
429
|
+
const cleaned = current.value
|
|
430
|
+
.replace(/[^A-Za-z0-9]/g, '') // remove tudo que não é letra ou número
|
|
431
|
+
.trim();
|
|
432
|
+
current.value = cleaned;
|
|
433
|
+
current.inputs[current.field] = cleaned as TRaw[keyof TRaw];
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return validator;
|
|
437
|
+
},
|
|
438
|
+
|
|
424
439
|
sanitizeDigits() {
|
|
425
440
|
if (shouldSkipValidation()) return validator;
|
|
426
441
|
|