{"id":30062546,"url":"https://github.com/dwtechs/hashitaka.js","last_synced_at":"2025-08-08T03:37:15.873Z","repository":{"id":308692392,"uuid":"1030958905","full_name":"DWTechs/Hashitaka.js","owner":"DWTechs","description":"Open source Node.js library for secure hash generation, encryption and comparison","archived":false,"fork":false,"pushed_at":"2025-08-07T10:30:30.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-07T11:20:27.898Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DWTechs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-02T17:43:04.000Z","updated_at":"2025-08-07T10:30:34.000Z","dependencies_parsed_at":"2025-08-07T11:20:47.760Z","dependency_job_id":"caadf7d5-efc3-461a-955f-4717a8ae0f32","html_url":"https://github.com/DWTechs/Hashitaka.js","commit_stats":null,"previous_names":["dwtechs/hashitaka.js"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/DWTechs/Hashitaka.js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FHashitaka.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FHashitaka.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FHashitaka.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FHashitaka.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DWTechs","download_url":"https://codeload.github.com/DWTechs/Hashitaka.js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DWTechs%2FHashitaka.js/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269360703,"owners_count":24404295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-08T02:00:09.200Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-08T03:37:12.295Z","updated_at":"2025-08-08T03:37:15.853Z","avatar_url":"https://github.com/DWTechs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n[![License: MIT](https://img.shields.io/npm/l/@dwtechs/hashitaka.svg?color=brightgreen)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40dwtechs%2Fhashitaka.svg)](https://www.npmjs.com/package/@dwtechs/hashitaka)\n[![last version release date](https://img.shields.io/github/release-date/DWTechs/Hashitaka.js)](https://www.npmjs.com/package/@dwtechs/hashitaka)\n![Jest:coverage](https://img.shields.io/badge/Jest:coverage-100%25-brightgreen.svg)\n[![minified size](https://img.shields.io/bundlephobia/min/@dwtechs/hashitaka?color=brightgreen)](https://www.npmjs.com/package/@dwtechs/hashitaka)\n\n- [Synopsis](#synopsis)\n- [Support](#support)\n- [Installation](#installation)\n- [Usage](#usage)\n- [API Reference](#api-reference)\n- [Error Handling](#error-handling)\n- [Express.js](#expressjs)\n- [Contributors](#contributors)\n- [Stack](#stack)\n\n\n## Synopsis\n\n**[Hashitaka.js](https://github.com/DWTechs/Hashitaka.js)** is an open source Node.js library for secure hash generation, encryption and comparison.\n\n- 📦 Only 1 dependency to check inputs variables\n- 🪶 Very lightweight\n- 🧪 Thoroughly tested\n- 🚚 Shipped as EcmaScrypt module\n- 📝 Written in Typescript\n\n\n## Support\n\n- Node.js: 22\n\nThis is the oldest targeted versions.  \nThe library uses node:crypto.  \n\n\n## Installation\n\n```bash\n$ npm i @dwtechs/hashitaka\n```\n\n\n## Usage\n\n### ES6 / TypeScript\n\nExample of use with Express.js using ES6 module format\n\n```javascript\n\nimport { compare, encrypt } from \"@dwtechs/hashitaka\";\nimport { randomPwd } from \"@dwtechs/passken\";\n\nconst { PWD_SECRET } = process.env;\n\n/**\n * This express middleware checks if a user-provided password matches a stored hashed password \n * in a database.\n * If the password is correct, it calls the next() function to proceed with the request.\n * If the password is incorrect or missing, it calls next() with an error.\n */\nfunction comparePwd(req, res, next) {\n  \n  const pwd = req.body.pwd; // from request\n  const hash = req.user.hash; //from db\n  try {\n    if (compare(pwd, hash, PWD_SECRET))\n      return next();\n    return next({statusCode: 401, message: \"Invalid password\" });\n  } catch (err) {\n    return next(err);\n  }\n\n}\n\n\n/**\n * This express middleware generates a random password for a user and encrypts it.\n */\nfunction createPwd(req, res, next) {\n\n  const user = req.body.user;\n  const options = {\n    len: 14,\n    num: true,\n    ucase: true,\n    lcase: true,\n    sym: true,\n    strict: true,\n    similarChars: true,\n  };\n  user.pwd = randomPwd(options);\n  user.pwdHash = encrypt(user.pwd, PWD_SECRET);\n  next();\n\n}\n\nexport {\n  comparePwd,\n  createPwd,\n};\n\n```\n\n\n## API Reference\n\n### Hash\n\n```typescript\n\n// Default values\nlet saltRnds = 12\nlet digest = \"sha256\";\nlet keyLen = 64;\n\n/**\n * Returns the number of salt rounds used for hashing.\n *\n * @returns {number} The number of salt rounds.\n */\nfunction getSaltRounds(): number {}\n\n/**\n * Sets the number of salt rounds for hashing.\n *\n * @param {number} rnds - The number of salt rounds to set. Must be a valid integer \n * between 12 and 100.\n * @returns {boolean} True if the salt rounds were successfully set, otherwise false.\n */\nfunction setSaltRounds(rnds: number): boolean {} // between 12 and 100\n\n/**\n * Returns the key length used for hashing.\n *\n * @returns {number} The key length.\n */\nfunction getKeyLen(): number {}\n\n/**\n * Sets the key length to the specified value for hashing.\n *\n * @param {number} len - The desired key length. Must be a valid integer \n * between 2 and 256.\n * @returns {boolean} True if the key length was successfully set; \n * otherwise false.\n */\nfunction setKeyLen(r: number): boolean {} // between 2 and 256\n\n/**\n * Returns the hash function used for hashing.\n *\n * @returns {string} The hash function.\n */\nfunction getDigest(): string {}\n\n/**\n * Sets the hash function used for hashing.\n * The list of available digests is returned by getDigests()\n *\n * @param {string} func - The hash function. Must be a valid value from the list of \n * available hash functions.\n * @returns {boolean} True if the hash function was successfully set; otherwise false.\n */\nfunction setDigest(d: string): boolean {}\n\n/**\n * Returns the list of available hash functions.\n *\n * @returns {string[]} The list of available hash functions.\n */\nfunction getDigests(): string[] {}\n\n/**\n * Encrypts a password using a base64 encoded secret.\n *\n * @param {string} str - The password to encrypt. Must be a non-empty string.\n * @param {string} b64Secret - The base64 encoded secret used for encryption. \n * Must be a valid base64 encoded string.\n * @returns {string} The encrypted password as a hex string prefixed with a random salt.\n * @throws {InvalidStringError} If `str` is not a non-empty string.\n * @throws {InvalidBase64SecretError} If `b64Secret` is not a valid base64 encoded string.\n */\nfunction encrypt( str: string, \n                  b64Secret: string\n                ): string | false {}\n\n/**\n * Compares a plaintext string with a hashed string using a secret.\n *\n * @param {string} str - The plaintext string to compare.\n * @param {string} hash - The hashed string to compare against.\n * @param {string} b64Secret - The base64 encoded secret used for hashing.\n * @returns {boolean} true if the password matches the hash, false otherwise.\n * @throws {InvalidStringError} If `str` or `hash` is not a non-empty string.\n * @throws {InvalidBase64SecretError} If `b64Secret` is not a valid base64 encoded string.\n */\nfunction compare( str: string, \n                  hash: string,\n                  b64Secret: string\n                ): boolean {}\n\n```\n\n### Secret\n\n```typescript\n\n/**\n * Generates a random string of the specified length, encoded in base64.\n *\n * @param {number} [length=32] - The length of the random string to generate. \n * Defaults to 32 if not specified.\n * @returns {string} The generated random string encoded in base64.\n */\nrndB64Secret(length = 32): string\n\n```\n\n\n### Base64\n\n---\n\n```typescript\n\n/**\n * Decodes a base64 encoded string.\n *\n * @param {string} str - The base64 encoded string to decode.\n * @param {boolean} urlSafe - A boolean indicating if the input string is URL safe. \n * Defaults to true.\n * @returns {string} The decoded string in UTF-8 format.\n * @throws {InvalidStringError} If `str` is not a non-empty string.\n */\nfunction b64Decode(str: string, urlSafe = true): string;\n\n/**\n * Encodes a given string into Base64 format.\n * \n * @param {string} str - The string to be encoded.\n * @param {boolean} urlSafe - Optional boolean to determine if the output should be URL safe. \n * Defaults to true.\n * @returns {string} The Base64 encoded string. If `urlSafe` is true, the output will be modified \n * to be URL safe.\n * @throws {InvalidStringError} If `str` is not a non-empty string.\n */\nfunction b64Encode(str: string, urlSafe = true): string;\n\n```\n\n## Error Handling\n\nHashitaka uses a structured error system that helps you identify and handle specific error cases. All errors extend from a base `HashitakaError` class.\n\n### Error Classes Hierarchy\n\n```\nHashitakaError (abstract base class)\n├── HashLengthMismatchError\n├── InvalidStringError\n└── InvalidBase64SecretError\n```\n\n### Common Properties\n\nAll error classes share these properties:\n\n- `message`: Human-readable error description\n- `code`: Human-readable error code (e.g., \"TOKEN_EXPIRED\")\n- `statusCode`: Suggested HTTP status code (e.g., 401)\n- `stack`: Error stack trace\n\n### Using Error Handling\n\n```typescript\nimport { encrypt, HashitakaError, HashLengthMismatchError } from '@dwtechs/hashitaka';\n\ntry {\n  const result = encrypt('mySecret', 'invalidBase64Secret');\n  // ...use result\n} catch (err) {\n  if (err instanceof HashLengthMismatchError) {\n    // Handle a specific error\n    console.error('Hash length mismatch:', err.message);\n  } else if (err instanceof HashitakaError) {\n    // Handle any library-specific error\n    console.error(`Hashitaka error [${err.code}]:`, err.message);\n  } else {\n    // Handle other/unexpected errors\n    console.error('Unknown error:', err);\n  }\n}\n```\n\n### Error Types and HTTP Status Codes\n\n| Error Class | Code | Status Code | Description |\n|-------------|------|-------------|-------------|\n| HashLengthMismatchError | HASH_LENGTH_MISMATCH | 400 | Hashes must have the same byte length |\n| InvalidStringError | INVALID_STRING | 400 | str must be a non-empty string |\n| InvalidBase64SecretError | INVALID_BASE64_SECRET | 400 | b64Secret must be a base64 encoded string |\n\n\n## Express.js\n\nYou can use Hashitaka directly as Express.js middlewares using: \n- [@dwtechs/passken-express library](https://www.npmjs.com/package/@dwtechs/passken-express) for password related middlewares.\n- [@dwtechs/toker-express library](https://www.npmjs.com/package/@dwtechs/toker-express) for JWT related middlewares.\nThis way you do not have to write express controllers yourself.\n\n\n## Contributors\n\n**Hashitaka.js** is still in development and we would be glad to get all the help you can provide.\nTo contribute please read **[contributor.md](https://github.com/DWTechs/Hashitaka.js/blob/main/contributor.md)** for detailed installation guide.\n\n\n## Stack\n\n| Purpose         |                    Choice                    |                             Motivation |\n| :-------------- | :------------------------------------------: | -------------------------------------------------------------: |\n| repository      |        [Github](https://github.com/)         |     hosting for software development version control using Git |\n| package manager |     [npm](https://www.npmjs.com/get-npm)     |                                default node.js package manager |\n| language        | [TypeScript](https://www.typescriptlang.org) | static type checking along with the latest ECMAScript features |\n| module bundler  |      [Rollup.js](https://rollupjs.org)       |                        advanced module bundler for ES6 modules |\n| unit testing    |          [Jest](https://jestjs.io/)          |                  delightful testing with a focus on simplicity |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwtechs%2Fhashitaka.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwtechs%2Fhashitaka.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwtechs%2Fhashitaka.js/lists"}