Telegram Mini App that allows you to generate one-time 2FA passwords inside Telegram.
➡️ OPEN
- ✅ Universal: TeleOTP implements TOTP (Time-Based One-Time Password Algorithm) which is used by most services.
- 👌 Convenient: Accounts are safely stored in your Telegram cloud storage, so you can access them anywhere you can use Telegram.
- 🔒 Secure: All accounts are encrypted using AES. That means even if your Telegram account is breached, the attacker won't have access to your tokens without the encryption password.
- 🥰 User-friendly: TeleOTP is designed to look like Telegram and follows your color theme.
- 🤗 Open: TeleOTP supports account migration to and from Google Authenticator. You can switch the platforms at any time without any hassle!
TeleOTP is made with React, Typescript, and Material UI. Vite frontend tooling is used for rapid development and easy deployment.
To begin working with the project, you should install the dependencies by running this command:
npm install
Before starting the server or building the app, make sure that
your project directory has a file named .env
.
It should follow the .env.example
file structure.
You could also set these variables directly when running the app.
The app uses following environment variables:
VITE_BOT_USERNAME
- This value contains the bot username. It is used to send export requests to the bot. Example:VITE_BOT_USERNAME=TeleOTPAppBot
VITE_PLAUSIBLE_DOMAIN
- The domain for Plausible analytics.VITE_PLAUSIBLE_API_HOST
- API host to report Plausible analytics to.VITE_CHANNEL_LINK
- Link to the news channel.VITE_APP_NAME
- Name of the app for the URL.- For the app https://t.me/TeleOTPAppBot/app, app name is
app
- For the app https://t.me/TeleOTPAppBot/app, app name is
VITE_TRANSLATE_LINK
- Link to the translation website
To start the development server with hot reload, run:
npm run dev
After that, the server will be accessible on http://localhost:5173/
Note
If you want the app to be accessible on your local network, you should add --host
argument to the command
npm run dev -- --host
npm run build
After a successful build, app bundle will be available in ./dist
.
The app is built and deployed automatically using Cloudflare Pages.
TeleOTP uses a helper bot to send user a link to the app and assist with account migration. The bot is written in Python using Python Telegram Bot library.
To start the bot, you have to run the main.py
script with environment variables.
python main.py
TOKEN
- Telegram bot token provided by @BotFatherTG_APP
- A link to the Mini App in Telegram (e.g. https://t.me/TeleOTPAppBot/app)WEBAPP_URL
- Deployed Mini App URL (e.g. https://uselessstudio.github.io/TeleOTP)
Note
Make sure that WEBAPP_URL
doesn't end with a /
!
It is added automatically by the bot.
We recommend running the bot inside the Docker container.
The latest image is available at ghcr.io/uselessstudio/teleotp-bot:main
.
Example docker-compose.yml
file:
services:
bot:
image: ghcr.io/uselessstudio/teleotp-bot:main
restart: unless-stopped
environment:
- TG_APP=https://t.me/TeleOTPAppBot/app
- WEBAPP_URL=https://uselessstudio.github.io/TeleOTP
- TOKEN=<insert your token>
And running is as simple as:
docker compose up
GitHub Actions is used to automate the building of the bot container.
The workflow is defined in the bot.yml
file
and ran on every push to main
. After a successful build,
the container is published in the GitHub Container Registry.
TeleOTP uses React Router to switch between pages.
Routes are specified in the main.tsx
file.
- Route implemented in
Root.tsx
is responsible for showing "required" screens:PasswordSetup.tsx
is a screen which is showed when no password is created. Alternatively, this screen is shown when user clicked a button to change the password. It displays a prompt to create a new password which is used to encrypt the accounts.Decrypt.tsx
is a screen which shows a password prompt to decrypt stored accounts. By default, it is shown only once on a new device. Later, the password retrieved fromlocalStorage
(if not disabled in the settings).
Accounts.tsx
is the main screen, which shows the generated password and a list of accounts that user has.NewAccount.tsx
is a screen, which prompts user to open the QR-code scanner. Otherwise, user could press a button to enter an account manually, which would redirect them toManualAccount.tsx
ManualAccount.tsx
prompts user to enter a secret for an OTP account.CreateAccount.tsx
is a final step in the account creation flow. User is redirected here after scanning a QR-code or after manually providing a secret. This screen allows user to change issuer and label and to select an icon with a color for the account.EditAccount.tsx
is a screen similar toCreateAccount.tsx
which allows user to edit or delete an account.Settings.tsx
is a menu screen with a few options. User can delete all accounts, encrypt them, change the password, or set preferences.ExportAccounts.tsx
is a page that handles the export logic.QrExport.tsx
is a screen that provides a QR-code with account data.LinkExport.tsx
is a screen which allows to copy a link to import accounts.
ResetAccounts.tsx
is a page that verifies that the user wants to delete all accounts and reset the password. This page can be accessed through the settings, or by typing in the password incorrectly when decrypting.DevToolsPage.tsx
is a debugging page, which allows checking the storage. (Only available in dev env)IconBrowser.tsx
is a page for browsing icons from simpleicons.org. User is able to search for icons.
TeleOTP implements the otpauth-migration
URI standard.
During the migration, accounts are (de)serialized using Protocol Buffers.
All generic icons and colors for accounts are defined in the globals.tsx
file.
Available icons are exported in the icons
const, colors are available in the colors
const.
Icon
and Color
types are provided for checking the validity of the corresponding item.
TeleOTP is officially translated only to Russian. If you have spare time and would like to help out the project, please add translations at Crowdin.
Currently supported languages:
- English (official)
- Russian (official)
- Ukrainian
- German
- French
- Spanish
If you need to add new strings:
- Modify the file
src/lang/en.ts
to have a new string with a descriptive key.- If a string needs to have variables, put them in braces
like {this}
- If a string needs to have variables, put them in braces
- Use the
useL10n()
hook to get the translation.
- Emoji animations from Telegram stickers.
- Duck stickers
- Brand icons from Simple Icons
- @twa-dev/types - Typescript types for Telegram Mini App SDK
- OTPAuth - generating TOTP codes
- nanoid - generating unique ids for accounts
- lottie-react - rendering lottie animations
- copy-text-to-clipboard - copying codes to the clipboard
🏆 TeleOTP won first place in the Telegram Mini App Contest.
Designed by @lunnaholy, implemented by @LowderPlay & @lenchq with ❤️