totpkit — одноразовые коды (TOTP) для любых сервисов
Одно шифрованное хранилище вторых факторов на все сервисы: PyPI, GitHub, Bitrix24, что угодно. Код можно получить командой, а можно кнопкой в Telegram, когда ноутбука под рукой нет. Другие проекты берут коды из того же стора одной строкой, не заводя собственных копий секретов.
Установка
uv add s-totpkit # как зависимость
uv sync --extra bot # с Telegram-ботом
uv run python scripts/self_check.py
Быстрый старт
totp entry add --uri "otpauth://totp/PyPI:alice?secret=…&issuer=PyPI"
totp list
totp code pypi # {"code": "366845", "seconds_left": 20}
Вывод — JSON по умолчанию; --text переключает на человекочитаемый.
Из своего кода
from totpkit import provider_for
login(username, password, totp_provider=provider_for("pypi"))
Провайдер отдаёт код по сигнатуре (попытка, прошлая ошибка) -> код и сам
разбирается с границей 30-секундного окна: ждёт ротацию, когда коду осталось
жить меньше трёх секунд, и никогда не отдаёт дважды один и тот же код — иначе
повторная попытка входа сгорает на коде, который сервис уже отверг.
Модель хранения
Запись — это сервис + аккаунт + иконка + группа. Ключ строится как
сервис или сервис:аккаунт и служит тем, что вы набираете руками: пока
аккаунт один, работает короткое totp code pypi; когда их стало два, короткая
форма даёт ошибку со списком вариантов, а не выдаёт код наугад.
Групп по умолчанию нет — всё лежит одним плоским списком, пока группу не задали.
Секреты пишутся в системное хранилище (keyring). Если рабочего бэкенда нет, кит
честно предупреждает и уходит в файл — проверить можно командой
totp store status. Длинные сторы режутся на куски: у Windows Credential
Manager есть жёсткий потолок на размер значения, и без нарезки хранилище молча
деградировало бы в открытый файл ровно тогда, когда записей стало много.
Telegram-бот
totp bot setup # токен бота и первый разрешённый аккаунт
totp bot run
Бот отдаёт коды только аккаунтам из белого списка: бот, отвечающий кому угодно, — это утечка второго фактора. Карточка показывает код, остаток жизни окна и кнопку «Обновить» — она стоит первой строкой одна на всю ширину, потому что за ней тянутся чаще всего (код живёт 30 секунд), а цвет кнопки Bot API задавать не умеет, и заметность даётся шириной и значком.
Навигация: внизу чата постоянный ряд «🏠 Главное меню» + «🗂 Сервисы», а возврат в начало есть на каждом экране. «Сервисы» — список сервисов с числом записей; вход в сервис показывает только его записи. «📋 Все записи» на первом экране появляется, только когда заведены группы: без групп первый экран и так плоский список, и кнопка вела бы туда, где человек уже стоит.
«⬅️ Назад» ведёт на ШАГ назад и дополняет «Главное меню», а не заменяет его:
из карточки — в тот список, откуда её открыли (группа, сервис или плоский
список), из записей сервиса — в «Сервисы». Точка возврата едет хвостом в
callback_data (код экрана плюс, для группы и сервиса, тот же 12-символьный
токен) — 13 байт, весь колбэк карточки укладывается в 28 из 64. Там, где шаг
назад и есть первый экран, отдельной кнопки нет: две кнопки с одинаковым
действием — выбор без разницы. Кнопки из старых сообщений точки возврата не
знают и по-прежнему ведут домой — падать им нельзя, они живут в чате вечно. Иконку сервиса и подписи
кнопок задаёт провайдер (плагин навыка, entry-point totpkit.providers); в
тексте сообщений иконка идёт премиум-эмодзи, в кнопках — обычная (Bot API
рисует custom_emoji только по entity сообщения). Если Telegram отверг
разметку, сообщение уходит повторно без неё: код важнее картинки.
Лицензия
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file s_totpkit-0.2.0.tar.gz.
File metadata
- Download URL: s_totpkit-0.2.0.tar.gz
- Upload date:
- Size: 177.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12bca604e8ab73b28adda55a192a037fa3f0646c127094ce0f621f0b23b8e4a6
|
|
| MD5 |
b52ddbc09ea5984ed55e0860f270e0b4
|
|
| BLAKE2b-256 |
06a70d2aedabaf173d77b8354946c81dbc028f51420f7a89507a39eaa1bb1ccf
|
File details
Details for the file s_totpkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: s_totpkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 73.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e934b564895a67952c9d48236f2e5ea4bd14c6b9688a52f3417d2bb6c8c0c647
|
|
| MD5 |
4f9324bef88b3d51a7c6c5a8268fb745
|
|
| BLAKE2b-256 |
a4788579be7c578b729f87c387a000a21eb2d4f68a909ceca4e1207ce3655927
|