https://github.com/dwtechs/hashitaka.js
Open source Node.js library for secure hash generation, encryption and comparison
https://github.com/dwtechs/hashitaka.js
Last synced: 10 months ago
JSON representation
Open source Node.js library for secure hash generation, encryption and comparison
- Host: GitHub
- URL: https://github.com/dwtechs/hashitaka.js
- Owner: DWTechs
- License: mit
- Created: 2025-08-02T17:43:04.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-08-07T10:30:30.000Z (10 months ago)
- Last Synced: 2025-08-07T11:20:27.898Z (10 months ago)
- Language: JavaScript
- Homepage:
- Size: 65.4 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://opensource.org/licenses/MIT)
[](https://www.npmjs.com/package/@dwtechs/hashitaka)
[](https://www.npmjs.com/package/@dwtechs/hashitaka)

[](https://www.npmjs.com/package/@dwtechs/hashitaka)
- [Synopsis](#synopsis)
- [Support](#support)
- [Installation](#installation)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Error Handling](#error-handling)
- [Express.js](#expressjs)
- [Contributors](#contributors)
- [Stack](#stack)
## Synopsis
**[Hashitaka.js](https://github.com/DWTechs/Hashitaka.js)** is an open source Node.js library for secure hash generation, encryption and comparison.
- ๐ฆ Only 1 dependency to check inputs variables
- ๐ชถ Very lightweight
- ๐งช Thoroughly tested
- ๐ Shipped as EcmaScrypt module
- ๐ Written in Typescript
## Support
- Node.js: 22
This is the oldest targeted versions.
The library uses node:crypto.
## Installation
```bash
$ npm i @dwtechs/hashitaka
```
## Usage
### ES6 / TypeScript
Example of use with Express.js using ES6 module format
```javascript
import { compare, encrypt } from "@dwtechs/hashitaka";
import { randomPwd } from "@dwtechs/passken";
const { PWD_SECRET } = process.env;
/**
* This express middleware checks if a user-provided password matches a stored hashed password
* in a database.
* If the password is correct, it calls the next() function to proceed with the request.
* If the password is incorrect or missing, it calls next() with an error.
*/
function comparePwd(req, res, next) {
const pwd = req.body.pwd; // from request
const hash = req.user.hash; //from db
try {
if (compare(pwd, hash, PWD_SECRET))
return next();
return next({statusCode: 401, message: "Invalid password" });
} catch (err) {
return next(err);
}
}
/**
* This express middleware generates a random password for a user and encrypts it.
*/
function createPwd(req, res, next) {
const user = req.body.user;
const options = {
len: 14,
num: true,
ucase: true,
lcase: true,
sym: true,
strict: true,
similarChars: true,
};
user.pwd = randomPwd(options);
user.pwdHash = encrypt(user.pwd, PWD_SECRET);
next();
}
export {
comparePwd,
createPwd,
};
```
## API Reference
### Hash
```typescript
// Default values
let saltRnds = 12
let digest = "sha256";
let keyLen = 64;
/**
* Returns the number of salt rounds used for hashing.
*
* @returns {number} The number of salt rounds.
*/
function getSaltRounds(): number {}
/**
* Sets the number of salt rounds for hashing.
*
* @param {number} rnds - The number of salt rounds to set. Must be a valid integer
* between 12 and 100.
* @returns {boolean} True if the salt rounds were successfully set, otherwise false.
*/
function setSaltRounds(rnds: number): boolean {} // between 12 and 100
/**
* Returns the key length used for hashing.
*
* @returns {number} The key length.
*/
function getKeyLen(): number {}
/**
* Sets the key length to the specified value for hashing.
*
* @param {number} len - The desired key length. Must be a valid integer
* between 2 and 256.
* @returns {boolean} True if the key length was successfully set;
* otherwise false.
*/
function setKeyLen(r: number): boolean {} // between 2 and 256
/**
* Returns the hash function used for hashing.
*
* @returns {string} The hash function.
*/
function getDigest(): string {}
/**
* Sets the hash function used for hashing.
* The list of available digests is returned by getDigests()
*
* @param {string} func - The hash function. Must be a valid value from the list of
* available hash functions.
* @returns {boolean} True if the hash function was successfully set; otherwise false.
*/
function setDigest(d: string): boolean {}
/**
* Returns the list of available hash functions.
*
* @returns {string[]} The list of available hash functions.
*/
function getDigests(): string[] {}
/**
* Encrypts a password using a base64 encoded secret.
*
* @param {string} str - The password to encrypt. Must be a non-empty string.
* @param {string} b64Secret - The base64 encoded secret used for encryption.
* Must be a valid base64 encoded string.
* @returns {string} The encrypted password as a hex string prefixed with a random salt.
* @throws {InvalidStringError} If `str` is not a non-empty string.
* @throws {InvalidBase64SecretError} If `b64Secret` is not a valid base64 encoded string.
*/
function encrypt( str: string,
b64Secret: string
): string | false {}
/**
* Compares a plaintext string with a hashed string using a secret.
*
* @param {string} str - The plaintext string to compare.
* @param {string} hash - The hashed string to compare against.
* @param {string} b64Secret - The base64 encoded secret used for hashing.
* @returns {boolean} true if the password matches the hash, false otherwise.
* @throws {InvalidStringError} If `str` or `hash` is not a non-empty string.
* @throws {InvalidBase64SecretError} If `b64Secret` is not a valid base64 encoded string.
*/
function compare( str: string,
hash: string,
b64Secret: string
): boolean {}
```
### Secret
```typescript
/**
* Generates a random string of the specified length, encoded in base64.
*
* @param {number} [length=32] - The length of the random string to generate.
* Defaults to 32 if not specified.
* @returns {string} The generated random string encoded in base64.
*/
rndB64Secret(length = 32): string
```
### Base64
---
```typescript
/**
* Decodes a base64 encoded string.
*
* @param {string} str - The base64 encoded string to decode.
* @param {boolean} urlSafe - A boolean indicating if the input string is URL safe.
* Defaults to true.
* @returns {string} The decoded string in UTF-8 format.
* @throws {InvalidStringError} If `str` is not a non-empty string.
*/
function b64Decode(str: string, urlSafe = true): string;
/**
* Encodes a given string into Base64 format.
*
* @param {string} str - The string to be encoded.
* @param {boolean} urlSafe - Optional boolean to determine if the output should be URL safe.
* Defaults to true.
* @returns {string} The Base64 encoded string. If `urlSafe` is true, the output will be modified
* to be URL safe.
* @throws {InvalidStringError} If `str` is not a non-empty string.
*/
function b64Encode(str: string, urlSafe = true): string;
```
## Error Handling
Hashitaka uses a structured error system that helps you identify and handle specific error cases. All errors extend from a base `HashitakaError` class.
### Error Classes Hierarchy
```
HashitakaError (abstract base class)
โโโ HashLengthMismatchError
โโโ InvalidStringError
โโโ InvalidBase64SecretError
```
### Common Properties
All error classes share these properties:
- `message`: Human-readable error description
- `code`: Human-readable error code (e.g., "TOKEN_EXPIRED")
- `statusCode`: Suggested HTTP status code (e.g., 401)
- `stack`: Error stack trace
### Using Error Handling
```typescript
import { encrypt, HashitakaError, HashLengthMismatchError } from '@dwtechs/hashitaka';
try {
const result = encrypt('mySecret', 'invalidBase64Secret');
// ...use result
} catch (err) {
if (err instanceof HashLengthMismatchError) {
// Handle a specific error
console.error('Hash length mismatch:', err.message);
} else if (err instanceof HashitakaError) {
// Handle any library-specific error
console.error(`Hashitaka error [${err.code}]:`, err.message);
} else {
// Handle other/unexpected errors
console.error('Unknown error:', err);
}
}
```
### Error Types and HTTP Status Codes
| Error Class | Code | Status Code | Description |
|-------------|------|-------------|-------------|
| HashLengthMismatchError | HASH_LENGTH_MISMATCH | 400 | Hashes must have the same byte length |
| InvalidStringError | INVALID_STRING | 400 | str must be a non-empty string |
| InvalidBase64SecretError | INVALID_BASE64_SECRET | 400 | b64Secret must be a base64 encoded string |
## Express.js
You can use Hashitaka directly as Express.js middlewares using:
- [@dwtechs/passken-express library](https://www.npmjs.com/package/@dwtechs/passken-express) for password related middlewares.
- [@dwtechs/toker-express library](https://www.npmjs.com/package/@dwtechs/toker-express) for JWT related middlewares.
This way you do not have to write express controllers yourself.
## Contributors
**Hashitaka.js** is still in development and we would be glad to get all the help you can provide.
To contribute please read **[contributor.md](https://github.com/DWTechs/Hashitaka.js/blob/main/contributor.md)** for detailed installation guide.
## Stack
| Purpose | Choice | Motivation |
| :-------------- | :------------------------------------------: | -------------------------------------------------------------: |
| repository | [Github](https://github.com/) | hosting for software development version control using Git |
| package manager | [npm](https://www.npmjs.com/get-npm) | default node.js package manager |
| language | [TypeScript](https://www.typescriptlang.org) | static type checking along with the latest ECMAScript features |
| module bundler | [Rollup.js](https://rollupjs.org) | advanced module bundler for ES6 modules |
| unit testing | [Jest](https://jestjs.io/) | delightful testing with a focus on simplicity |