@carecard/auth-util 1.0.0 → 2.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/coverage/clover.xml +179 -0
- package/coverage/coverage-final.json +8 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/cryptoUtilAuth.ts.html +418 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +206 -0
- package/coverage/lcov-report/index.ts.html +103 -0
- package/coverage/lcov-report/jwtUtilAuth.ts.html +340 -0
- package/coverage/lcov-report/keyGen.ts.html +127 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/pwdUtilAuth.ts.html +319 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/strEncryptUtil.ts.html +562 -0
- package/coverage/lcov-report/stringUtilAuth.ts.html +391 -0
- package/coverage/lcov.info +298 -0
- package/index.js +29 -0
- package/lib/cryptoUtilAuth.js +100 -0
- package/lib/jwtUtilAuth.js +81 -0
- package/lib/keyGen.js +21 -0
- package/lib/pwdUtilAuth.js +71 -0
- package/lib/strEncryptUtil.js +113 -0
- package/lib/stringUtilAuth.js +119 -0
- package/package.json +10 -42
package/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const pwdUtilAuth = require( './lib/pwdUtilAuth' );
|
|
2
|
+
const jwtUtilAuth = require( './lib/jwtUtilAuth' );
|
|
3
|
+
const strEncryptUtil = require( './lib/strEncryptUtil' );
|
|
4
|
+
const keyGen = require( './lib/keyGen' );
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
jwtUtilAuth: {
|
|
8
|
+
createSignedJwtFromObject: jwtUtilAuth.createSignedJwtFromObject,
|
|
9
|
+
verifyJwtSignature: jwtUtilAuth.verifyJwtSignature,
|
|
10
|
+
getHeaderPayloadFromJwt: jwtUtilAuth.getHeaderPayloadFromJwt
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
pwdUtilAuth: {
|
|
14
|
+
createPasswordHashWithRandomSalt: pwdUtilAuth.createPasswordHashWithRandomSalt,
|
|
15
|
+
createPasswordHashBasedOnSavedAlgorithmSalt: pwdUtilAuth.createPasswordHashBasedOnSavedAlgorithmSalt
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
strEncryptUtil: {
|
|
19
|
+
encryptByPrivateKey: strEncryptUtil.encryptByPrivateKey,
|
|
20
|
+
decryptByPublicKey: strEncryptUtil.decryptByPublicKey,
|
|
21
|
+
encryptByKey: strEncryptUtil.encryptByKey,
|
|
22
|
+
decryptByKey: strEncryptUtil.decryptByKey
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
createRsaKeys: keyGen.generateKeyPair,
|
|
26
|
+
|
|
27
|
+
stringUtilAuth: require( './lib/stringUtilAuth' ),
|
|
28
|
+
};
|
|
29
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const crypto = require( "crypto" );
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signs a token returns signature string
|
|
6
|
+
* @param token
|
|
7
|
+
* @param privateKey
|
|
8
|
+
* @param signingAlgorithm
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
const createBase64SignatureOfToken = function ( token = '', privateKey, signingAlgorithm ) {
|
|
12
|
+
|
|
13
|
+
const sign = crypto.createSign( signingAlgorithm );
|
|
14
|
+
sign.write( token );
|
|
15
|
+
sign.end();
|
|
16
|
+
return sign.sign( privateKey, 'base64' );
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Verifies the signature returns true or false
|
|
21
|
+
* @param token
|
|
22
|
+
* @param signature
|
|
23
|
+
* @param publicKey
|
|
24
|
+
* @param signingAlgorithm
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
*/
|
|
27
|
+
const verifyBase64SignatureOfToken = function ( token = '', signature, publicKey, signingAlgorithm ) {
|
|
28
|
+
const verify = crypto.createVerify( signingAlgorithm );
|
|
29
|
+
verify.update( token );
|
|
30
|
+
verify.end();
|
|
31
|
+
return verify.verify( publicKey, signature, 'base64' );
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates the hash of given string
|
|
36
|
+
* @param string
|
|
37
|
+
* @param secret
|
|
38
|
+
* @param algorithm
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
const createHmacBase64 = function ( string = '', secret, algorithm ) {
|
|
42
|
+
const hmac = crypto.createHmac( algorithm, secret );
|
|
43
|
+
hmac.update( string );
|
|
44
|
+
return hmac.digest( 'base64' );
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create random salt
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
51
|
+
const createSaltBase64 = () => {
|
|
52
|
+
const date = new Date().valueOf();
|
|
53
|
+
const hmac = crypto.createHmac( 'SHA256', date.toString() );
|
|
54
|
+
hmac.update( date.toString() );
|
|
55
|
+
return hmac.digest( 'base64' );
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Encrypt given string
|
|
60
|
+
* @param string
|
|
61
|
+
* @param salt
|
|
62
|
+
* @param secret
|
|
63
|
+
* @param algorithm
|
|
64
|
+
* @returns {string}
|
|
65
|
+
*/
|
|
66
|
+
const encryptStringAsciiToBase64 = ( string, salt, secret, algorithm ) => {
|
|
67
|
+
|
|
68
|
+
const key = crypto.scryptSync( secret, salt, 24 );
|
|
69
|
+
const iv = Buffer.alloc( 16, 0 );
|
|
70
|
+
const cipher = crypto.createCipheriv( algorithm, key, iv );
|
|
71
|
+
let encrypted = cipher.update( string, 'ascii', 'base64' );
|
|
72
|
+
encrypted += cipher.final( 'base64' );
|
|
73
|
+
return encrypted;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Decrypts given string
|
|
78
|
+
* @param encryptedString
|
|
79
|
+
* @param salt
|
|
80
|
+
* @param secret
|
|
81
|
+
* @param algorithm
|
|
82
|
+
* @returns {string}
|
|
83
|
+
*/
|
|
84
|
+
const decryptStringBase64ToAscii = ( encryptedString, salt, secret, algorithm ) => {
|
|
85
|
+
const key = crypto.scryptSync( secret, salt, 24 );
|
|
86
|
+
const iv = Buffer.alloc( 16, 0 );
|
|
87
|
+
const decipher = crypto.createDecipheriv( algorithm, key, iv );
|
|
88
|
+
let decrypted = decipher.update( encryptedString, 'base64', 'ascii' );
|
|
89
|
+
decrypted += decipher.final( 'ascii' );
|
|
90
|
+
return decrypted;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
module.exports = {
|
|
94
|
+
createBase64SignatureOfToken,
|
|
95
|
+
verifyBase64SignatureOfToken,
|
|
96
|
+
createHmacBase64,
|
|
97
|
+
createSaltBase64,
|
|
98
|
+
encryptStringAsciiToBase64,
|
|
99
|
+
decryptStringBase64ToAscii
|
|
100
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const stringUtilAuth = require( './stringUtilAuth' );
|
|
2
|
+
const cryptoUtilAuth = require( './cryptoUtilAuth' );
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User supplied header, payload and signature create jwt.
|
|
6
|
+
* @returns {string|null}
|
|
7
|
+
* @param headerBase64
|
|
8
|
+
* @param payloadBase64
|
|
9
|
+
* @param signatureBase64
|
|
10
|
+
*/
|
|
11
|
+
const _assembleJwt = ( headerBase64, payloadBase64, signatureBase64 ) => {
|
|
12
|
+
return headerBase64 + "." + payloadBase64 + "." + signatureBase64;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* User supplied header, payload and signature create jwt.
|
|
17
|
+
* @returns {{payload: *, signature: *, header: *}}
|
|
18
|
+
* @param jwt
|
|
19
|
+
*/
|
|
20
|
+
const _splitJwtInToHeaderPayloadSignature = ( jwt ) => {
|
|
21
|
+
return stringUtilAuth.dotConnectedStringToHeaderPayloadSignature( jwt );
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates Url safe jwt
|
|
26
|
+
* @param headerObject
|
|
27
|
+
* @param payloadObject
|
|
28
|
+
* @param privateKey
|
|
29
|
+
* @return {string|null}
|
|
30
|
+
*/
|
|
31
|
+
const createSignedJwtFromObject = ( headerObject, payloadObject, privateKey ) => {
|
|
32
|
+
try {
|
|
33
|
+
const algorithm = headerObject.alg;
|
|
34
|
+
const headerBase64UrlSafe = stringUtilAuth.objectToBase64UrlSafeString( headerObject );
|
|
35
|
+
const payloadBase64UrlSafe = stringUtilAuth.objectToBase64UrlSafeString( payloadObject );
|
|
36
|
+
const token = headerBase64UrlSafe + "." + payloadBase64UrlSafe;
|
|
37
|
+
const signature = cryptoUtilAuth.createBase64SignatureOfToken( token, privateKey, algorithm );
|
|
38
|
+
const urlSafeSignature = stringUtilAuth.makeStringUrlSafe( signature );
|
|
39
|
+
return _assembleJwt( headerBase64UrlSafe, payloadBase64UrlSafe, urlSafeSignature );
|
|
40
|
+
} catch ( error ) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Verify signature of jwt
|
|
47
|
+
* @param jwt
|
|
48
|
+
* @param publicKey
|
|
49
|
+
* @return {boolean}
|
|
50
|
+
*/
|
|
51
|
+
const verifyJwtSignature = ( jwt, publicKey ) => {
|
|
52
|
+
try {
|
|
53
|
+
const { header, payload, signature } = _splitJwtInToHeaderPayloadSignature( jwt );
|
|
54
|
+
const token = header + "." + payload;
|
|
55
|
+
const headerObject = stringUtilAuth.urlSafeBase64ToObject( header );
|
|
56
|
+
return cryptoUtilAuth.verifyBase64SignatureOfToken( token, signature, publicKey, headerObject.alg )
|
|
57
|
+
} catch ( error ) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns header and payload object for jwt.
|
|
64
|
+
* @param jwt
|
|
65
|
+
* @return {{payload: any, header: any}}
|
|
66
|
+
*/
|
|
67
|
+
const getHeaderPayloadFromJwt = jwt => {
|
|
68
|
+
const { header, payload, signature } = _splitJwtInToHeaderPayloadSignature( jwt );
|
|
69
|
+
let headerAscii = stringUtilAuth.base64ToAscii( header );
|
|
70
|
+
let payloadAscii = stringUtilAuth.base64ToAscii( payload );
|
|
71
|
+
return { header: JSON.parse( headerAscii ), payload: JSON.parse( payloadAscii ) }
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
module.exports = {
|
|
76
|
+
_assembleJwt,
|
|
77
|
+
_splitJwtInToHeaderPayloadSignature,
|
|
78
|
+
createSignedJwtFromObject,
|
|
79
|
+
verifyJwtSignature,
|
|
80
|
+
getHeaderPayloadFromJwt
|
|
81
|
+
};
|
package/lib/keyGen.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const {
|
|
2
|
+
generateKeyPairSync,
|
|
3
|
+
} = require( 'node:crypto' );
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const generateKeyPair = ( modulusLength = 4096 ) => ( generateKeyPairSync( 'rsa', {
|
|
7
|
+
modulusLength: modulusLength,
|
|
8
|
+
publicKeyEncoding: {
|
|
9
|
+
type: 'spki',
|
|
10
|
+
format: 'pem',
|
|
11
|
+
},
|
|
12
|
+
privateKeyEncoding: {
|
|
13
|
+
type: 'pkcs8',
|
|
14
|
+
format: 'pem',
|
|
15
|
+
},
|
|
16
|
+
} ) );
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
generateKeyPair
|
|
21
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const cryptoUtilAuth = require( './cryptoUtilAuth' );
|
|
2
|
+
const stringUtilAuth = require( './stringUtilAuth' );
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Just assemble password together
|
|
6
|
+
* @param algorithmBase64
|
|
7
|
+
* @param hashBase64
|
|
8
|
+
* @param saltBase64
|
|
9
|
+
* @return {string}
|
|
10
|
+
*/
|
|
11
|
+
const _assemblePasswordHash = ( algorithmBase64, hashBase64, saltBase64 ) => {
|
|
12
|
+
return "$1$" + algorithmBase64 + "$" + hashBase64 + "$" + saltBase64 + "$";
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Break password into its parts does not reverse base64 encoding.
|
|
17
|
+
* @param passwordHashStored
|
|
18
|
+
* @return {{salt: *, version: *, alg: *, hash: *}}
|
|
19
|
+
*/
|
|
20
|
+
const _disassemblePasswordHash = passwordHashStored => {
|
|
21
|
+
return stringUtilAuth.dollarSignConnectedStringToAlgorithmHashSalt( passwordHashStored );
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates password hash ready to be saved in database.
|
|
27
|
+
* @param password
|
|
28
|
+
* @param secret
|
|
29
|
+
* @param salt
|
|
30
|
+
* @param algorithm
|
|
31
|
+
* @return {string}
|
|
32
|
+
*/
|
|
33
|
+
const _createPasswordHash = ( password, secret, salt, algorithm ) => {
|
|
34
|
+
const algorithmBase64 = stringUtilAuth.asciiToBase64( algorithm );
|
|
35
|
+
const hashBase64 = cryptoUtilAuth.createHmacBase64( password, secret, algorithm );
|
|
36
|
+
return _assemblePasswordHash( algorithmBase64, hashBase64, salt );
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Automatically adds random salt.
|
|
41
|
+
* @param password
|
|
42
|
+
* @param secret
|
|
43
|
+
* @param algorithm
|
|
44
|
+
* @return {string}
|
|
45
|
+
*/
|
|
46
|
+
const createPasswordHashWithRandomSalt = ( password, secret, algorithm ) => {
|
|
47
|
+
const salt = cryptoUtilAuth.createSaltBase64();
|
|
48
|
+
return _createPasswordHash( password, secret, salt, algorithm );
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Creates hash based on saved hash in database.
|
|
53
|
+
* @param password
|
|
54
|
+
* @param savedPasswordHash
|
|
55
|
+
* @param secret
|
|
56
|
+
* @return {string}
|
|
57
|
+
*/
|
|
58
|
+
const createPasswordHashBasedOnSavedAlgorithmSalt = ( password, savedPasswordHash, secret ) => {
|
|
59
|
+
const { version, alg, hash, salt } = _disassemblePasswordHash( savedPasswordHash );
|
|
60
|
+
const algorithm = stringUtilAuth.base64ToAscii( alg );
|
|
61
|
+
return _createPasswordHash( password, secret, salt, algorithm );
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
_assemblePasswordHash,
|
|
67
|
+
_disassemblePasswordHash,
|
|
68
|
+
_createPasswordHash,
|
|
69
|
+
createPasswordHashWithRandomSalt,
|
|
70
|
+
createPasswordHashBasedOnSavedAlgorithmSalt
|
|
71
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const crypto = require( "crypto" );
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function createKey( key, keyLength = 32 ) {
|
|
5
|
+
return crypto.scryptSync( key, key, keyLength );
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const encryptByPrivateKey = ( encryptionConfigObj, textToEncrypt ) => {
|
|
9
|
+
try {
|
|
10
|
+
|
|
11
|
+
const encrypted = crypto.privateEncrypt(
|
|
12
|
+
encryptionConfigObj.privateKey,
|
|
13
|
+
Buffer.from( textToEncrypt )
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return encrypted.toString( encryptionConfigObj.encryptedTextEncoding );
|
|
17
|
+
|
|
18
|
+
} catch ( error ) {
|
|
19
|
+
|
|
20
|
+
return error.code;
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const decryptByPublicKey = ( decryptionConfigObj, textToDecrypt ) => {
|
|
26
|
+
try {
|
|
27
|
+
|
|
28
|
+
const decrypted = crypto.publicDecrypt(
|
|
29
|
+
decryptionConfigObj.publicKey,
|
|
30
|
+
Buffer.from(
|
|
31
|
+
textToDecrypt,
|
|
32
|
+
decryptionConfigObj.encryptedTextEncoding
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return decrypted.toString( decryptionConfigObj.plainTextEncoding );
|
|
37
|
+
|
|
38
|
+
} catch ( error ) {
|
|
39
|
+
|
|
40
|
+
return error.code;
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const encryptByKey = ( encryptConfigObj = {}, textToEncrypt ) => {
|
|
46
|
+
try {
|
|
47
|
+
|
|
48
|
+
const iv = Buffer.alloc( 16, 0 );
|
|
49
|
+
|
|
50
|
+
const cipher = crypto.createCipheriv(
|
|
51
|
+
encryptConfigObj.cipherAlgorithm,
|
|
52
|
+
createKey(
|
|
53
|
+
encryptConfigObj.encryptionKey,
|
|
54
|
+
encryptConfigObj.keyLength
|
|
55
|
+
),
|
|
56
|
+
iv
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
let encrypted = cipher.update(
|
|
60
|
+
textToEncrypt,
|
|
61
|
+
encryptConfigObj.plainTextEncoding,
|
|
62
|
+
encryptConfigObj.encryptedTextEncoding
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
encrypted += cipher.final( encryptConfigObj.encryptedTextEncoding );
|
|
66
|
+
|
|
67
|
+
return encrypted;
|
|
68
|
+
|
|
69
|
+
} catch ( error ) {
|
|
70
|
+
|
|
71
|
+
return error.code;
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const decryptByKey = ( encryptConfigObj, textToDecrypt ) => {
|
|
77
|
+
try {
|
|
78
|
+
|
|
79
|
+
const iv = Buffer.alloc( 16, 0 );
|
|
80
|
+
|
|
81
|
+
const decipher = crypto.createDecipheriv(
|
|
82
|
+
encryptConfigObj.cipherAlgorithm,
|
|
83
|
+
createKey(
|
|
84
|
+
encryptConfigObj.encryptionKey,
|
|
85
|
+
encryptConfigObj.keyLength
|
|
86
|
+
),
|
|
87
|
+
iv
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
let decrypted = decipher.update(
|
|
91
|
+
textToDecrypt,
|
|
92
|
+
encryptConfigObj.encryptedTextEncoding,
|
|
93
|
+
encryptConfigObj.plainTextEncoding
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
decrypted += decipher.final( encryptConfigObj.plainTextEncoding );
|
|
97
|
+
|
|
98
|
+
return decrypted;
|
|
99
|
+
|
|
100
|
+
} catch ( error ) {
|
|
101
|
+
|
|
102
|
+
return error.code;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
encryptByPrivateKey,
|
|
110
|
+
decryptByPublicKey,
|
|
111
|
+
encryptByKey,
|
|
112
|
+
decryptByKey
|
|
113
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* For incoming jwt token validation, splitting and parsing.
|
|
4
|
+
* For outgoing jwt token assembling to jwt, make it url safe.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Adjusts padding of base64String
|
|
9
|
+
* @param base64String
|
|
10
|
+
* @return {*}
|
|
11
|
+
*/
|
|
12
|
+
const adjustBase64Padding = base64String => {
|
|
13
|
+
while ( base64String.length % 4 ) base64String += '=';
|
|
14
|
+
return base64String;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Removes /, + and = from the string
|
|
19
|
+
* @returns {string}
|
|
20
|
+
*/
|
|
21
|
+
const makeStringUrlSafe = ( urlUnsafeString = '' ) => {
|
|
22
|
+
return urlUnsafeString
|
|
23
|
+
.replaceAll( '+', '-' )
|
|
24
|
+
.replaceAll( '/', '_' )
|
|
25
|
+
.replaceAll( '=', '' );
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Put back /, + and = into the string
|
|
30
|
+
* @returns {string}
|
|
31
|
+
*/
|
|
32
|
+
const reverseStringUrlSafe = ( urlSafeString = '' ) => {
|
|
33
|
+
let myString = urlSafeString
|
|
34
|
+
.replaceAll( '-', '+' )
|
|
35
|
+
.replaceAll( '_', '/' );
|
|
36
|
+
return adjustBase64Padding( myString );
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Encode string to base64 string
|
|
41
|
+
* @param unCodedString
|
|
42
|
+
* @returns {string}
|
|
43
|
+
*/
|
|
44
|
+
const asciiToBase64 = ( unCodedString ) => {
|
|
45
|
+
return Buffer.from( unCodedString ).toString( 'base64' );
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Decode string from base64
|
|
49
|
+
* @param codedString
|
|
50
|
+
* @returns {string}
|
|
51
|
+
*/
|
|
52
|
+
const base64ToAscii = ( codedString ) => {
|
|
53
|
+
return Buffer.from( codedString, 'base64' ).toString( 'ascii' );
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Decompose $ connected string and return an object
|
|
58
|
+
* return null if error
|
|
59
|
+
* @param passwordHash
|
|
60
|
+
*/
|
|
61
|
+
const dollarSignConnectedStringToAlgorithmHashSalt = ( passwordHash ) => {
|
|
62
|
+
const splitStringArray = passwordHash.split( '$' );
|
|
63
|
+
if ( splitStringArray.length !== 6 ) return null;
|
|
64
|
+
return {
|
|
65
|
+
version: splitStringArray[ 1 ],
|
|
66
|
+
alg: splitStringArray[ 2 ],
|
|
67
|
+
hash: splitStringArray[ 3 ],
|
|
68
|
+
salt: splitStringArray[ 4 ]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Decompose . connected string and return an object with
|
|
74
|
+
* {header: 'string', payload: 'string', signature: 'string'}
|
|
75
|
+
* return null if error
|
|
76
|
+
*/
|
|
77
|
+
const dotConnectedStringToHeaderPayloadSignature = ( jwt ) => {
|
|
78
|
+
const splitJWT = jwt.split( '.' );
|
|
79
|
+
if ( splitJWT.length !== 3 ) return null;
|
|
80
|
+
return {
|
|
81
|
+
header: splitJWT[ 0 ],
|
|
82
|
+
payload: splitJWT[ 1 ],
|
|
83
|
+
signature: splitJWT[ 2 ]
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Turns object into url safe string
|
|
90
|
+
* @param object
|
|
91
|
+
* @return {string}
|
|
92
|
+
*/
|
|
93
|
+
const objectToBase64UrlSafeString = object => {
|
|
94
|
+
let stringAscii = JSON.stringify( object );
|
|
95
|
+
let base64String = asciiToBase64( stringAscii );
|
|
96
|
+
return makeStringUrlSafe( base64String );
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Turns base64 into object
|
|
101
|
+
* @param urlSafeBase64String
|
|
102
|
+
* @return {any}
|
|
103
|
+
*/
|
|
104
|
+
const urlSafeBase64ToObject = urlSafeBase64String => {
|
|
105
|
+
let base64String = reverseStringUrlSafe( urlSafeBase64String );
|
|
106
|
+
let stringAscii = base64ToAscii( base64String );
|
|
107
|
+
return JSON.parse( stringAscii );
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
module.exports = {
|
|
111
|
+
makeStringUrlSafe,
|
|
112
|
+
reverseStringUrlSafe,
|
|
113
|
+
asciiToBase64,
|
|
114
|
+
base64ToAscii,
|
|
115
|
+
dollarSignConnectedStringToAlgorithmHashSalt,
|
|
116
|
+
dotConnectedStringToHeaderPayloadSignature,
|
|
117
|
+
objectToBase64UrlSafeString,
|
|
118
|
+
urlSafeBase64ToObject
|
|
119
|
+
};
|
package/package.json
CHANGED
|
@@ -1,54 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carecard/auth-util",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"repository": "https://github.com/CareCard-ca/pkg-auth-util.git",
|
|
5
5
|
"description": "Auth utility functions",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https:github.com/CareCard-ca/pkg-auth-util.git"
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "export NODE_ENV=test && mocha --watch --recursive"
|
|
11
9
|
},
|
|
12
10
|
"keywords": [
|
|
13
11
|
"auth",
|
|
14
12
|
"utility",
|
|
15
13
|
"cryptology"
|
|
16
14
|
],
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"access": "public"
|
|
20
|
-
},
|
|
21
|
-
"main": "./dist/cjs/index.cjs",
|
|
22
|
-
"module": "./dist/esm/index.js",
|
|
23
|
-
"types": "./dist/esm/index.d.ts",
|
|
24
|
-
"exports": {
|
|
25
|
-
".": {
|
|
26
|
-
"import": "./dist/esm/index.js",
|
|
27
|
-
"require": "./dist/cjs/index.cjs",
|
|
28
|
-
"types": "./dist/esm/index.d.ts"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"files": [
|
|
32
|
-
"dist"
|
|
33
|
-
],
|
|
34
|
-
"scripts": {
|
|
35
|
-
"build": "npm run build:esm && npm run build:cjs",
|
|
36
|
-
"build:esm": "tsc -p tsconfig.esm.json",
|
|
37
|
-
"build:cjs": "tsc -p tsconfig.cjs.json && node ./scripts/rename-cjs.js",
|
|
38
|
-
"test": "NODE_NO_WARNINGS=1 jest --coverage",
|
|
39
|
-
"format": "prettier --write .",
|
|
40
|
-
"format:check": "prettier --check .",
|
|
41
|
-
"lint": "eslint",
|
|
42
|
-
"prepare": "husky"
|
|
43
|
-
},
|
|
15
|
+
"author": "CareCard team",
|
|
16
|
+
"license": "ISC",
|
|
44
17
|
"devDependencies": {
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"jest": "30.2.0",
|
|
49
|
-
"prettier": "3.7.4",
|
|
50
|
-
"ts-jest": "29.4.6",
|
|
51
|
-
"typescript": "5.9.3",
|
|
52
|
-
"typescript-eslint": "8.50.1"
|
|
18
|
+
"mocha": "10.2.0"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
53
21
|
}
|
|
54
22
|
}
|