ldap-sha512
Advanced tools
Comparing version 1.1.0 to 2.0.0
import { randomBytes } from 'node:crypto'; | ||
import { sha512 } from './helpers.js'; | ||
/** | ||
* Encrypt a plain text password with the Ldap sha512crypt algorithm. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string} salt - Salt used to hash the password (it can't be greater than 16 characters). | ||
* @returns {string} - Encrypted password with the Ldap sha512crypt algorithm. | ||
* | ||
* @throws {Error} If salt length is greater than 16. | ||
* | ||
* @example | ||
* const encryptedPassword = sha512Crypt('mySuperSecretPassword') | ||
* // return {CRYPT}$6$NQgPVC0up/oNVCb4$Aduz92Zfo/PFDE/XhvA3QmSqHquqdNiCdZvc9N5/UTpEUepMdd/6Mq/TeoM07wvyxHpg8ELGVzTWZt2e7Z9LY/ | ||
*/ | ||
export function sha512Crypt(textPassword, salt = '') { | ||
if (!salt) | ||
salt = randomBytes(16).toString('base64').substring(0, 16); | ||
if (salt.length > 16) | ||
throw new Error('The maximum length of salt is 16 characters'); | ||
return sha512(textPassword, salt); | ||
} | ||
/** | ||
* Verify passwords encrypted with sha512. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string | string[]} sha512Password - String or Array of strings to be compared to the plain text password. | ||
* | ||
* @example | ||
* const isValid = verifySha512('mySuperSecretPassword', arrayOfSha512Passwords) | ||
* // return true or false | ||
*/ | ||
export function verifySha512(textPassword, sha512Password) { | ||
let isValid = false; | ||
const sha512Passwords = typeof sha512Password === 'string' ? [sha512Password] : sha512Password; | ||
for (const cryptPasswd of sha512Passwords) { | ||
const hashType = cryptPasswd.match(/\{([^}]+)\}/); | ||
if (hashType && hashType[1] === 'CRYPT') { | ||
const salt = cryptPasswd.split('$')[2]; | ||
const hashedPassword = sha512Crypt(textPassword, salt); | ||
if (hashedPassword === cryptPasswd) | ||
isValid = true; | ||
} | ||
} | ||
return isValid; | ||
} | ||
/** | ||
* Encrypt a plain text password with the Ldap sha512crypt algorithm. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string} salt - Salt used to hash the password (it can't be greater than 16 characters). | ||
* @returns {string} - Encrypted password with the Ldap sha512crypt algorithm. | ||
* | ||
* @throws {Error} If salt length is greater than 16. | ||
* | ||
* @example | ||
* const encryptedPassword = await sha512CryptAsync('mySuperSecretPassword') | ||
* // return Promise that resolves to => {CRYPT}$6$NQgPVC0up/oNVCb4$Aduz92Zfo/PFDE/XhvA3QmSqHquqdNiCdZvc9N5/UTpEUepMdd/6Mq/TeoM07wvyxHpg8ELGVzTWZt2e7Z9LY/ | ||
*/ | ||
export function sha512CryptAsync(textPassword, salt = '') { | ||
return new Promise((resolve, reject) => { | ||
@@ -8,23 +65,32 @@ if (!salt) | ||
if (salt.length > 16) | ||
return reject('The maximum length of salt is 16 characters'); | ||
return reject(new Error('The maximum length of salt is 16 characters')); | ||
resolve(sha512(textPassword, salt)); | ||
}); | ||
} | ||
export function verifySha512(textPassword, sha512Password) { | ||
/** | ||
* Verify passwords encrypted with sha512. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string | string[]} sha512Password - String or Array of strings to be compared to the plain text password. | ||
* | ||
* @example | ||
* const isValid = await verifySha512Async('mySuperSecretPassword', arrayOfSha512Passwords) | ||
* // return Promise that resolves to => true or false | ||
*/ | ||
export function verifySha512Async(textPassword, sha512Password) { | ||
return new Promise((resolve) => { | ||
let valid = false; | ||
let isValid = false; | ||
const sha512Passwords = typeof sha512Password === 'string' ? [sha512Password] : sha512Password; | ||
sha512Passwords.forEach(async (cryptPasswd, index) => { | ||
for (const cryptPasswd of sha512Passwords) { | ||
const hashType = cryptPasswd.match(/\{([^}]+)\}/); | ||
if (hashType && hashType[1] === 'CRYPT') { | ||
const salt = cryptPasswd.split('$')[2]; | ||
const hashedPassword = await sha512Crypt(textPassword, salt); | ||
const hashedPassword = sha512Crypt(textPassword, salt); | ||
if (hashedPassword === cryptPasswd) | ||
valid = true; | ||
isValid = true; | ||
} | ||
if (index === sha512Passwords.length - 1) | ||
return resolve(valid); | ||
}); | ||
} | ||
return resolve(isValid); | ||
}); | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -7,8 +7,3 @@ import antfu from '@antfu/eslint-config' | ||
rules: { | ||
'no-async-promise-executor': 'off', | ||
'no-use-before-define': 'off', | ||
'ts/no-use-before-define': 'off', | ||
'no-tabs': 'off', | ||
'prefer-promise-reject-errors': 'off', | ||
'no-throw-literal': 'off', | ||
}, | ||
@@ -15,0 +10,0 @@ stylistic: { |
{ | ||
"name": "ldap-sha512", | ||
"type": "module", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "Ldap sha512-crypt password generator for node", | ||
@@ -26,14 +26,13 @@ "author": { | ||
"build": "tsc", | ||
"dev": "tsc && node dist/index.js", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix", | ||
"test": "vitest run" | ||
"test": "tsc && vitest run" | ||
}, | ||
"devDependencies": { | ||
"@antfu/eslint-config": "^1.1.0", | ||
"@types/node": "^20.3.3", | ||
"eslint": "^8.53.0", | ||
"typescript": "^5.1.6", | ||
"vitest": "^0.34.6" | ||
"@antfu/eslint-config": "^2.6.1", | ||
"@types/node": "^20.10.6", | ||
"eslint": "^8.56.0", | ||
"typescript": "^5.3.3", | ||
"vitest": "^1.1.3" | ||
} | ||
} |
@@ -14,3 +14,3 @@ <h1 align="center">Ldap-sha512</h1> | ||
<a href="https://rosa.dev.br"> | ||
<img src="https://img.shields.io/badge/check me!-👻-06b6d4" alt="rosa.dev.br"/> | ||
<img src="https://img.shields.io/badge/check me!-👻-F28AA9" alt="rosa.dev.br"/> | ||
</a> | ||
@@ -31,6 +31,7 @@ </p> | ||
- yarn : `yarn add ldap-sha512` | ||
- bun : `bun add ldap-sha512` | ||
2. Import the function into your project: | ||
```ts | ||
import { sha512Crypt, verifySha512 } from 'ldap-sha512' | ||
import { sha512Crypt, sha512CryptAsync, verifySha512, verifySha512Async } from 'ldap-sha512' | ||
``` | ||
@@ -42,4 +43,9 @@ | ||
```ts | ||
const encryptedPassword = await sha512Crypt('mySuperSecretPassword') | ||
const encryptedPassword = sha512Crypt('mySuperSecretPassword') | ||
// return {CRYPT}$6$NQgPVC0up/oNVCb4$Aduz92Zfo/PFDE/XhvA3QmSqHquqdNiCdZvc9N5/UTpEUepMdd/6Mq/TeoM07wvyxHpg8ELGVzTWZt2e7Z9LY/ | ||
// OR | ||
const encryptedPassword = await sha512CryptAsync('mySuperSecretPassword') | ||
// return Promise that resolves to => {CRYPT}$6$NQgPVC0up/oNVCb4$Aduz92Zfo/PFDE/XhvA3QmSqHquqdNiCdZvc9N5/UTpEUepMdd/6Mq/TeoM07wvyxHpg8ELGVzTWZt2e7Z9LY/ | ||
``` | ||
@@ -50,4 +56,9 @@ | ||
```ts | ||
const encryptedPassword = await sha512Crypt('mySuperSecretPassword', 'myDopeCustomSalt') | ||
const encryptedPassword = sha512Crypt('mySuperSecretPassword', 'myDopeCustomSalt') | ||
// return {CRYPT}$6$myDopeCustomSalt$4ENRn.vwcs09z0fjr6Jt3NMOFVkn.p9v7ilDcK/CwRnQm48Y5HawkiGivh4gBTLwSY4SQNfCAe05E1nCTpZ0u. | ||
// OR | ||
const encryptedPassword = await sha512CryptAsync('mySuperSecretPassword', 'myDopeCustomSalt') | ||
// return Promise that resolves to => {CRYPT}$6$myDopeCustomSalt$4ENRn.vwcs09z0fjr6Jt3NMOFVkn.p9v7ilDcK/CwRnQm48Y5HawkiGivh4gBTLwSY4SQNfCAe05E1nCTpZ0u. | ||
``` | ||
@@ -58,4 +69,9 @@ | ||
```ts | ||
const isValid = await verifySha512('mySuperSecretPassword', arrayOfSha512Passwords) | ||
const isValid = verifySha512('mySuperSecretPassword', arrayOfSha512Passwords) | ||
// return true or false | ||
// OR | ||
const isValid = await verifySha512Async('mySuperSecretPassword', arrayOfSha512Passwords) | ||
// return Promise that resolves to => true or false | ||
``` | ||
@@ -65,3 +81,3 @@ | ||
Copyright © 2023 [Gabriel 'DethDKN' Rosa](https://github.com/dethdkn)\ | ||
This project is under [MIT license](https://github.com/dethdkn/ldap-sha512/blob/main/LICENSE) | ||
Copyright © 2024 [Gabriel 'DethDKN' Rosa](https://github.com/dethdkn)\ | ||
This project is under [MIT license](https://github.com/dethdkn/ldap-sha512/blob/main/LICENSE) |
@@ -0,0 +0,0 @@ class Int64 { |
@@ -1,2 +0,4 @@ | ||
export declare function sha512Crypt(textPassword: string, salt?: string): Promise<string> | ||
export declare function verifySha512(textPassword: string, sha512Password: string | string[]): Promise<boolean> | ||
export declare function sha512Crypt(textPassword: string, salt?: string): string | ||
export declare function verifySha512(textPassword: string, sha512Password: string | string[]): boolean | ||
export declare function sha512CryptAsync(textPassword: string, salt?: string): Promise<string> | ||
export declare function verifySha512Async(textPassword: string, sha512Password: string | string[]): Promise<boolean> |
import { randomBytes } from 'node:crypto' | ||
import { sha512 } from './helpers.js' | ||
export function sha512Crypt(textPassword: string, salt: string = ''): Promise<string> { | ||
/** | ||
* Encrypt a plain text password with the Ldap sha512crypt algorithm. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string} salt - Salt used to hash the password (it can't be greater than 16 characters). | ||
* @returns {string} - Encrypted password with the Ldap sha512crypt algorithm. | ||
* | ||
* @throws {Error} If salt length is greater than 16. | ||
* | ||
* @example | ||
* const encryptedPassword = sha512Crypt('mySuperSecretPassword') | ||
* // return {CRYPT}$6$NQgPVC0up/oNVCb4$Aduz92Zfo/PFDE/XhvA3QmSqHquqdNiCdZvc9N5/UTpEUepMdd/6Mq/TeoM07wvyxHpg8ELGVzTWZt2e7Z9LY/ | ||
*/ | ||
export function sha512Crypt(textPassword: string, salt: string = ''): string { | ||
if (!salt) | ||
salt = randomBytes(16).toString('base64').substring(0, 16) | ||
if (salt.length > 16) | ||
throw new Error('The maximum length of salt is 16 characters') | ||
return sha512(textPassword, salt) | ||
} | ||
/** | ||
* Verify passwords encrypted with sha512. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string | string[]} sha512Password - String or Array of strings to be compared to the plain text password. | ||
* | ||
* @example | ||
* const isValid = verifySha512('mySuperSecretPassword', arrayOfSha512Passwords) | ||
* // return true or false | ||
*/ | ||
export function verifySha512(textPassword: string, sha512Password: string | string[]): boolean { | ||
let isValid = false | ||
const sha512Passwords = typeof sha512Password === 'string' ? [sha512Password] : sha512Password | ||
for (const cryptPasswd of sha512Passwords) { | ||
const hashType = cryptPasswd.match(/\{([^}]+)\}/) | ||
if (hashType && hashType[1] === 'CRYPT') { | ||
const salt = cryptPasswd.split('$')[2] | ||
const hashedPassword = sha512Crypt(textPassword, salt) | ||
if (hashedPassword === cryptPasswd) | ||
isValid = true | ||
} | ||
} | ||
return isValid | ||
} | ||
/** | ||
* Encrypt a plain text password with the Ldap sha512crypt algorithm. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string} salt - Salt used to hash the password (it can't be greater than 16 characters). | ||
* @returns {string} - Encrypted password with the Ldap sha512crypt algorithm. | ||
* | ||
* @throws {Error} If salt length is greater than 16. | ||
* | ||
* @example | ||
* const encryptedPassword = await sha512CryptAsync('mySuperSecretPassword') | ||
* // return Promise that resolves to => {CRYPT}$6$NQgPVC0up/oNVCb4$Aduz92Zfo/PFDE/XhvA3QmSqHquqdNiCdZvc9N5/UTpEUepMdd/6Mq/TeoM07wvyxHpg8ELGVzTWZt2e7Z9LY/ | ||
*/ | ||
export function sha512CryptAsync(textPassword: string, salt: string = ''): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
@@ -9,3 +68,3 @@ if (!salt) | ||
if (salt.length > 16) | ||
return reject('The maximum length of salt is 16 characters') | ||
return reject(new Error('The maximum length of salt is 16 characters')) | ||
resolve(sha512(textPassword, salt)) | ||
@@ -15,18 +74,27 @@ }) | ||
export function verifySha512(textPassword: string, sha512Password: string | string[]): Promise<boolean> { | ||
/** | ||
* Verify passwords encrypted with sha512. | ||
* | ||
* @param {string} textPassword - Plain text password. | ||
* @param {string | string[]} sha512Password - String or Array of strings to be compared to the plain text password. | ||
* | ||
* @example | ||
* const isValid = await verifySha512Async('mySuperSecretPassword', arrayOfSha512Passwords) | ||
* // return Promise that resolves to => true or false | ||
*/ | ||
export function verifySha512Async(textPassword: string, sha512Password: string | string[]): Promise<boolean> { | ||
return new Promise((resolve) => { | ||
let valid = false | ||
const sha512Passwords: string[] = typeof sha512Password === 'string' ? [sha512Password] : sha512Password | ||
sha512Passwords.forEach(async (cryptPasswd, index) => { | ||
let isValid = false | ||
const sha512Passwords = typeof sha512Password === 'string' ? [sha512Password] : sha512Password | ||
for (const cryptPasswd of sha512Passwords) { | ||
const hashType = cryptPasswd.match(/\{([^}]+)\}/) | ||
if (hashType && hashType[1] === 'CRYPT') { | ||
const salt = cryptPasswd.split('$')[2] | ||
const hashedPassword = await sha512Crypt(textPassword, salt) | ||
const hashedPassword = sha512Crypt(textPassword, salt) | ||
if (hashedPassword === cryptPasswd) | ||
valid = true | ||
isValid = true | ||
} | ||
if (index === sha512Passwords.length - 1) | ||
return resolve(valid) | ||
}) | ||
} | ||
return resolve(isValid) | ||
}) | ||
} |
import { expect, it } from 'vitest' | ||
import { sha512Crypt, verifySha512 } from '../src/index' | ||
import { sha512Crypt, sha512CryptAsync, verifySha512, verifySha512Async } from '../src/index' | ||
@@ -7,6 +7,7 @@ const password = 'mySuperSecretPassword' | ||
const encryptedPass = '{CRYPT}$6$myDopeCustomSalt$4ENRn.vwcs09z0fjr6Jt3NMOFVkn.p9v7ilDcK/CwRnQm48Y5HawkiGivh4gBTLwSY4SQNfCAe05E1nCTpZ0u.' | ||
const anotherEncryptedPass = '{CRYPT}$6$myDopeCustomSalt$D4JKgzmZmNroxjTQyA2MAsNvWvfxGCKVLzL1aGO0UMD24HGPiKvoZO0r899u.keezGsMdod3XSbXyOSFJv32Z1' | ||
it('should return a string when not adding a salt', () => { | ||
const returnedPass = sha512Crypt(password) | ||
expect(returnedPass).resolves.toBeTypeOf('string') | ||
expect(returnedPass).toBeTypeOf('string') | ||
}) | ||
@@ -16,3 +17,3 @@ | ||
const returnedPass = sha512Crypt(password, salt) | ||
expect(returnedPass).resolves.toBeTypeOf('string') | ||
expect(returnedPass).toBeTypeOf('string') | ||
}) | ||
@@ -22,8 +23,7 @@ | ||
const returnedPass = sha512Crypt(password, salt) | ||
expect(returnedPass).resolves.toBe(encryptedPass) | ||
expect(returnedPass).toBe(encryptedPass) | ||
}) | ||
it('should return a error when adding a salt larger than 16 chars', () => { | ||
const returnedPass = sha512Crypt(password, 'saltLargerThan16Chars') | ||
expect(returnedPass).rejects.toThrow('The maximum length of salt is 16 characters') | ||
expect(() => sha512Crypt(password, 'saltLargerThan16Chars')).toThrowError(/^The maximum length of salt is 16 characters$/) | ||
}) | ||
@@ -33,8 +33,38 @@ | ||
const returnedVerification = verifySha512(password, encryptedPass) | ||
expect(returnedVerification).toBe(true) | ||
}) | ||
it('should return false', () => { | ||
const returnedVerification = verifySha512(password, anotherEncryptedPass) | ||
expect(returnedVerification).toBe(false) | ||
}) | ||
it('async - should return a string when not adding a salt', () => { | ||
const returnedPass = sha512CryptAsync(password) | ||
expect(returnedPass).resolves.toBeTypeOf('string') | ||
}) | ||
it('async - should return a string when adding a salt', () => { | ||
const returnedPass = sha512CryptAsync(password, salt) | ||
expect(returnedPass).resolves.toBeTypeOf('string') | ||
}) | ||
it('async - should return a string equals to the encrypted password', () => { | ||
const returnedPass = sha512CryptAsync(password, salt) | ||
expect(returnedPass).resolves.toBe(encryptedPass) | ||
}) | ||
it('async - should return a error when adding a salt larger than 16 chars', () => { | ||
const returnedPass = sha512CryptAsync(password, 'saltLargerThan16Chars') | ||
expect(returnedPass).rejects.toThrowError(/^The maximum length of salt is 16 characters$/) | ||
}) | ||
it('async - should return true', () => { | ||
const returnedVerification = verifySha512Async(password, encryptedPass) | ||
expect(returnedVerification).resolves.toBe(true) | ||
}) | ||
it('should return false', () => { | ||
const returnedVerification = verifySha512(password, '{CRYPT}$6$myDopeCustomSalt$D4JKgzmZmNroxjTQyA2MAsNvWvfxGCKVLzL1aGO0UMD24HGPiKvoZO0r899u.keezGsMdod3XSbXyOSFJv32Z1') | ||
it('async - should return false', () => { | ||
const returnedVerification = verifySha512Async(password, anotherEncryptedPass) | ||
expect(returnedVerification).resolves.toBe(false) | ||
}) |
@@ -0,0 +0,0 @@ { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
61180
755
78
0