{"id":17835056,"url":"https://github.com/namesmt/shash","last_synced_at":"2025-03-19T15:30:18.678Z","repository":{"id":249733546,"uuid":"832415679","full_name":"NamesMT/shash","owner":"NamesMT","description":"Simple stateful-salt hash helper","archived":false,"fork":false,"pushed_at":"2025-03-14T04:19:47.000Z","size":144,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-19T10:09:47.888Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/NamesMT.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}},"created_at":"2024-07-23T01:40:27.000Z","updated_at":"2024-09-13T07:31:56.000Z","dependencies_parsed_at":"2024-07-23T02:47:22.533Z","dependency_job_id":"3ef90eb4-f027-42dc-83b6-d7c8b1afc969","html_url":"https://github.com/NamesMT/shash","commit_stats":null,"previous_names":["namesmt/shash"],"tags_count":10,"template":false,"template_full_name":"NamesMT/starter-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fshash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fshash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fshash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fshash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NamesMT","download_url":"https://codeload.github.com/NamesMT/shash/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244453655,"owners_count":20455253,"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","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":"2024-10-27T20:16:40.719Z","updated_at":"2025-03-19T15:30:18.332Z","avatar_url":"https://github.com/NamesMT.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# shash ![TypeScript heart icon](https://img.shields.io/badge/♡-%23007ACC.svg?logo=typescript\u0026logoColor=white)\n\n[![npm version][npm-version-src]][npm-version-href]\n[![npm downloads][npm-downloads-src]][npm-downloads-href]\n[![Codecov][codecov-src]][codecov-href]\n[![Bundlejs][bundlejs-src]][bundlejs-href]\n[![jsDocs.io][jsDocs-src]][jsDocs-href]\n\n**shash** (SHash - Stateful-salt Hash)\n\nSHash is not a cryptographic hashing algorithm, it is a collection of helpers to implement a hash secret system with multiple layers of security.\n\nSHash requires a storage interface to be passed in, which is used to store the stateful salt.\n\nSHash aims to be simple and easy to use, to help you implement a hash secret with multiple layers of security:  \nSHash stores a stateful salt, which means that there is a layer of database/storage.  \nSHash allows you to specify your additional salt, which could add two layers: hard-coded salt and environment salt.  \nThe hashed value is calculated as needed with all the salts and is not stored.  \n\nSHash supports any hashing algorithm, it is recommended to use SHA256 for the balance of security and performance,  \nDo note that SHA256 is NOT SAFE for highly sensitive information like passwords, because it is relatively fast and easier for an attacker to crack your passwords in case of a full breach of all layers.\n\nNote: Hashing algorithm is not included in this package, you can use any hashing algorithm you want.\n\n## Features\n- [x] TypeScript ready!\n\n## Usage\n### Install package:\n```sh\n# npm\nnpm install @namesmt/shash\n\n# yarn\nyarn add @namesmt/shash\n\n# pnpm (recommended)\npnpm install @namesmt/shash\n```\n\n### Import and use:\n```ts\n// ESM\nimport { SHash } from '@namesmt/shash'\n\n/**\n * This is a simple in-memory storage implementation.\n * \n * This is not recommended for production use, but it is useful for testing.\n */\nclass MemoryStorage implements SHashStorageInterface {\n  store: Record\u003cstring, string\u003e = {}\n\n  async getSalt(partition: string, id: string) { return this.store[`${partition}#${id}`] }\n  async setSalt(partition: string, id: string, value: string | undefined) {\n    if (value === undefined)\n      delete this.store[`${partition}#${id}`]\n    else\n      this.store[`${partition}#${id}`] = value\n  }\n}\n\n// A simple hash function for demo purposes\nfunction demoHash(str: string) {\n  return `${str}-demohashed`\n}\n\nconst {\n  getHash, // getHash will create a new salt for the partition and id if it does not exist.\n  getExistHash, // getExistHash only returns the hash if it the stateful salt exists.\n  verifyHash, // verify functions will call get* under-the-hood and then verify it with the given key, throws if it does not match.\n  verifyExistHash,\n  cleanSalt, // cleanSalt will remove the stateful salt for the partition and id.\n} = new SHash(new MemoryStorage(), demoHash) // You could pass in any hashing algorithm\n\n// It is recommended to use a hybrid salt from environment variable and hard-coded like: `salted${env.SECRET_SAUCE}`\nconst hash = await getHash('salt', 'partition', 'id')\n```\n\n## Roadmap\n- [ ] Become the legendary 10000x developer\n\n## License [![License][license-src]][license-href]\n[MIT](./LICENSE) License © 2024 [NamesMT](https://github.com/NamesMT)\n\n\u003c!-- Badges --\u003e\n\n[npm-version-src]: https://img.shields.io/npm/v/@namesmt/shash?labelColor=18181B\u0026color=F0DB4F\n[npm-version-href]: https://npmjs.com/package/@namesmt/shash\n[npm-downloads-src]: https://img.shields.io/npm/dm/@namesmt/shash?labelColor=18181B\u0026color=F0DB4F\n[npm-downloads-href]: https://npmjs.com/package/@namesmt/shash\n[codecov-src]: https://img.shields.io/codecov/c/gh/namesmt/shash/main?labelColor=18181B\u0026color=F0DB4F\n[codecov-href]: https://codecov.io/gh/namesmt/shash\n[license-src]: https://img.shields.io/github/license/namesmt/shash.svg?labelColor=18181B\u0026color=F0DB4F\n[license-href]: https://github.com/namesmt/shash/blob/main/LICENSE\n[bundlejs-src]: https://img.shields.io/bundlejs/size/@namesmt/shash?labelColor=18181B\u0026color=F0DB4F\n[bundlejs-href]: https://bundlejs.com/?q=@namesmt/shash\n[jsDocs-src]: https://img.shields.io/badge/Check_out-jsDocs.io---?labelColor=18181B\u0026color=F0DB4F\n[jsDocs-href]: https://www.jsdocs.io/package/@namesmt/shash\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnamesmt%2Fshash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnamesmt%2Fshash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnamesmt%2Fshash/lists"}