{"id":26880016,"url":"https://github.com/mobilpadde/moths","last_synced_at":"2025-07-25T20:02:13.168Z","repository":{"id":65211569,"uuid":"486392333","full_name":"Mobilpadde/moths","owner":"Mobilpadde","description":"moths: emojicon authentications","archived":false,"fork":false,"pushed_at":"2023-06-08T17:08:00.000Z","size":195,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-06-21T09:13:12.175Z","etag":null,"topics":["emoji","go"],"latest_commit_sha":null,"homepage":"","language":"Go","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/Mobilpadde.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2022-04-28T00:24:11.000Z","updated_at":"2023-07-25T18:56:01.000Z","dependencies_parsed_at":"2024-06-20T07:12:40.857Z","dependency_job_id":"e33f1f65-ce0e-403e-b7b3-a322d1dbe4b8","html_url":"https://github.com/Mobilpadde/moths","commit_stats":{"total_commits":109,"total_committers":1,"mean_commits":109.0,"dds":0.0,"last_synced_commit":"b8d12a79ae9f587d30893ee83cf47f727a68c7f4"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mobilpadde%2Fmoths","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mobilpadde%2Fmoths/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mobilpadde%2Fmoths/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mobilpadde%2Fmoths/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mobilpadde","download_url":"https://codeload.github.com/Mobilpadde/moths/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246474948,"owners_count":20783576,"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":["emoji","go"],"created_at":"2025-03-31T13:34:36.135Z","updated_at":"2025-03-31T13:34:37.349Z","avatar_url":"https://github.com/Mobilpadde.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# moths 🪰\n\n\u003e e**mo**jicon au**th**entication**s**\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/Mobilpadde/moths/v6.svg)](https://pkg.go.dev/github.com/Mobilpadde/moths/v6)\n[![codecov](https://codecov.io/gh/Mobilpadde/moths/branch/main/graph/badge.svg?token=VpeLKuFdDx)](https://codecov.io/gh/Mobilpadde/moths)\n\n## what (is this 💩)\n\nEmojies as [TOTP](https://rublon.com/blog/hotp-totp-difference/), [because](#why-).\n\n## why 🥲\n\nWe _all_ **could** use a little more emotion in our lives 🤗 Go show the world how you really feel!\n\nIt's a great companion for any app that uses 2FA - as every app should! Make your app's 2FA as star-striking as your app! 🤩\n\nSo whether your mascot is:\n\n0. 🦋\n1. 🐰\n2. 🐶\n3. 🐕\n4. 🐷\n5. 🐥\n6. 🐱\n7. 🐣\n8. 🐻\n9. 🐈\n\n**moths** has got you covered! 🪰\n\n\u003e P.S. These emojies wasn't chosen by accident (random), they really are the 10 ut[most frequently used (animal) emojies of 2021](https://home.unicode.org/emoji/emoji-frequency/)\n\nShow that sparkly emojies ✨\n\n## how 🧑‍💼\n\nRunning this is quite easy 💨\n\n0. Download the dependencies ⏬\n\n\u003e **Note**\n\u003e\n\u003e You can skip this step and let the `run`-command handle it - but you knew that 🧠\n\n```sh\ngo mod download\n```\n\n1. Add a secret 🔐\n\n\u003e **Warning**\n\u003e\n\u003e This is just an one-liner to write the `base64`-encoded `sha256` of `moths` into `.env`.\n\u003e Make sure to use something better 🤷\n\u003e\n\u003e You don't need to use environment variables, this is just my choice.\n\n```sh\necho 'moths' | sha256sum | base64 -w 0 | { echo -n \"MOTHS_SECRET=$(cat -)\" } \u003e .env\n```\n\n2. Run the program 🏃\n\n```sh\ngo run .\n```\n\nAs I said, easy-peasy! 💖\n\n### options 👓\n\nTo setup a new `code`-generator, you must call [`token.NewGenerator`](token/newGenerator.go#L11-L33) as\n\n```go\ngen, err := token.NewGenerator()\n```\n\nBut I do recommend to add some customization, as it will fail immediately if not.\n\nLike so\n\n```go\ngen, err := token.NewGenerator(\n  token.OptionWithSecret(secret), // Any string as the secret\n  token.OptionWithPeriod(time.Second), // Each code is only valid for a second\n  token.OptionWithAmount(6), // Each must is always `6` emojies\n  token.OptionWithEmojies(emojies.CATS), // A pure slice of cats\n  token.OptionWithTime(time.Now().AddDate(10, 0, 0)), // 10 years into the future\n)\n```\n\nThere are a few options to choose from, these are\n\n- [`OptionWithSecret(secret string)`](token/option/secret.go#L7-L11)\n  - The secret to generate from\n  - Defaults to a random 32-character string\n- [`OptionWithPeriod(period time.Duration)`](token/option/period.go#L11-L15)**\\***\n  - On which interval should a new `code` be generated\n  - A `code` will only be valid during this duration - Until (if) skewed interval are implemented\n- [`OptionWithAmount(amount int)`](token/option/amount.go#L9-L13)\n  - The amount of emojies to generate in a `moth`\n  - Defaults to `6`-charater tokens\n- [`OptionWithEmojies(emojies emojies.Emojies)`](token/option/emojies.go#L11-L15)**\\***\n  - Take a look in the [`emojies`](token/emojies)-package to see your options\n  - You can also add your own emojies - [How to](#emojies-)\n- [`OptionWithTime(t time.Time)`](token/option/time.go#L14-L18)\n  - This will allow you to add a custom time\n  - Meaning you can validate towards old `code`s\n  - You can even add future dates ⌛\n  - Defaults to _now_\n- [`OptionFromEncoded(str string)`](token/option/encode.go#L11-L15)\n  - Use this if you have [exported](token/encoding.go#L57) a generator earlier\n\n\u003e **Warning**\n\u003e\n\u003e Options marked with an asterix (\\*) are required!\n\n### generating 🖇\n\nNow that you have a sparkly new `code`-generator, you can use it as\n\n```go\ncode, err := gen.Next()\n```\n\nNow that you have a [`code`](token/code), you can use its functions\n\n- [`Validate(emojies string) bool`](token/code/validate.go#L3-L5)\n  - Will validate a code (pattern of emojies) directly\n- [`ValidateToken(token string) bool`](token/code/validate.go#L8-L10) - **_DEPRECATED_**\n  - Will validate a token\n  - You'll need to expose the token to your user(s) for this - not recommended\n- [`String() string`](token/code/config.go#L16-L18)\n  - Returns the code as a string\n- [`SpacedString() string`](token/code/config.go#L20-L22)\n  - Returns the code as a string with spaces inbetween\n- [`Slice() []string`](token/code/config.go#L24-L26)\n  - Returns the code as a slice of strings\n  - Returns the code as a string\n- [`CreatedAt() time.Time`](token/code/config.go#L28-L30)\n  - Returns the time the code was generated\n- [`ExpiresAt() time.Time`](token/code/config.go#L32-L34)\n  - Returns the time when the code will expire\n- [`Token() string`](token/code/config.go#L37-L39) - **_DEPRECATED_**\n  - Returns the token - for whatever reason that might be needed\n\n### validating 🧑‍🔬\n\nTo validate, you'll need both the `code` (or the `token`) and the generator\n\n```go\nstr := code.String() // Ideally you'd get this from the user\nok := gen.Validate(str)\n```\n\n### emojies 😻\n\nTo use your own set of **known** emojies, you can reference the [`cat`-emojies](token/emojies/cats.go).\n\nI've chosen the `cats` as it's a great reference, both for creating and re-using.\n\nIf we would like to add an easter-egg to a purebred slice of cats, we could do it like:\n\n```go\n// A slice of cat emojies and a single hotdog 🌭\nvar catsHotdog = []string{\n\temoji.GrinningCat.String(),\n\temoji.GrinningCatWithSmilingEyes.String(),\n\temoji.CatWithTearsOfJoy.String(),\n\temoji.SmilingCatWithHeartEyes.String(),\n\temoji.CatWithWrySmile.String(),\n\temoji.KissingCat.String(),\n\temoji.WearyCat.String(),\n\temoji.CryingCat.String(),\n\temoji.PoutingCat.String(),\n\n\temoji.HotDog.String(),\n}\n\nvar CATS_HOTDOG = ToEmojies(catsHotdog)\n```\n\nIt doesn't even have to be from the [emoji](https://github.com/enescakir/emoji)-package,\nsimply make a slice of your desired emojies, and use the [`ToEmojies`-func](token/emojies/helper.go#L7-L21).\nThen provide this as an argument in `token.OptionWithEmojies(CATS_HOTDOG)` when calling the `token.NewGenerator()`.\n\n## example 🤷\n\nCheck out [`main.go`](main.go) for an example\n\n## show-case 🕺\n\n![Three iterations of moths](./data/sample.png)\n\n## history ✍\n\n- [`v6.0.0`](https://github.com/Mobilpadde/moths/tree/v6.0.0) 💘\n\n- \u003cdetails\u003e\n    \u003csummary\u003eOlder\u003c/summary\u003e\n\n  - [`v5.0.2`](https://github.com/Mobilpadde/moths/tree/v5.0.2)\n  - [`v5.0.1`](https://github.com/Mobilpadde/moths/tree/v5.0.1)\n  - [`v5.0.0`](https://github.com/Mobilpadde/moths/tree/v5.0.0)\n  - [`v4.0.1`](https://github.com/Mobilpadde/moths/tree/v4.0.1)\n  - [`v4.0.0`](https://github.com/Mobilpadde/moths/tree/v4.0.0)\n  - [`v3.0.0`](https://github.com/Mobilpadde/moths/tree/v3.0.0)\n  - [`v2.2.2`](https://github.com/Mobilpadde/moths/tree/v2.2.2)\n  - [`v2.2.1`](https://github.com/Mobilpadde/moths/tree/v2.2.1)\n  - [`v2.2.0`](https://github.com/Mobilpadde/moths/tree/v2.2.0)\n  - [`v2.1.0`](https://github.com/Mobilpadde/moths/tree/v2.1.0)\n  - [`v2.0.0`](https://github.com/Mobilpadde/moths/tree/v2.0.0)\n  - [`v1.0.0`](https://github.com/Mobilpadde/moths/tree/v1.0.0)\n  - [`v0.1.0`](https://github.com/Mobilpadde/moths/tree/v0.1)\n  \u003c/details\u003e\n\n## future 🔮\n\n- Add [Skew Intervals](https://www.ibm.com/docs/en/sva/9.0.6?topic=authentication-configuring-totp-one-time-password-mechanism) 🕰️\n- Add better documentation 🫢\n- Get into fixing [`geatures`](token/emojies/gestures.go#L28-L60) 🤦\n- ~~`Export` / `Import`~~ - [d1bb4cc](https://github.com/Mobilpadde/moths/commit/d1bb4cc92abcf1f00d19088bbeee7013f6c8c302)\n- ~~Rename `moth` to something better (`OTP` / `Token`)~~ - [6105848](https://github.com/Mobilpadde/moths/commit/6105848b336d57af5cc60fe53aa60532d2f979a4)\n- ~~Rename the `Moths`-struct to `Generator`~~ - [4c973ef](https://github.com/Mobilpadde/moths/commit/4c973ef15c6f6102aaf3741aeb64ea35663b0b9c)\n  - ~~This means renaming the `otp`-package as well?~~ - [fcdf295](https://github.com/Mobilpadde/moths/commit/fcdf295111bec0b516db62c3879bf4b7d7fd4436)\n- ~~Get [pkg.go.dev](https://pkg.go.dev/github.com/Mobilpadde/moths) up-to-date~~ - Works with [v6](https://pkg.go.dev/github.com/Mobilpadde/moths/v6)\n\n## shoutout 📢💨\n\nI couldn't have done it without these lovely OSS 🦾\n\n- \u003chttps://github.com/aidarkhanov/nanoid\u003e\n- \u003chttps://github.com/enescakir/emoji\u003e\n- \u003chttps://github.com/tilaklodha/google-authenticator\u003e\n- \u003chttps://github.com/pquerna/otp/\u003e\n\nIn no specific order 🤷\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobilpadde%2Fmoths","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmobilpadde%2Fmoths","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobilpadde%2Fmoths/lists"}