{"id":19232637,"url":"https://github.com/makeomatic/ms-token","last_synced_at":"2025-07-02T04:32:43.241Z","repository":{"id":10167998,"uuid":"62556549","full_name":"makeomatic/ms-token","owner":"makeomatic","description":"utils for associating specific data with a token, encoding \u0026 decoding it","archived":false,"fork":false,"pushed_at":"2024-10-23T17:59:30.000Z","size":472,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-21T04:42:26.911Z","etag":null,"topics":["challenge","mail","node","nodejs","phone","secret","verification"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/makeomatic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2016-07-04T11:17:21.000Z","updated_at":"2024-10-23T17:24:58.000Z","dependencies_parsed_at":"2025-04-21T04:52:09.296Z","dependency_job_id":null,"html_url":"https://github.com/makeomatic/ms-token","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/makeomatic/ms-token","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makeomatic%2Fms-token","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makeomatic%2Fms-token/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makeomatic%2Fms-token/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makeomatic%2Fms-token/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/makeomatic","download_url":"https://codeload.github.com/makeomatic/ms-token/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/makeomatic%2Fms-token/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263074849,"owners_count":23409828,"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":["challenge","mail","node","nodejs","phone","secret","verification"],"created_at":"2024-11-09T16:07:00.859Z","updated_at":"2025-07-02T04:32:43.181Z","avatar_url":"https://github.com/makeomatic.png","language":"TypeScript","readme":"# Token Orchestrator\n\n[![Build Status](https://semaphoreci.com/api/v1/makeomatic/ms-token/branches/master/shields_badge.svg)](https://semaphoreci.com/makeomatic/ms-token)\n[![codecov](https://codecov.io/gh/makeomatic/ms-token/branch/master/graph/badge.svg)](https://codecov.io/gh/makeomatic/ms-token)\n\nThere is a common task that requires one to request challenges to be performed for a specific action. Imagine user, who wants to register\nfor you service and you need to validate an email, or you want to issue an invitation and remove the burden of activation from a user, as well as\nsupply extra meta information with that token. Furthermore, you often need to throttle specific requests and make sure they are not performed more\nthan once in a certain time span. All of these tasks are easily handled by this module\n\n## Install me\n\n`npm i ms-token -S`\n\n## API\n\nModule API is pretty simple and contains only 4 functions alongside initialization.\nWhen reading docs, keep in mind that anything in `[]` is an optional prop.\n\n### `new TokenManager(args)`\n\n* `args.backend`:\n  * `name`: supported backends include: `redis`\n  * `connection`: appropriate connector, `ioredis` instance for `redis`\n  * `prefix`: optional, used in `redis` backend as key prefix\n* `args.encrypt`, used in `crypto.createCipher(algorithm, password)` when encoding long tokens:\n  * `algorithm`: one of `openssl list-cipher-algorithms`, example: `aes192`\n  * `sharedSecret`: The password is used to derive the cipher key and initialization vector (IV).\n  The value must be either a 'binary' encoded string or a Buffer.\n\n\n```js\nconst TokenManager = require('ms-token');\nconst Redis = require('ioredis');\nconst tokenManager = new TokenManager({\n  backend: {\n    name: 'redis',\n    connection: new Redis(),\n    prefix: 'ms-token:',\n  },\n  encrypt: {\n    algorithm: 'aes256',\n    sharedSecret: Buffer.from('incredibly-long-secret-ooooohooo'),\n  },\n});\n```\n\n### `tokenManager.create(args)`\n\nUse this to create challenge token, which should be sent to user for verification purposes.\n\nAccepts:\n\n* `args.action`: unique action name, non-empty string\n* `args.id`: unique request identification. For instance, if you are going to send this to an email, use `email` as id. If this is going to be a\ntoken sent to the phone - use normalized phone number. Combination of `action` \u0026 `id` grants access to `secret`, while `secret` grants access to all associated\nmetadata\n* `[args.ttl]`: token expiration, in `seconds`\n* `[args.throttle]`:\n  * `true`: would be equal to `args.ttl`, in that case `ttl` must be defined\n  * `Number`: do not allow creating token for `args.{action,id}` combo for `Number` amount of `seconds`. Sometimes you want throttle to be small (60 seconds),\n  and ttl to be 15 mins (text messages), or 2 hours and 24 hours (emails)\n* `[args.metadata]`: Mixed content, must be able to `JSON.stringify` it\n* `[args.secret]`:\n  * `true`, default. in that case secret would be automatically generated and would include encrypted public data + generated secret\n  * `false`, do not generate secret. In that case it would simply use `action + id` for verification/unlocking\n  * `Object`:\n    * `type`: enumerable, acceptable values are: `alphabet`, `number`, `uuid` (default `uuid`)\n    * `[alphabet]`: string containing characters that are allowed to be used in the secret. Only used in `alphabet` mode\n    * `[length]`: length of generated secret, only used in `alphabet` and `number` mode\n    * `[encrypt]`: defaults to `true` for `uuid`. If `true` - then returned token includes `action`, `id` \u0026 generated `secret` encrypted in it. That token alone is enough for verification function. If `false` - it returns plain text generated secret, you must pass `action`, `id` and `secret` to verification function in order for it to succeed\n* `[args.regenerate]`: defauls to `false`. If set to `true` would allow usage of `.regenerate()` API by returning `uid` of this challenge\n\nReturns `Object`:\n\n* `id`: id from `args`\n* `action`: action from `args`\n* `[uid]`: token unique identificator, when `regenerate` is true\n* `[secret]`: send secret to user for completing challenge (for instance via SMS). Secret is not present if was set to false\n\n### `tokenManager.info(args)`\n\nReturns associated data for an already created token. It doesn't perform any verifications.\nThis action should be considered a system action, which could be used for debugging purposes.\n\nInput:\n\n* `args`, must have one of `uid`, `args.action` and `args.id` combo or `args.secret` + `args.encrypt` combo\n* `args.uid`: `String`\n* `args.action`: `String`\n* `args.id`: `String`\n* `args.secret`: `String`\n* `args.encrypt`: `Boolean` - `true` is secret must be encrypted, `false` otherwise. If `false` then `id` and `action` must be supplied alongside\nsecret\n\nResponse:\n\n* `Object`: associated metadata with a given input\n\n### `tokenManager.regenerate(uid)`\n\nWorks with both `uid` OR `action`\u0026 `id` combo. Sometimes challenge token might not reach the user and the user would want to ask\nfor another challenge token. Idea of this is to accept public challenge `uid`, which would use previous data passed in `.create(args)`\nand generate new secret based on this. Can only be used when `regenerate` was set to `true` on the `.create(args)` action\n\nInput:\n\n* `uid` - uid from `.create(args)`, when `regenerate` was set to `true`\n\nResponse:\n\n* `String`: newly generated secret, either plain-text or encrypted based on what was passed earlier in `.create(args)`\n\n### `tokenManager.verify(args, [opts])`\n\nUsed for completing challenge by verifying user input.\n\nAccepts:\n\n* `args` as `String`, we would attempt to decode \u0026 verify in according with encryption settings\n* `args` as `Object`:\n  * `args.action` - action from `.create()`\n  * `args.id` - id from `.create()`\n  * `args.token` - secret from `.crete()` return value\n* `[opts]` as `Object`:\n  * `opts.erase`: Defaults to `true`. if `true`, when verification succeeds - associated `throttle` is removed, as well as any notion of this token\n  * `opts.log`: if `true`, logs attempt time.\n  * `opts.control`: verifies that decrypted args contains same values\n    * `opts.id` -\u003e checks id\n    * `opts.action` -\u003e checks action\n\nResponse, always `Object` in case of successful verification:\n\n* `id`\n* `action`\n* `uid`\n* `secret`\n* `created`\n* `settings`\n* `metadata`\n* `isFirstVerification` - whether this was a first successful verification\n* `verified` - timestamp when it was verified\n\nOtherwise rejects promise with an error\n\n### `tokenManager.remove(args)`\n\n* `args` as `String`, we would attempt to decode \u0026 verify in according with encryption settings\n* `args` as `Object`:\n  * `args.uid` - either `uid` OR `action` \u0026 `id` combination\n  * `args.action` - action from `.create()`\n  * `args.id` - id from `.create()`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmakeomatic%2Fms-token","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmakeomatic%2Fms-token","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmakeomatic%2Fms-token/lists"}