Metadata-Version: 2.4
Name: s-totpkit
Version: 0.1.2
Summary: TOTP-хранилище и генератор одноразовых кодов для любых сервисов: CLI, библиотека и Telegram-бот выдачи кодов
Project-URL: Homepage, https://gitlab.com/S-kits/totpkit
Project-URL: Source, https://gitlab.com/S-kits/totpkit
Author: Dmitry Semyonov
License: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: keyring>=24
Requires-Dist: pyotp>=2.9
Requires-Dist: s-clikit>=0.1.5
Requires-Dist: s-librarykit>=0.7.7
Provides-Extra: bot
Requires-Dist: aiogram>=3.13; extra == 'bot'
Requires-Dist: aiohttp-socks>=0.11.0; extra == 'bot'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# totpkit — одноразовые коды (TOTP) для любых сервисов

Одно шифрованное хранилище вторых факторов на все сервисы: PyPI, GitHub,
Bitrix24, что угодно. Код можно получить командой, а можно кнопкой в Telegram,
когда ноутбука под рукой нет. Другие проекты берут коды из того же стора одной
строкой, не заводя собственных копий секретов.

## Установка

```bash
uv add s-totpkit            # как зависимость
uv sync --extra bot         # с Telegram-ботом
uv run python scripts/self_check.py
```

## Быстрый старт

```bash
totp entry add --uri "otpauth://totp/PyPI:alice?secret=…&issuer=PyPI"
totp list
totp code pypi              # {"code": "366845", "seconds_left": 20}
```

Вывод — JSON по умолчанию; `--text` переключает на человекочитаемый.

## Из своего кода

```python
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-бот

```bash
totp bot setup            # токен бота и первый разрешённый аккаунт
totp bot run
```

Бот отдаёт коды только аккаунтам из белого списка: бот, отвечающий кому угодно,
— это утечка второго фактора. Карточка показывает код, остаток жизни окна и
кнопку «Обновить».

## Лицензия

MIT
